[gimp/soc-2012-unified-transformation: 35/51] transformtool: Deduplicate code, use more vector representations, fix style and warnings
- From: Mikael Magnusson <mikachu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/soc-2012-unified-transformation: 35/51] transformtool: Deduplicate code, use more vector representations, fix style and warnings
- Date: Mon, 20 Aug 2012 13:53:42 +0000 (UTC)
commit ed29503f2889db56fd340310109302633d9964d5
Author: Mikael Magnusson <mikachu src gnome org>
Date: Sun Aug 5 17:56:28 2012 +0200
transformtool: Deduplicate code, use more vector representations, fix style and warnings
app/tools/gimpunifiedtransformtool.c | 428 +++++++++++++++-------------------
1 files changed, 189 insertions(+), 239 deletions(-)
---
diff --git a/app/tools/gimpunifiedtransformtool.c b/app/tools/gimpunifiedtransformtool.c
index e00528e..e087ae6 100644
--- a/app/tools/gimpunifiedtransformtool.c
+++ b/app/tools/gimpunifiedtransformtool.c
@@ -679,75 +679,87 @@ gimp_unified_transform_tool_prepare (GimpTransformTool *tr_tool)
}
-static inline gdouble dotprod (GimpVector2 a, GimpVector2 b) {
- return a.x*b.x + a.y*b.y;
+static inline gdouble dotprod (GimpVector2 a, GimpVector2 b)
+{
+ return a.x*b.x + a.y*b.y;
}
-static inline gdouble norm (GimpVector2 a) {
- return sqrt (dotprod (a, a));
+static inline gdouble norm (GimpVector2 a)
+{
+ return sqrt (dotprod (a, a));
}
-static inline GimpVector2 vectorsubtract (GimpVector2 a, GimpVector2 b) {
- GimpVector2 c;
- c.x = a.x - b.x;
- c.y = a.y - b.y;
- return c;
+static inline GimpVector2 vectorsubtract (GimpVector2 a, GimpVector2 b)
+{
+ GimpVector2 c;
+ c.x = a.x - b.x;
+ c.y = a.y - b.y;
+ return c;
}
-static inline GimpVector2 vectoradd (GimpVector2 a, GimpVector2 b) {
- GimpVector2 c;
- c.x = a.x + b.x;
- c.y = a.y + b.y;
- return c;
+static inline GimpVector2 vectoradd (GimpVector2 a, GimpVector2 b)
+{
+ GimpVector2 c;
+ c.x = a.x + b.x;
+ c.y = a.y + b.y;
+ return c;
}
-static inline GimpVector2 scalemult (GimpVector2 a, gdouble b) {
- GimpVector2 c;
- c.x = a.x * b;
- c.y = a.y * b;
- return c;
+static inline GimpVector2 scalemult (GimpVector2 a, gdouble b)
+{
+ GimpVector2 c;
+ c.x = a.x * b;
+ c.y = a.y * b;
+ return c;
}
-static inline GimpVector2 vectorproject (GimpVector2 a, GimpVector2 b) {
- return scalemult (b, dotprod (a, b)/dotprod (b, b));
+static inline GimpVector2 vectorproject (GimpVector2 a, GimpVector2 b)
+{
+ return scalemult (b, dotprod (a, b)/dotprod (b, b));
}
/* finds the clockwise angle between the vectors given, 0-2Ï */
-static inline gdouble calcangle (GimpVector2 a, GimpVector2 b) {
- gdouble angle, angle2, length = norm (a) * norm (b);
- angle = acos (dotprod (a, b)/length);
- angle2 = b.y;
- b.y = -b.x;
- b.x = angle2;
- angle2 = acos (dotprod (a, b)/length);
- return ((angle2 > G_PI/2.) ? angle : 2*G_PI-angle);
+static inline gdouble calcangle (GimpVector2 a, GimpVector2 b)
+{
+ gdouble angle, angle2, length = norm (a) * norm (b);
+ angle = acos (dotprod (a, b)/length);
+ angle2 = b.y;
+ b.y = -b.x;
+ b.x = angle2;
+ angle2 = acos (dotprod (a, b)/length);
+ return ((angle2 > G_PI/2.) ? angle : 2*G_PI-angle);
}
-static inline GimpVector2 rotate2d (GimpVector2 p, gdouble angle) {
- GimpVector2 ret;
- ret.x = cos (angle)*p.x-sin (angle)*p.y;
- ret.y = sin (angle)*p.x+cos (angle)*p.y;
- return ret;
+static inline GimpVector2 rotate2d (GimpVector2 p, gdouble angle)
+{
+ GimpVector2 ret;
+ ret.x = cos (angle)*p.x-sin (angle)*p.y;
+ ret.y = sin (angle)*p.x+cos (angle)*p.y;
+ return ret;
}
static inline GimpVector2 lineintersect (GimpVector2 p1, GimpVector2 p2,
- GimpVector2 q1, GimpVector2 q2) {
- gdouble denom, u;
- GimpVector2 p;
-
- denom = (q2.y-q1.y) * (p2.x-p1.x) - (q2.x-q1.x) * (p2.y-p1.y);
- if (denom == 0.0) {
- p.x = (p1.x + p2.x + q1.x + q2.x) / 4;
- p.y = (p1.y + p2.y + q1.y + q2.y) / 4;
- } else {
- u = (q2.x-q1.x) * (p1.y-q1.y) - (q2.y-q1.y) * (p1.x-q1.x);
- u /= denom;
-
- p.x = p1.x + u * (p2.x - p1.x);
- p.y = p1.y + u * (p2.y - p1.y);
+ GimpVector2 q1, GimpVector2 q2)
+{
+ gdouble denom, u;
+ GimpVector2 p;
+
+ denom = (q2.y-q1.y) * (p2.x-p1.x) - (q2.x-q1.x) * (p2.y-p1.y);
+ if (denom == 0.0)
+ {
+ p.x = (p1.x + p2.x + q1.x + q2.x) / 4;
+ p.y = (p1.y + p2.y + q1.y + q2.y) / 4;
+ }
+ else
+ {
+ u = (q2.x-q1.x) * (p1.y-q1.y) - (q2.y-q1.y) * (p1.x-q1.x);
+ u /= denom;
+
+ p.x = p1.x + u * (p2.x - p1.x);
+ p.y = p1.y + u * (p2.y - p1.y);
}
- return p;
+ return p;
}
static inline GimpVector2 getpivotdelta (GimpTransformTool *tr_tool)
@@ -792,11 +804,18 @@ static inline GimpVector2 getpivotdelta (GimpTransformTool *tr_tool)
static void
gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
{
- gdouble dx = transform_tool->curx - transform_tool->mousex;
- gdouble dy = transform_tool->cury - transform_tool->mousey;
- gdouble *x[4], *y[4], px[5], py[5], *pivot_x, *pivot_y, ppivot_x, ppivot_y;
+ gdouble *x[4], *y[4], *newpivot_x, *newpivot_y;
+
+ GimpVector2 oldpos[5], newpos[4];
+ GimpVector2 cur = { .x = transform_tool->curx, .y = transform_tool->cury };
+ GimpVector2 mouse = { .x = transform_tool->mousex, .y = transform_tool->mousey };
+ GimpVector2 p;
+ GimpVector2 pivot;
+
gint i;
+
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (transform_tool);
+
gboolean constrain = options->constrain;
gboolean keepaspect = options->keepaspect;
gboolean frompivot = options->frompivot;
@@ -806,33 +825,24 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
TransformAction function = transform_tool->function;
- x[0] = &transform_tool->trans_info[X0];
- x[1] = &transform_tool->trans_info[X1];
- x[2] = &transform_tool->trans_info[X2];
- x[3] = &transform_tool->trans_info[X3];
- y[0] = &transform_tool->trans_info[Y0];
- y[1] = &transform_tool->trans_info[Y1];
- y[2] = &transform_tool->trans_info[Y2];
- y[3] = &transform_tool->trans_info[Y3];
-
- px[0] = (*transform_tool->prev_trans_info)[X0];
- px[1] = (*transform_tool->prev_trans_info)[X1];
- px[2] = (*transform_tool->prev_trans_info)[X2];
- px[3] = (*transform_tool->prev_trans_info)[X3];
- py[0] = (*transform_tool->prev_trans_info)[Y0];
- py[1] = (*transform_tool->prev_trans_info)[Y1];
- py[2] = (*transform_tool->prev_trans_info)[Y2];
- py[3] = (*transform_tool->prev_trans_info)[Y3];
+ for (i = 0; i < 4; i++) {
+ x[i] = &transform_tool->trans_info[X0+i*2];
+ y[i] = &transform_tool->trans_info[Y0+i*2];
+ newpos[i].x = oldpos[i].x = transform_tool->prev_trans_info[0][X0+i*2];
+ newpos[i].y = oldpos[i].y = transform_tool->prev_trans_info[0][Y0+i*2];
+ }
/* put center point in this array too */
- px[4] = (px[0] + px[1] + px[2] + px[3]) / 4.;
- py[4] = (py[0] + py[1] + py[2] + py[3]) / 4.;
+ oldpos[4].x = (oldpos[0].x + oldpos[1].x + oldpos[2].x + oldpos[3].x) / 4.;
+ oldpos[4].y = (oldpos[0].y + oldpos[1].y + oldpos[2].y + oldpos[3].y) / 4.;
+
+ p = vectorsubtract (cur, mouse);
- pivot_x = &transform_tool->trans_info[PIVOT_X];
- pivot_y = &transform_tool->trans_info[PIVOT_Y];
+ newpivot_x = &transform_tool->trans_info[PIVOT_X];
+ newpivot_y = &transform_tool->trans_info[PIVOT_Y];
- ppivot_x = (*transform_tool->prev_trans_info)[PIVOT_X];
- ppivot_y = (*transform_tool->prev_trans_info)[PIVOT_Y];
+ pivot.x = transform_tool->prev_trans_info[0][PIVOT_X];
+ pivot.y = transform_tool->prev_trans_info[0][PIVOT_Y];
/* move */
if (function == TRANSFORM_HANDLE_CENTER)
@@ -840,32 +850,33 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
if (constrain)
{
/* snap to 45 degree vectors from starting point */
- gdouble angle = calcangle ((GimpVector2){1., 0.}, (GimpVector2){dx, dy}) / (2.*G_PI);
+ gdouble angle = calcangle ((GimpVector2){1., 0.}, p) / (2.*G_PI);
+ gdouble diag = norm (p) / sqrt (2);
if (angle < 1./16 || angle > 15./16)
- dy = 0;
+ p.y = 0;
else if (angle < 3./16)
- dy = -(dx = sqrt (dx*dx+dy*dy)/sqrt (2));
+ p.y = -(p.x = diag);
else if (angle < 5./16)
- dx = 0;
+ p.x = 0;
else if (angle < 7./16)
- dx = dy = -sqrt (dx*dx+dy*dy)/sqrt (2);
+ p.x = p.y = -diag;
else if (angle < 9./16)
- dy = 0;
+ p.y = 0;
else if (angle < 11./16)
- dx = -(dy = sqrt (dx*dx+dy*dy)/sqrt (2));
+ p.x = -(p.y = diag);
else if (angle < 13./16)
- dx = 0;
+ p.x = 0;
else if (angle < 15./16)
- dx = dy = sqrt (dx*dx+dy*dy)/sqrt (2);
+ p.x = p.y = diag;
}
for (i = 0; i < 4; i++)
{
- *x[i] = px[i] + dx;
- *y[i] = py[i] + dy;
+ *x[i] = oldpos[i].x + p.x;
+ *y[i] = oldpos[i].y + p.y;
}
if (!fixedpivot) {
- *pivot_x = ppivot_x + dx;
- *pivot_y = ppivot_y + dy;
+ *newpivot_x = pivot.x + p.x;
+ *newpivot_y = pivot.y + p.y;
fixedpivot = TRUE;
}
}
@@ -873,10 +884,7 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
/* rotate */
if (function == TRANSFORM_HANDLE_ROTATION)
{
- GimpVector2 m = { .x = transform_tool->curx, .y = transform_tool->cury };
- GimpVector2 p = { .x = transform_tool->mousex, .y = transform_tool->mousey };
- GimpVector2 c = { .x = ppivot_x, .y = ppivot_y };
- gdouble angle = calcangle (vectorsubtract (m, c), vectorsubtract (p, c));
+ gdouble angle = calcangle (vectorsubtract (cur, pivot), vectorsubtract (mouse, pivot));
if (constrain)
{
/* round to 15 degree multiple */
@@ -885,10 +893,9 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
angle *= 2*G_PI/24.;
}
for (i = 0; i < 4; i++) {
- p.x = px[i]; p.y = py[i];
- m = vectoradd (c, rotate2d (vectorsubtract (p, c), angle));
- *x[i] = m.x;
- *y[i] = m.y;
+ newpos[i] = vectoradd (pivot, rotate2d (vectorsubtract (oldpos[i], pivot), angle));
+ *x[i] = newpos[i].x;
+ *y[i] = newpos[i].y;
}
fixedpivot = TRUE;
}
@@ -905,7 +912,7 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
gdouble closest_dist = G_MAXDOUBLE, dist;
for (i = 0; i < 5; i++)
{
- dist = norm (vectorsubtract ((GimpVector2){transform_tool->curx, transform_tool->cury}, (GimpVector2){px[i], py[i]}));
+ dist = norm (vectorsubtract (cur, oldpos[i]));
if (dist < closest_dist)
{
closest_dist = dist;
@@ -914,14 +921,14 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
}
if (closest_dist * gimp_display_get_shell (GIMP_TOOL (transform_tool)->display)->scale_x < 50)
{
- *pivot_x = px[closest];
- *pivot_y = py[closest];
+ *newpivot_x = oldpos[closest].x;
+ *newpivot_y = oldpos[closest].y;
return;
}
}
- *pivot_x = ppivot_x + dx;
- *pivot_y = ppivot_y + dy;
+ *newpivot_x = pivot.x + p.x;
+ *newpivot_y = pivot.y + p.y;
fixedpivot = TRUE;
}
@@ -947,21 +954,13 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
this = 3; left = 2; right = 1; opposite = 0;
} else g_assert_not_reached ();
- GimpVector2 lp = { .x = px[left], .y = py[left] },
- rp = { .x = px[right], .y = py[right] },
- tp = { .x = px[this], .y = py[this] },
- op = { .x = px[opposite], .y = py[opposite] },
- p = { .x = dx, .y = dy },
- pivot = { .x = ppivot_x, .y = ppivot_y },
- nt, nr, nl, no = op;
-
/* when the keep aspect transformation constraint is enabled, the
* translation shall only be along the diagonal that runs trough
* this corner point. */
if (keepaspect)
{
/* restrict to movement along the diagonal */
- GimpVector2 diag = vectorsubtract (tp, op);
+ GimpVector2 diag = vectorsubtract (oldpos[this], oldpos[opposite]);
p = vectorproject (p, diag);
}
@@ -973,7 +972,7 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
* op----------/
*
*/
- nt = vectoradd (tp, p);
+ newpos[this] = vectoradd (oldpos[this], p);
/* Where the corner to the right and left would go, need these to form
* lines to intersect with the sides */
@@ -985,20 +984,18 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
* nl
*/
- nr = vectoradd (rp, p);
- nl = vectoradd (lp, p);
+ newpos[right] = vectoradd (oldpos[right], p);
+ newpos[left] = vectoradd (oldpos[left], p);
/* Now we just need to find the intersection of op-rp and nr-nt.
- * If frompivot mode is active, then op also moved,
- * so we add no-op to rp */
- /* rp----------/
+ * rp----------/
* / /
* / nr==========nt
* op----------/
*
*/
- nr = lineintersect (nr, nt, no, vectoradd (rp, vectorsubtract (no, op)));
- nl = lineintersect (nl, nt, no, vectoradd (lp, vectorsubtract (no, op)));
+ newpos[right] = lineintersect (newpos[right], newpos[this], oldpos[opposite], oldpos[right]);
+ newpos[left] = lineintersect (newpos[left], newpos[this], oldpos[opposite], oldpos[left]);
/* /-----------/
* / /
* rp============nt
@@ -1006,17 +1003,12 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
*
*/
- *x[this] = nt.x;
- *y[this] = nt.y;
-
- *x[right] = nr.x;
- *y[right] = nr.y;
+ newpos[opposite] = oldpos[opposite];
- *x[left] = nl.x;
- *y[left] = nl.y;
-
- *x[opposite] = no.x;
- *y[opposite] = no.y;
+ for (i = 0; i < 4; i++) {
+ *x[i] = newpos[i].x;
+ *y[i] = newpos[i].y;
+ }
/*
*
* /--------------/
@@ -1030,7 +1022,6 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
* this difference */
//TODO don't fly off to hell when the transform is 'invalid'
//TODO the handle doesn't actually end up where the mouse cursor is
- gint i;
GimpVector2 delta = getpivotdelta (transform_tool);
for (i = 0; i < 4; i++)
{
@@ -1048,6 +1039,7 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
function == TRANSFORM_HANDLE_W)
{
gint this_l, this_r, opp_l, opp_r;
+ GimpVector2 side_l, side_r, midline;
/* 0: northwest, 1: northeast, 2: southwest, 3: southeast */
if (function == TRANSFORM_HANDLE_N) {
@@ -1062,57 +1054,45 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
opp_l = 3 - this_r; opp_r = 3 - this_l;
- GimpVector2 tl = { .x = px[this_l], .y = py[this_l] },
- tr = { .x = px[this_r], .y = py[this_r] },
- ol = { .x = px[opp_l], .y = py[opp_l] },
- or = { .x = px[opp_r], .y = py[opp_r] },
- p = { .x = dx, .y = dy },
- pivot = { .x = ppivot_x, .y = ppivot_y },
- side_l = vectorsubtract (ol, tl),
- side_r = vectorsubtract (or, tr),
- midline = vectoradd (side_l, side_r);
+ side_l = vectorsubtract (oldpos[opp_l], oldpos[this_l]);
+ side_r = vectorsubtract (oldpos[opp_r], oldpos[this_r]);
+ midline = vectoradd (side_l, side_r);
/* restrict to movement along the midline */
p = vectorproject (p, midline);
if (keepaspect)
{
+ GimpVector2 before, after, effective_pivot = pivot;
+ gdouble distance;
+
if (!frompivot)
{
/* center of the opposite side is pivot */
- pivot = scalemult(vectoradd(ol, or), 0.5);
+ effective_pivot = scalemult (vectoradd (oldpos[opp_l], oldpos[opp_r]), 0.5);
}
- GimpVector2 mouse = { .x = transform_tool->mousex, .y = transform_tool->mousey };
- GimpVector2 cur = { .x = transform_tool->curx, .y = transform_tool->cury };
- GimpVector2 before = vectorsubtract(pivot, mouse);
- GimpVector2 after = vectorsubtract(pivot, cur);
- after = vectorproject(after, before);
-
- gdouble distance = 0.5 * (after.x / before.x + after.y / before.y);
-
- tl = vectoradd(pivot, scalemult(vectorsubtract(tl, pivot), distance));
- tr = vectoradd(pivot, scalemult(vectorsubtract(tr, pivot), distance));
- ol = vectoradd(pivot, scalemult(vectorsubtract(ol, pivot), distance));
- or = vectoradd(pivot, scalemult(vectorsubtract(or, pivot), distance));
+ before = vectorsubtract (effective_pivot, mouse);
+ after = vectorsubtract (effective_pivot, cur);
+ after = vectorproject (after, before);
+
+ distance = 0.5 * (after.x / before.x + after.y / before.y);
+
+ for (i = 0; i < 4; i++)
+ newpos[i] = vectoradd (effective_pivot, scalemult (vectorsubtract (oldpos[i], effective_pivot), distance));
}
else
{
/* just move the side */
- tl = vectoradd (tl, p);
- tr = vectoradd (tr, p);
+ newpos[this_l] = vectoradd (oldpos[this_l], p);
+ newpos[this_r] = vectoradd (oldpos[this_r], p);
+ newpos[opp_l] = oldpos[opp_l];
+ newpos[opp_r] = oldpos[opp_r];
}
- *x[this_l] = tl.x;
- *y[this_l] = tl.y;
-
- *x[this_r] = tr.x;
- *y[this_r] = tr.y;
-
- *x[opp_l] = ol.x;
- *y[opp_l] = ol.y;
-
- *x[opp_r] = or.x;
- *y[opp_r] = or.y;
+ for (i = 0; i < 4; i++) {
+ *x[i] = newpos[i].x;
+ *y[i] = newpos[i].y;
+ }
if (!keepaspect && frompivot)
{
@@ -1132,75 +1112,57 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
function == TRANSFORM_HANDLE_S_S ||
function == TRANSFORM_HANDLE_W_S)
{
- /* o for the opposite edge, for frompivot */
- gint left, right, lefto, righto;
- gdouble dxo, dyo;
+ gint this_l, this_r, opp_l, opp_r;
+ GimpVector2 po, zero = { .x = 0.0, .y = 0.0 };
/* set up indices for this edge and the opposite edge */
if (function == TRANSFORM_HANDLE_N_S) {
- left = 1; right = 0;
+ this_l = 1; this_r = 0;
} else if (function == TRANSFORM_HANDLE_W_S) {
- left = 0; right = 2;
+ this_l = 0; this_r = 2;
} else if (function == TRANSFORM_HANDLE_S_S) {
- left = 2; right = 3;
+ this_l = 2; this_r = 3;
} else if (function == TRANSFORM_HANDLE_E_S) {
- left = 3; right = 1;
+ this_l = 3; this_r = 1;
} else g_assert_not_reached ();
- lefto = 3 - left;
- righto = 3 - right;
+ opp_l = 3 - this_l;
+ opp_r = 3 - this_r;
if (frompivot)
- {
- dxo = -dx;
- dyo = -dy;
- }
+ po = vectorsubtract (zero, p);
else
- {
- dxo = dyo = 0;
- }
+ po = zero;
if (!freeshear)
{
/* restrict to movement along the side */
- GimpVector2 lp = { .x = px[left], .y = py[left] },
- rp = { .x = px[right], .y = py[right] },
- p = { .x = dx, .y = dy },
- side = vectorsubtract (rp, lp);
+ GimpVector2 side = vectorsubtract (oldpos[this_r], oldpos[this_l]);
p = vectorproject (p, side);
-
- dx = p.x;
- dy = p.y;
}
if (!freeshear && frompivot)
{
/* restrict to movement along the opposite side */
- GimpVector2 lp = { .x = px[lefto], .y = py[lefto] },
- rp = { .x = px[righto], .y = py[righto] },
- p = { .x = dxo, .y = dyo },
- side = vectorsubtract (rp, lp);
+ GimpVector2 side = vectorsubtract (oldpos[opp_r], oldpos[opp_l]);
- p = vectorproject (p, side);
-
- dxo = p.x;
- dyo = p.y;
+ po = vectorproject (po, side);
}
- *x[left] = px[left] + dx;
- *y[left] = py[left] + dy;
+ *x[this_l] = oldpos[this_l].x + p.x;
+ *y[this_l] = oldpos[this_l].y + p.y;
- *x[right] = px[right] + dx;
- *y[right] = py[right] + dy;
+ *x[this_r] = oldpos[this_r].x + p.x;
+ *y[this_r] = oldpos[this_r].y + p.y;
/* We have to set these unconditionally, or the opposite edge will stay
* in place when you toggle the frompivot constraint during an action */
- *x[lefto] = px[lefto] + dxo;
- *y[lefto] = py[lefto] + dyo;
+ *x[opp_l] = oldpos[opp_l].x + po.x;
+ *y[opp_l] = oldpos[opp_l].y + po.y;
- *x[righto] = px[righto] + dxo;
- *y[righto] = py[righto] + dyo;
+ *x[opp_r] = oldpos[opp_r].x + po.x;
+ *y[opp_r] = oldpos[opp_r].y + po.y;
}
/* perspective transform */
@@ -1228,45 +1190,33 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
two sides that run to this corner point, or along the
diagonal that runs trough this corner point. */
- GimpVector2 l = { .x = px[left], .y = py[left] };
- GimpVector2 r = { .x = px[right], .y = py[right] };
- GimpVector2 o = { .x = px[opposite], .y = py[opposite] };
- GimpVector2 t = { .x = px[this], .y = py[this] };
- GimpVector2 p = { .x = dx, .y = dy };
- GimpVector2 lp, rp, op;
- gdouble rej_lp, rej_rp, rej_op;
-
- /* get the vectors along the sides and the diagonal */
- l = vectorsubtract (t, l);
- r = vectorsubtract (t, r);
- o = vectorsubtract (t, o);
-
- /* project p on l, r and o and see which has the shortest rejection */
- lp = vectorproject (p, l);
- rp = vectorproject (p, r);
- op = vectorproject (p, o);
-
- rej_lp = norm (vectorsubtract (p, lp));
- rej_rp = norm (vectorsubtract (p, rp));
- rej_op = norm (vectorsubtract (p, op));
-
- if (rej_lp < rej_rp && rej_lp < rej_op)
- p = lp;
- else if (rej_rp < rej_op)
- p = rp;
- else
- p = op;
+ GimpVector2 proj[4];
+ gdouble rej[4];
- dx = p.x;
- dy = p.y;
+ for (i = 0; i < 4; i++)
+ {
+ if (i == this) continue;
+ /* get the vectors along the sides and the diagonal */
+ proj[i] = vectorsubtract (oldpos[this], oldpos[i]);
+ /* project p on each candidate vector and see
+ * which has the shortest rejection */
+ proj[i] = vectorproject (p, proj[i]);
+ rej[i] = norm (vectorsubtract (p, proj[i]));
+ }
+
+ if (rej[left] < rej[right] && rej[left] < rej[opposite])
+ p = proj[left];
+ else if (rej[right] < rej[opposite])
+ p = proj[right];
+ else
+ p = proj[opposite];
}
- *x[this] = px[this] + dx;
- *y[this] = py[this] + dy;
+ *x[this] = oldpos[this].x + p.x;
+ *y[this] = oldpos[this].y + p.y;
- if (frompivot)
+ if (frompivot) //TODO constrain and frompivot are both bound to ctrl
{
- gint i;
GimpVector2 delta = getpivotdelta (transform_tool);
for (i = 0; i < 4; i++)
{
@@ -1280,8 +1230,8 @@ gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
if (!fixedpivot)
{
GimpVector2 delta = getpivotdelta (transform_tool);
- *pivot_x = ppivot_x + delta.x;
- *pivot_y = ppivot_y + delta.y;
+ *newpivot_x = pivot.x + delta.x;
+ *newpivot_y = pivot.y + delta.y;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]