app: misc cleanup in gimpcoords-interpolate

Fix indentation, typos, style.  Use array parameters for the
control points, instead of using individual by-value parameters.
Use GArray* for the results, instead of GArray**.  Verify
arguments.

Adapt the rest of the code to the changes.
This commit is contained in:
Ell
2018-02-01 10:39:28 -05:00
parent 1cae93ac42
commit 275815c808
4 changed files with 109 additions and 160 deletions

View File

@ -30,15 +30,12 @@
/* Local helper functions declarations*/
static void gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt1,
const GimpCoords bezier_pt2,
const GimpCoords bezier_pt3,
const GimpCoords bezier_pt4,
static void gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt[4],
const gdouble start_t,
const gdouble end_t,
const gdouble precision,
GArray **ret_coords,
GArray **ret_params,
GArray *ret_coords,
GArray *ret_params,
gint depth);
static gdouble gimp_coords_get_catmull_spline_point (const gdouble t,
const gdouble p0,
@ -49,18 +46,16 @@ static gdouble gimp_coords_get_catmull_spline_point (const gdouble t,
/* Functions for bezier subdivision */
void
gimp_coords_interpolate_bezier (const GimpCoords bezier_pt1,
const GimpCoords bezier_pt2,
const GimpCoords bezier_pt3,
const GimpCoords bezier_pt4,
const gdouble precision,
GArray **ret_coords,
GArray **ret_params)
gimp_coords_interpolate_bezier (const GimpCoords bezier_pt[4],
const gdouble precision,
GArray *ret_coords,
GArray *ret_params)
{
gimp_coords_interpolate_bezier_internal (bezier_pt1,
bezier_pt2,
bezier_pt3,
bezier_pt4,
g_return_if_fail (bezier_pt != NULL);
g_return_if_fail (precision > 0.0);
g_return_if_fail (ret_coords != NULL);
gimp_coords_interpolate_bezier_internal (bezier_pt,
0.0, 1.0,
precision,
ret_coords, ret_params, 10);
@ -68,44 +63,34 @@ gimp_coords_interpolate_bezier (const GimpCoords bezier_pt1,
/* Recursive subdivision helper function */
static void
gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt1,
const GimpCoords bezier_pt2,
const GimpCoords bezier_pt3,
const GimpCoords bezier_pt4,
gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt[4],
const gdouble start_t,
const gdouble end_t,
const gdouble precision,
GArray **ret_coords,
GArray **ret_params,
GArray *ret_coords,
GArray *ret_params,
gint depth)
{
/*
* beziercoords has to contain four GimpCoords with the four control points
* bezier_pt has to contain four GimpCoords with the four control points
* of the bezier segment. We subdivide it at the parameter 0.5.
*/
GimpCoords subdivided[8];
gdouble middle_t = (start_t + end_t) / 2;
subdivided[0] = bezier_pt1;
subdivided[6] = bezier_pt4;
subdivided[0] = bezier_pt[0];
subdivided[6] = bezier_pt[3];
/* if (!depth) g_printerr ("Hit recursion depth limit!\n"); */
gimp_coords_average (&bezier_pt1, &bezier_pt2, &(subdivided[1]));
gimp_coords_average (&bezier_pt[0], &bezier_pt[1], &subdivided[1]);
gimp_coords_average (&bezier_pt[1], &bezier_pt[2], &subdivided[7]);
gimp_coords_average (&bezier_pt[2], &bezier_pt[3], &subdivided[5]);
gimp_coords_average (&bezier_pt2, &bezier_pt3, &(subdivided[7]));
gimp_coords_average (&bezier_pt3, &bezier_pt4, &(subdivided[5]));
gimp_coords_average (&(subdivided[1]), &(subdivided[7]),
&(subdivided[2]));
gimp_coords_average (&(subdivided[7]), &(subdivided[5]),
&(subdivided[4]));
gimp_coords_average (&(subdivided[2]), &(subdivided[4]),
&(subdivided[3]));
gimp_coords_average (&subdivided[1], &subdivided[7], &subdivided[2]);
gimp_coords_average (&subdivided[7], &subdivided[5], &subdivided[4]);
gimp_coords_average (&subdivided[2], &subdivided[4], &subdivided[3]);
/*
* We now have the coordinates of the two bezier segments in
@ -117,13 +102,10 @@ gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt1,
* if the stroke is sufficiently close to a straight line.
*/
if (!depth || gimp_coords_bezier_is_straight (subdivided[0],
subdivided[1],
subdivided[2],
subdivided[3],
precision)) /* 1st half */
if (! depth ||
gimp_coords_bezier_is_straight (subdivided, precision)) /* 1st half */
{
*ret_coords = g_array_append_vals (*ret_coords, &(subdivided[0]), 3);
g_array_append_vals (ret_coords, subdivided, 3);
if (ret_params)
{
@ -133,27 +115,22 @@ gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt1,
params[1] = (2 * start_t + middle_t) / 3;
params[2] = (start_t + 2 * middle_t) / 3;
*ret_params = g_array_append_vals (*ret_params, &(params[0]), 3);
g_array_append_vals (ret_params, params, 3);
}
}
else
{
gimp_coords_interpolate_bezier_internal (subdivided[0],
subdivided[1],
subdivided[2],
subdivided[3],
gimp_coords_interpolate_bezier_internal (subdivided,
start_t, (start_t + end_t) / 2,
precision,
ret_coords, ret_params, depth-1);
ret_coords, ret_params,
depth - 1);
}
if (!depth || gimp_coords_bezier_is_straight (subdivided[3],
subdivided[4],
subdivided[5],
subdivided[6],
precision)) /* 2nd half */
if (! depth ||
gimp_coords_bezier_is_straight (subdivided + 3, precision)) /* 2nd half */
{
*ret_coords = g_array_append_vals (*ret_coords, &(subdivided[3]), 3);
g_array_append_vals (ret_coords, subdivided + 3, 3);
if (ret_params)
{
@ -163,18 +140,16 @@ gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt1,
params[1] = (2 * middle_t + end_t) / 3;
params[2] = (middle_t + 2 * end_t) / 3;
*ret_params = g_array_append_vals (*ret_params, &(params[0]), 3);
g_array_append_vals (ret_params, params, 3);
}
}
else
{
gimp_coords_interpolate_bezier_internal (subdivided[3],
subdivided[4],
subdivided[5],
subdivided[6],
gimp_coords_interpolate_bezier_internal (subdivided + 3,
(start_t + end_t) / 2, end_t,
precision,
ret_coords, ret_params, depth-1);
ret_coords, ret_params,
depth - 1);
}
}
@ -191,64 +166,65 @@ gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt1,
*/
gboolean
gimp_coords_bezier_is_straight (const GimpCoords bezier_pt1,
const GimpCoords bezier_pt2,
const GimpCoords bezier_pt3,
const GimpCoords bezier_pt4,
gimp_coords_bezier_is_straight (const GimpCoords bezier_pt[4],
gdouble precision)
{
GimpCoords pt1, pt2;
g_return_val_if_fail (bezier_pt != NULL, FALSE);
g_return_val_if_fail (precision > 0.0, FALSE);
/* calculate the "ideal" positions for the control points */
gimp_coords_mix (2.0 / 3.0, &bezier_pt1,
1.0 / 3.0, &bezier_pt4,
gimp_coords_mix (2.0 / 3.0, &bezier_pt[0],
1.0 / 3.0, &bezier_pt[3],
&pt1);
gimp_coords_mix (1.0 / 3.0, &bezier_pt1,
2.0 / 3.0, &bezier_pt4,
gimp_coords_mix (1.0 / 3.0, &bezier_pt[0],
2.0 / 3.0, &bezier_pt[3],
&pt2);
/* calculate the deviation of the actual control points */
return (gimp_coords_manhattan_dist (&bezier_pt2, &pt1) < precision &&
gimp_coords_manhattan_dist (&bezier_pt3, &pt2) < precision);
return (gimp_coords_manhattan_dist (&bezier_pt[1], &pt1) < precision &&
gimp_coords_manhattan_dist (&bezier_pt[2], &pt2) < precision);
}
/* Functions for camull-rom interpolation */
/* Functions for catmull-rom interpolation */
void
gimp_coords_interpolate_catmull (const GimpCoords catmul_pt1,
const GimpCoords catmul_pt2,
const GimpCoords catmul_pt3,
const GimpCoords catmul_pt4,
gdouble precision,
GArray **ret_coords,
GArray **ret_params)
gimp_coords_interpolate_catmull (const GimpCoords catmull_pt[4],
gdouble precision,
GArray *ret_coords,
GArray *ret_params)
{
gdouble delta_x, delta_y;
gdouble distance;
gdouble dir_step;
gdouble delta_dir;
gint num_points;
gint n;
gdouble delta_x, delta_y;
gdouble distance;
gdouble dir_step;
gdouble delta_dir;
gint num_points;
gint n;
GimpCoords past_coords;
GimpCoords start_coords;
GimpCoords end_coords;
GimpCoords future_coords;
GimpCoords past_coords;
GimpCoords start_coords;
GimpCoords end_coords;
GimpCoords future_coords;
delta_x = catmul_pt3.x - catmul_pt2.x;
delta_y = catmul_pt3.y - catmul_pt2.y;
g_return_if_fail (catmull_pt != NULL);
g_return_if_fail (precision > 0.0);
g_return_if_fail (ret_coords != NULL);
delta_x = catmull_pt[2].x - catmull_pt[1].x;
delta_y = catmull_pt[2].y - catmull_pt[1].y;
/* Catmull-Rom interpolation requires 4 points.
* Two endpoints plus one more at each end.
*/
past_coords = catmul_pt1;
start_coords = catmul_pt2;
end_coords = catmul_pt3;
future_coords = catmul_pt4;
past_coords = catmull_pt[0];
start_coords = catmull_pt[1];
end_coords = catmull_pt[2];
future_coords = catmull_pt[3];
distance = sqrt (SQR (delta_x) + SQR (delta_y));
@ -329,19 +305,19 @@ gimp_coords_interpolate_catmull (const GimpCoords catmul_pt1,
coords.angle = end_coords.angle;
coords.reflect = end_coords.reflect;
g_array_append_val (*ret_coords, coords);
g_array_append_val (ret_coords, coords);
if (ret_params)
g_array_append_val (*ret_params, p);
g_array_append_val (ret_params, p);
}
}
static gdouble
gimp_coords_get_catmull_spline_point (const gdouble t,
const gdouble p0,
const gdouble p1,
const gdouble p2,
const gdouble p3)
gimp_coords_get_catmull_spline_point (const gdouble t,
const gdouble p0,
const gdouble p1,
const gdouble p2,
const gdouble p3)
{
return ((((-t + 2.0) * t - 1.0) * t / 2.0) * p0 +
((((3.0 * t - 5.0) * t) * t + 2.0) / 2.0) * p1 +

View File

@ -20,26 +20,17 @@
#ifndef __GIMP_COORDS_INTERPOLATE_H__
#define __GIMP_COORDS_INTERPOLATE_H__
void gimp_coords_interpolate_bezier (const GimpCoords bezier_pt1,
const GimpCoords bezier_pt2,
const GimpCoords bezier_pt3,
const GimpCoords bezier_pt4,
gdouble precision,
GArray **ret_coords,
GArray **ret_params);
void gimp_coords_interpolate_bezier (const GimpCoords bezier_pt[4],
gdouble precision,
GArray *ret_coords,
GArray *ret_params);
gboolean gimp_coords_bezier_is_straight (const GimpCoords bezier_pt1,
const GimpCoords bezier_pt2,
const GimpCoords bezier_pt3,
const GimpCoords bezier_pt4,
gdouble precision);
gboolean gimp_coords_bezier_is_straight (const GimpCoords bezier_pt[4],
gdouble precision);
void gimp_coords_interpolate_catmull (const GimpCoords catmul_pt1,
const GimpCoords catmul_pt2,
const GimpCoords catmul_pt3,
const GimpCoords catmul_pt4,
gdouble precision,
GArray **ret_coords,
GArray **ret_params);
void gimp_coords_interpolate_catmull (const GimpCoords catmull_pt[4],
gdouble precision,
GArray *ret_coords,
GArray *ret_params);
#endif /* __GIMP_COORDS_INTERPOLATE_H__ */

View File

@ -540,24 +540,22 @@ static void
gimp_motion_buffer_interpolate_stroke (GimpMotionBuffer *buffer,
GimpCoords *coords)
{
GArray *ret_coords;
gint i = buffer->event_history->len - 1;
GimpCoords catmull[4];
GArray *ret_coords;
gint i = buffer->event_history->len - 1;
/* Note that there must be exactly one event in buffer or bad things
* can happen. This must never get called under other circumstances.
*/
ret_coords = g_array_new (FALSE, FALSE, sizeof (GimpCoords));
gimp_coords_interpolate_catmull (g_array_index (buffer->event_history,
GimpCoords, i - 1),
g_array_index (buffer->event_history,
GimpCoords, i),
g_array_index (buffer->event_queue,
GimpCoords, 0),
*coords,
EVENT_FILL_PRECISION / 2,
&ret_coords,
NULL);
catmull[0] = g_array_index (buffer->event_history, GimpCoords, i - 1);
catmull[1] = g_array_index (buffer->event_history, GimpCoords, i);
catmull[2] = g_array_index (buffer->event_queue, GimpCoords, 0);
catmull[3] = *coords;
gimp_coords_interpolate_catmull (catmull, EVENT_FILL_PRECISION / 2,
ret_coords, NULL);
/* Push the last actual event in history */
gimp_motion_buffer_push_event_history (buffer,

View File

@ -683,13 +683,9 @@ gimp_bezier_stroke_segment_nearest_point_get (const GimpCoords *beziercoords,
gimp_coords_difference (&beziercoords[1], &beziercoords[0], &point1);
gimp_coords_difference (&beziercoords[3], &beziercoords[2], &point2);
if (!depth || (gimp_coords_bezier_is_straight (beziercoords[0],
beziercoords[1],
beziercoords[2],
beziercoords[3],
precision)
&& gimp_coords_length_squared (&point1) < precision
&& gimp_coords_length_squared (&point2) < precision))
if (! depth || (gimp_coords_bezier_is_straight (beziercoords, precision) &&
gimp_coords_length_squared (&point1) < precision &&
gimp_coords_length_squared (&point2) < precision))
{
GimpCoords line, dcoord;
gdouble length2, scalar;
@ -920,12 +916,8 @@ gimp_bezier_stroke_segment_nearest_tangent_get (const GimpCoords *beziercoords,
g_printerr ("(%.2f, %.2f)-(%.2f,%.2f): ", coord1->x, coord1->y,
coord2->x, coord2->y);
gimp_coords_interpolate_bezier (beziercoords[0],
beziercoords[1],
beziercoords[2],
beziercoords[3],
precision,
&ret_coords, &ret_params);
gimp_coords_interpolate_bezier (beziercoords, precision,
ret_coords, ret_params);
g_return_val_if_fail (ret_coords->len == ret_params->len, -1.0);
@ -1578,12 +1570,8 @@ gimp_bezier_stroke_interpolate (GimpStroke *stroke,
if (count == 4)
{
gimp_coords_interpolate_bezier (segmentcoords[0],
segmentcoords[1],
segmentcoords[2],
segmentcoords[3],
precision,
&ret_coords, NULL);
gimp_coords_interpolate_bezier (segmentcoords, precision,
ret_coords, NULL);
segmentcoords[0] = segmentcoords[3];
count = 1;
need_endpoint = TRUE;
@ -1603,12 +1591,8 @@ gimp_bezier_stroke_interpolate (GimpStroke *stroke,
if (anchorlist)
segmentcoords[3] = GIMP_ANCHOR (anchorlist->data)->position;
gimp_coords_interpolate_bezier (segmentcoords[0],
segmentcoords[1],
segmentcoords[2],
segmentcoords[3],
precision,
&ret_coords, NULL);
gimp_coords_interpolate_bezier (segmentcoords, precision,
ret_coords, NULL);
need_endpoint = TRUE;
}