gimp r24609 - in trunk: . app/tools
- From: martinn svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r24609 - in trunk: . app/tools
- Date: Mon, 14 Jan 2008 21:23:03 +0000 (GMT)
Author: martinn
Date: Mon Jan 14 21:23:02 2008
New Revision: 24609
URL: http://svn.gnome.org/viewvc/gimp?rev=24609&view=rev
Log:
2008-01-14 Martin Nordholts <martinn svn gnome org>
* app/tools/tools-utils.[ch]
(gimp_tool_motion_constrain): Generalized to allow a variable
number of lines for snapping, and rewritten to make snapping
happen more intuitively; snap the shortest distance rather than
only horizontally or vertically.
(gimp_tool_utils_point_to_line_distance): New helper function.
* app/tools/gimpblendtool.c
* app/tools/gimpmeasuretool.c
* app/tools/gimppainttool.c: Adjust to the new function signature.
Modified:
trunk/ChangeLog
trunk/app/tools/gimpblendtool.c
trunk/app/tools/gimpmeasuretool.c
trunk/app/tools/gimppainttool.c
trunk/app/tools/tools-utils.c
trunk/app/tools/tools-utils.h
Modified: trunk/app/tools/gimpblendtool.c
==============================================================================
--- trunk/app/tools/gimpblendtool.c (original)
+++ trunk/app/tools/gimpblendtool.c Mon Jan 14 21:23:02 2008
@@ -46,7 +46,8 @@
#include "gimp-intl.h"
-#define TARGET_SIZE 15
+#define TARGET_SIZE 15
+#define N_SNAP_LINES 12
/* local function prototypes */
@@ -287,7 +288,8 @@
if (state & GDK_CONTROL_MASK)
{
gimp_tool_motion_constrain (blend_tool->start_x, blend_tool->start_y,
- &blend_tool->end_x, &blend_tool->end_y);
+ &blend_tool->end_x, &blend_tool->end_y,
+ N_SNAP_LINES);
}
gimp_tool_pop_status (tool, display);
@@ -319,7 +321,8 @@
if (press)
{
gimp_tool_motion_constrain (blend_tool->start_x, blend_tool->start_y,
- &blend_tool->end_x, &blend_tool->end_y);
+ &blend_tool->end_x, &blend_tool->end_y,
+ N_SNAP_LINES);
}
gimp_tool_pop_status (tool, display);
Modified: trunk/app/tools/gimpmeasuretool.c
==============================================================================
--- trunk/app/tools/gimpmeasuretool.c (original)
+++ trunk/app/tools/gimpmeasuretool.c Mon Jan 14 21:23:02 2008
@@ -54,6 +54,7 @@
#define TARGET 12
#define ARC_RADIUS 30
+#define N_SNAP_LINES 12
/* local function prototypes */
@@ -434,7 +435,9 @@
gdouble x = measure->x[i];
gdouble y = measure->y[i];
- gimp_tool_motion_constrain (measure->x[0], measure->y[0], &x, &y);
+ gimp_tool_motion_constrain (measure->x[0], measure->y[0],
+ &x, &y,
+ N_SNAP_LINES);
measure->x[i] = ROUND (x);
measure->y[i] = ROUND (y);
@@ -505,7 +508,9 @@
y = measure->mouse_y;
if (press)
- gimp_tool_motion_constrain (measure->x[0], measure->y[0], &x, &y);
+ gimp_tool_motion_constrain (measure->x[0], measure->y[0],
+ &x, &y,
+ N_SNAP_LINES);
measure->x[measure->point] = ROUND (x);
measure->y[measure->point] = ROUND (y);
Modified: trunk/app/tools/gimppainttool.c
==============================================================================
--- trunk/app/tools/gimppainttool.c (original)
+++ trunk/app/tools/gimppainttool.c Mon Jan 14 21:23:02 2008
@@ -51,6 +51,7 @@
#define HANDLE_SIZE 15
#define STATUSBAR_SIZE 200
+#define N_SNAP_LINES 12
static GObject * gimp_paint_tool_constructor (GType type,
@@ -256,7 +257,8 @@
/* Restrict to multiples of 15 degrees if ctrl is pressed */
if (state & GDK_CONTROL_MASK)
gimp_tool_motion_constrain (core->last_coords.x, core->last_coords.y,
- &core->cur_coords.x, &core->cur_coords.y);
+ &core->cur_coords.x, &core->cur_coords.y,
+ N_SNAP_LINES);
}
static void
Modified: trunk/app/tools/tools-utils.c
==============================================================================
--- trunk/app/tools/tools-utils.c (original)
+++ trunk/app/tools/tools-utils.c Mon Jan 14 21:23:02 2008
@@ -25,34 +25,46 @@
#include "tools-utils.h"
+static gdouble gimp_tool_utils_point_to_line_distance (const GimpVector2 *point,
+ const GimpVector2 *point_on_line,
+ const GimpVector2 *normalized_line_direction,
+ GimpVector2 *closest_line_point);
+
+
/**
- * gimp_tool_motion_constrain_helper:
- * @dx: the (fixed) delta-x
- * @dy: a suggested delta-y
+ * gimp_tool_utils_point_to_line_distance:
+ * @point: The point to calculate the distance for.
+ * @point_on_line: A point on the line.
+ * @line_direction: Normalized line direction vector.
+ * @closest_line_point: Gets set to the point on the line that is
+ * closest to @point.
*
- * Returns: An adjusted dy' near dy such that the slope (dx,dy')
- * is a multiple of 15 degrees.
+ * Returns: The shortest distance from @point to the line defined by
+ * @point_on_line and @normalized_line_direction.
**/
static gdouble
-gimp_tool_motion_constrain_helper (gdouble dx,
- gdouble dy)
+gimp_tool_utils_point_to_line_distance (const GimpVector2 *point,
+ const GimpVector2 *point_on_line,
+ const GimpVector2 *line_direction,
+ GimpVector2 *closest_line_point)
{
- static const gdouble slope[4] = { 0, 0.26795, 0.57735, 1 };
- static const gdouble divider[3] = { 0.13165, 0.41421, 0.76732 };
- gint i;
+ GimpVector2 distance_vector;
+ GimpVector2 tmp_a;
+ GimpVector2 tmp_b;
+ gdouble d;
+
+ gimp_vector2_sub (&tmp_a, point, point_on_line);
- if (dy < 0)
- return - gimp_tool_motion_constrain_helper (dx, -dy);
+ d = gimp_vector2_inner_product (&tmp_a, line_direction);
- dx = fabs (dx);
+ tmp_b = gimp_vector2_mul_val (*line_direction, d);
- for (i = 0; i < 3; i ++)
- if (dy < dx * divider[i])
- break;
+ *closest_line_point = gimp_vector2_add_val (*point_on_line,
+ tmp_b);
- dy = dx * slope[i];
+ gimp_vector2_sub (&distance_vector, closest_line_point, point);
- return dy;
+ return gimp_vector2_length (&distance_vector);
}
/**
@@ -61,33 +73,47 @@
* @start_y:
* @end_x:
* @end_y:
+ * @n_snap_lines: Number evenly disributed lines to snap to.
*
- * Restricts the motion vector to 15 degree steps by changing the end
- * point (if necessary).
+ * Projects a line onto the specified subset of evenly radially
+ * distributed lines. @n_lines of 2 makes the line snap horizontally
+ * or vertically. @n_lines of 4 snaps on 45 degree steps. @n_lines of
+ * 12 on 15 degree steps. etc.
**/
void
-gimp_tool_motion_constrain (gdouble start_x,
- gdouble start_y,
- gdouble *end_x,
- gdouble *end_y)
+gimp_tool_motion_constrain (gdouble start_x,
+ gdouble start_y,
+ gdouble *end_x,
+ gdouble *end_y,
+ gint n_snap_lines)
{
- gdouble dx = *end_x - start_x;
- gdouble dy = *end_y - start_y;
-
- /* This algorithm changes only one of dx and dy, and does not try
- * to constrain the resulting dx and dy to integers. This gives
- * at least two benefits:
- * 1. gimp_tool_motion_constrain is idempotent, even if followed by
- * a rounding operation.
- * 2. For any two lines with the same starting-point and ideal
- * 15-degree direction, the points plotted by
- * gimp_paint_core_interpolate for the shorter line will always
- * be a superset of those plotted for the longer line.
- */
-
- if (fabs (dx) > fabs (dy))
- *end_y = (start_y + gimp_tool_motion_constrain_helper (dx, dy));
- else
- *end_x = (start_x + gimp_tool_motion_constrain_helper (dy, dx));
+ GimpVector2 line_point = { start_x, start_y };
+ GimpVector2 point = { *end_x, *end_y };
+ GimpVector2 constrained_point;
+ GimpVector2 line_dir;
+ gdouble shortest_dist_moved = G_MAXDOUBLE;
+ gdouble dist_moved;
+ gdouble angle;
+ gint i;
+
+ for (i = 0; i < n_snap_lines; i++)
+ {
+ angle = i * G_PI / n_snap_lines;
+
+ gimp_vector2_set (&line_dir,
+ cos (angle),
+ sin (angle));
+
+ dist_moved = gimp_tool_utils_point_to_line_distance (&point,
+ &line_point,
+ &line_dir,
+ &constrained_point);
+ if (dist_moved < shortest_dist_moved)
+ {
+ shortest_dist_moved = dist_moved;
+
+ *end_x = constrained_point.x;
+ *end_y = constrained_point.y;
+ }
+ }
}
-
Modified: trunk/app/tools/tools-utils.h
==============================================================================
--- trunk/app/tools/tools-utils.h (original)
+++ trunk/app/tools/tools-utils.h Mon Jan 14 21:23:02 2008
@@ -23,7 +23,8 @@
void gimp_tool_motion_constrain (gdouble start_x,
gdouble start_y,
gdouble *end_x,
- gdouble *end_y);
+ gdouble *end_y,
+ gint n_snap_lines);
#endif /* __TOOLS_UTILS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]