[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: gaf.git: branch: master updated (1.5.0-20080706-74-g4ef611b)



The branch, master has been updated
       via  4ef611b6e1cc6eb47538148ce1d196d495313969 (commit)
      from  371c37024225e506b1018445e61f4392e13d7db9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 gschem/src/o_find.c              |    6 ++-
 libgeda/include/prototype.h      |    2 +
 libgeda/include/prototype_priv.h |    8 +++
 libgeda/src/o_arc_basic.c        |   97 ++++++++++++++++++++++++++++++++++++++
 libgeda/src/o_basic.c            |   66 ++++++++++++++++++++++++++
 libgeda/src/o_box_basic.c        |   51 ++++++++++++++++++++
 libgeda/src/o_circle_basic.c     |   30 ++++++++++++
 libgeda/src/o_complex_basic.c    |   40 ++++++++++++++++
 libgeda/src/o_line_basic.c       |   62 ++++++++++++++++++++++++
 libgeda/src/o_picture.c          |   43 +++++++++++++++++
 libgeda/src/o_text_basic.c       |   42 ++++++++++++++++
 11 files changed, 445 insertions(+), 2 deletions(-)


=================
 Commit Messages
=================

commit 4ef611b6e1cc6eb47538148ce1d196d495313969
Author: Edward Hennessy <ehennes@xxxxxxxxxxxxx>
Date:   Fri Jul 18 20:24:46 2008 -0700

    Altered point selection mechanism to use distance instead of just a bounding box.
    
    This patch improves the mechanism used to select objects when using a single
    point.  In addition to using the bounding box, this patch calculates the
    distance between the selection point and the object itself.  This calculated
    distance provides a more accurate means to determine the actual object the user
    selected.
    
    Signed-off-by: Peter TB Brett <peter@xxxxxxxxxxxxx>

:100644 100644 54236e1... b060df2... M	gschem/src/o_find.c
:100644 100644 c6f6fc0... 12f3f64... M	libgeda/include/prototype.h
:100644 100644 2b58fff... 3563338... M	libgeda/include/prototype_priv.h
:100644 100644 0055bee... 455ec54... M	libgeda/src/o_arc_basic.c
:100644 100644 5426c54... c1a0691... M	libgeda/src/o_basic.c
:100644 100644 dd488eb... 5f13c67... M	libgeda/src/o_box_basic.c
:100644 100644 0a58d4e... fc7e49a... M	libgeda/src/o_circle_basic.c
:100644 100644 39703fb... 716ad64... M	libgeda/src/o_complex_basic.c
:100644 100644 034f0dd... 625206a... M	libgeda/src/o_line_basic.c
:100644 100644 acc9b0c... e86649a... M	libgeda/src/o_picture.c
:100644 100644 468b442... 8c1dc92... M	libgeda/src/o_text_basic.c

=========
 Changes
=========

commit 4ef611b6e1cc6eb47538148ce1d196d495313969
Author: Edward Hennessy <ehennes@xxxxxxxxxxxxx>
Date:   Fri Jul 18 20:24:46 2008 -0700

    Altered point selection mechanism to use distance instead of just a bounding box.
    
    This patch improves the mechanism used to select objects when using a single
    point.  In addition to using the bounding box, this patch calculates the
    distance between the selection point and the object itself.  This calculated
    distance provides a more accurate means to determine the actual object the user
    selected.
    
    Signed-off-by: Peter TB Brett <peter@xxxxxxxxxxxxx>

diff --git a/gschem/src/o_find.c b/gschem/src/o_find.c
index 54236e1..b060df2 100644
--- a/gschem/src/o_find.c
+++ b/gschem/src/o_find.c
@@ -57,7 +57,8 @@ gboolean o_find_object(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y,
   while (o_current != NULL) {
     if (inside_region(o_current->w_left - w_slack, o_current->w_top - w_slack,
                       o_current->w_right + w_slack, o_current->w_bottom + w_slack,
-                      w_x, w_y)) {
+                      w_x, w_y) &&
+        o_shortest_distance( o_current, w_x, w_y ) < w_slack ) {
       if (o_current->sel_func != NULL &&
 	  o_current->type != OBJ_HEAD &&
 	  (o_current->visibility == VISIBLE ||
@@ -89,7 +90,8 @@ gboolean o_find_object(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y,
          o_current != toplevel->page_current->object_lastplace) {
     if (inside_region(o_current->w_left - w_slack, o_current->w_top - w_slack,
                       o_current->w_right + w_slack, o_current->w_bottom + w_slack,
-                      w_x, w_y)) {
+                      w_x, w_y) &&
+        o_shortest_distance( o_current, w_x, w_y ) < w_slack ) {
       
       if (o_current->sel_func != NULL &&
           o_current->type != OBJ_HEAD &&
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index c6f6fc0..12f3f64 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -139,6 +139,8 @@ void o_set_fill_options(TOPLEVEL *toplevel, OBJECT *o_current, OBJECT_FILLING ty
 void o_translate_world (TOPLEVEL *toplevel, gint dx, gint dy, OBJECT *object);
 void o_rotate_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, int angle, OBJECT *object);
 void o_mirror_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, OBJECT *object);
+gdouble o_shortest_distance(OBJECT *object, gint x, gint y);
+
 /* o_box_basic.c */
 OBJECT *o_box_add(TOPLEVEL *toplevel, OBJECT *object_list, char type, int color, int x1, int y1, int x2, int y2);
 OBJECT *o_box_copy(TOPLEVEL *toplevel, OBJECT *list_tail, OBJECT *o_current);
diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index 2b58fff..3563338 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -61,6 +61,8 @@ void o_arc_print_dotted(TOPLEVEL *toplevel, FILE *fp, int x, int y, int radius,
 void o_arc_print_dashed(TOPLEVEL *toplevel, FILE *fp, int x, int y, int radius, int angle1, int angle2, int color, int arc_width, int length, int space, int origin_x, int origin_y);
 void o_arc_print_center(TOPLEVEL *toplevel, FILE *fp, int x, int y, int radius, int angle1, int angle2, int color, int arc_width, int length, int space, int origin_x, int origin_y);
 void o_arc_print_phantom(TOPLEVEL *toplevel, FILE *fp, int x, int y, int radius, int angle1, int angle2, int color, int arc_width, int length, int space, int origin_x, int origin_y);
+gdouble o_arc_shortest_distance(ARC *arc, gint x, gint y);
+gboolean o_arc_within_sweep(ARC *arc, gint x, gint y);
 
 /* o_attrib.c */
 OBJECT *o_read_attribs(TOPLEVEL *toplevel,
@@ -82,6 +84,7 @@ void o_box_print_phantom(TOPLEVEL *toplevel, FILE *fp, int x, int y, int width,
 void o_box_print_filled(TOPLEVEL *toplevel, FILE *fp, int x, int y, int width, int height, int color, int fill_width, int angle1, int pitch1, int angle2, int pitch2, int origin_x, int origin_y);
 void o_box_print_mesh(TOPLEVEL *toplevel, FILE *fp, int x, int y, int width, int height, int color, int fill_width, int angle1, int pitch1, int angle2, int pitch2, int origin_x, int origin_y);
 void o_box_print_hatch(TOPLEVEL *toplevel, FILE *fp, int x, int y, int width, int height, int color, int fill_width, int angle1, int pitch1, int angle2, int pitch2, int origin_x, int origin_y);
+gdouble o_box_shortest_distance(BOX *box, gint x, gint y);
 
 /* o_bus_basic.c */
 OBJECT *o_bus_read(TOPLEVEL *toplevel, OBJECT *object_list, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
@@ -100,10 +103,12 @@ void o_circle_print_phantom(TOPLEVEL *toplevel, FILE *fp, int x, int y, int radi
 void o_circle_print_filled(TOPLEVEL *toplevel, FILE *fp, int x, int y, int radius, int color, int fill_width, int angle1, int pitch1, int angle2, int pitch2, int origin_x, int origin_y);
 void o_circle_print_mesh(TOPLEVEL *toplevel, FILE *fp, int x, int y, int radius, int color, int fill_width, int angle1, int pitch1, int angle2, int pitch2, int origin_x, int origin_y);
 void o_circle_print_hatch(TOPLEVEL *toplevel, FILE *fp, int x, int y, int radius, int color, int fill_width, int angle1, int pitch1, int angle2, int pitch2, int origin_x, int origin_y);
+gdouble o_circle_shortest_distance(CIRCLE *circle, gint x, gint y);
 
 /* o_complex_basic.c */
 OBJECT *o_complex_read(TOPLEVEL *toplevel, OBJECT *object_list, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
 char *o_complex_save(OBJECT *object);
+gdouble o_complex_shortest_distance(COMPLEX *complex, gint x, gint y);
 
 /* o_line_basic.c */
 OBJECT *o_line_read(TOPLEVEL *toplevel, OBJECT *object_list, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
@@ -114,6 +119,7 @@ void o_line_print_dotted(TOPLEVEL *toplevel, FILE *fp, int x1, int y1, int x2, i
 void o_line_print_dashed(TOPLEVEL *toplevel, FILE *fp, int x1, int y1, int x2, int y2, int color, int line_width, int length, int space, int origin_x, int origin_y);
 void o_line_print_center(TOPLEVEL *toplevel, FILE *fp, int x1, int y1, int x2, int y2, int color, int line_width, int length, int space, int origin_x, int origin_y);
 void o_line_print_phantom(TOPLEVEL *toplevel, FILE *fp, int x1, int y1, int x2, int y2, int color, int line_width, int length, int space, int origin_x, int origin_y);
+gdouble o_line_shortest_distance(LINE *line, gint x, gint y);
 
 /* o_net_basic.c */
 OBJECT *o_net_read(TOPLEVEL *toplevel, OBJECT *object_list, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
@@ -129,6 +135,7 @@ OBJECT *o_picture_read(TOPLEVEL *toplevel, OBJECT *object_list,
 char *o_picture_save(OBJECT *object);
 void o_picture_print(TOPLEVEL *toplevel, FILE *fp, OBJECT *o_current,
 		     int origin_x, int origin_y);
+gdouble o_picture_shortest_distance(PICTURE *picture, gint x, gint y);
 
 /* o_pin_basic.c */
 OBJECT *o_pin_read(TOPLEVEL *toplevel, OBJECT *object_list, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
@@ -148,6 +155,7 @@ void o_text_print_text_height(FILE *fp, int size);
 void o_text_print_text_height_full(FILE *fp, char *string, int size);
 void o_text_print_text_string(FILE *fp, char *string, int unicode_count, gunichar *unicode_table);
 void o_text_print(TOPLEVEL *toplevel, FILE *fp, OBJECT *o_current, int origin_x, int origin_y, int unicode_count, gunichar *unicode_table);
+gdouble o_text_shortest_distance(TEXT *text, gint x, gint y);
 
 /* s_clib.c */
 void s_clib_init (void);
diff --git a/libgeda/src/o_arc_basic.c b/libgeda/src/o_arc_basic.c
index 0055bee..455ec54 100644
--- a/libgeda/src/o_arc_basic.c
+++ b/libgeda/src/o_arc_basic.c
@@ -1238,3 +1238,100 @@ void o_arc_print_phantom(TOPLEVEL *toplevel, FILE *fp,
 	  x,y, radius, arc_width);
 }
 
+/*! \brief Calculates the distance between the given point and the closest
+ * point on the perimeter of the arc.
+ *
+ *  \param [in] object The object, where object->arc != NULL.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return The shortest distance from the object to the point.  With an
+ *  invalid parameter, this function returns G_MAXDOUBLE.
+ */
+gdouble o_arc_shortest_distance(ARC *arc, gint x, gint y)
+{
+  gdouble radius;
+  gdouble shortest_distance;
+
+  if (arc == NULL) {
+    g_critical("o_arc_shortest_distance(): arc == NULL\n");
+    return G_MAXDOUBLE;
+  }
+
+  radius = ((gdouble) arc->width) / 2.0;
+
+  if ( o_arc_within_sweep(arc, x, y) ) {
+    gdouble distance_to_center;
+    gdouble dx;
+    gdouble dy;
+
+    dx = ((gdouble) x) - ((gdouble) arc->x);
+    dy = ((gdouble) y) - ((gdouble) arc->y);
+
+    distance_to_center = sqrt((dx*dx) + (dy*dy));
+
+    shortest_distance = fabs(distance_to_center - radius);
+  }
+  else {
+    gdouble angle;
+    gdouble distance_to_end0;
+    gdouble distance_to_end1;
+    gdouble dx;
+    gdouble dy;
+
+    angle = G_PI * ((gdouble) arc->start_angle ) / 180;
+
+    dx = ((gdouble) x) - radius*cos(angle) - ((gdouble) arc->x);
+    dy = ((gdouble) y) - radius*sin(angle) - ((gdouble) arc->y);
+
+    distance_to_end0 = sqrt((dx*dx) + (dy*dy));
+
+    angle += G_PI * ((gdouble) arc->end_angle ) / 180;
+
+    dx = ((gdouble) x) - radius*cos(angle) - ((gdouble) arc->x);
+    dy = ((gdouble) y) - radius*sin(angle) - ((gdouble) arc->y);
+
+    distance_to_end1 = sqrt((dx*dx) + (dy*dy));
+
+    shortest_distance = min(distance_to_end0, distance_to_end1);
+  }
+
+  return shortest_distance;
+}
+
+/*! \brief Determines if a point lies within the sweep of the arc.
+ *
+ *  \param [in] object The object, where object->arc != NULL.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return TRUE if the point lies within the sweep of the arc.
+ *  FALSE if the point lies outside the sweep of the arc. With an 
+ *  invalid parameter, this function returns FALSE.
+ */
+gboolean o_arc_within_sweep(ARC *arc, gint x, gint y)
+{
+  gdouble a0;
+  gdouble a1;
+  gdouble angle;
+  gdouble dx;
+  gdouble dy;
+
+  if (arc == NULL) {
+    g_critical("o_arc_within_sweep(): arc == NULL\n");
+    return FALSE;
+  }
+
+  dx = ((gdouble) x) - ((gdouble) arc->x);
+  dy = ((gdouble) y) - ((gdouble) arc->y);
+
+  angle = 180 * atan2(dy, dx) / G_PI;
+
+  a0 = (gdouble) arc->start_angle;
+  a1 = ((gdouble) arc->end_angle) + a0;
+
+  while (angle < a0) {
+    angle+=360;
+  }
+
+  return (angle < a1);
+}
+
diff --git a/libgeda/src/o_basic.c b/libgeda/src/o_basic.c
index 5426c54..c1a0691 100644
--- a/libgeda/src/o_basic.c
+++ b/libgeda/src/o_basic.c
@@ -366,3 +366,69 @@ void o_mirror_world (TOPLEVEL *toplevel, int world_centerx, int world_centery, O
     (*func) (toplevel, world_centerx, world_centery, object);
   }
 }
+
+/*! \brief Calculates the distance between the given point and the closest
+ * point on the given object.
+ *
+ *  \param [in] object The given object.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return The shortest distance from the object to the point. If the
+ *  distance cannot be calculated, this function returns a really large
+ *  number (G_MAXDOUBLE).  If an error occurs, this function returns
+ *  G_MAXDOUBLE.
+ */
+gdouble o_shortest_distance(OBJECT *object, gint x, gint y)
+{
+  gdouble shortest_distance = G_MAXDOUBLE;
+
+  if (object == NULL) {
+    g_critical("o_shortest_distance(): object == NULL\n");
+    return G_MAXDOUBLE;
+  }
+
+
+  switch(object->type) {
+
+    case(OBJ_ARC):
+      shortest_distance = o_arc_shortest_distance(object->arc, x, y);
+      break;
+
+    case(OBJ_BOX):
+      shortest_distance = o_box_shortest_distance(object->box, x, y);
+      break;
+
+    case(OBJ_BUS):
+    case(OBJ_LINE):
+    case(OBJ_NET):
+    case(OBJ_PIN):
+      shortest_distance = o_line_shortest_distance(object->line, x, y);
+      break;
+
+    case(OBJ_CIRCLE):
+      shortest_distance = o_circle_shortest_distance(object->circle, x, y);
+      break;
+
+    case(OBJ_COMPLEX):
+    case(OBJ_PLACEHOLDER):
+      shortest_distance = o_complex_shortest_distance(object->complex, x, y);
+      break;
+
+    case(OBJ_HEAD):
+      break;
+
+    case(OBJ_PICTURE):
+      shortest_distance = o_picture_shortest_distance(object->picture, x, y);
+      break;
+
+    case(OBJ_TEXT):
+      shortest_distance = o_text_shortest_distance(object->text, x, y);
+      break;
+
+    default:
+      g_critical ("o_shortest_distance: object %p has bad type '%c'\n",
+                  object, object->type);
+  }
+  return shortest_distance;
+}
+
diff --git a/libgeda/src/o_box_basic.c b/libgeda/src/o_box_basic.c
index dd488eb..5f13c67 100644
--- a/libgeda/src/o_box_basic.c
+++ b/libgeda/src/o_box_basic.c
@@ -1440,4 +1440,55 @@ void o_box_print_hatch(TOPLEVEL *toplevel, FILE *fp,
   }
 }
 
+/*! \brief Calculates the distance between the given point and the closest
+ * point on the perimeter of the box.
+ *
+ *  \param [in] object The object, where object->box != NULL.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return The shortest distance from the object to the point.  With an 
+ *  invalid parameter, this function returns G_MAXDOUBLE.
+ */
+gdouble o_box_shortest_distance(BOX *box, gint x, gint y)
+{
+  gdouble dx;
+  gdouble dy;
+  gdouble shortest_distance;
+  gdouble x0;
+  gdouble x1;
+  gdouble y0;
+  gdouble y1;
+
+  if (box == NULL) {
+    g_critical("o_box_shortest_distance(): box == NULL\n");
+    return G_MAXDOUBLE;
+  }
+
+  x0 = (gdouble) min(box->upper_x, box->lower_x);
+  x1 = (gdouble) max(box->upper_x, box->lower_x);
+  y0 = (gdouble) min(box->upper_y, box->lower_y);
+  y1 = (gdouble) max(box->upper_y, box->lower_y);
+
+  dx = min(((gdouble) x)-x0, x1-((gdouble) x));
+  dy = min(((gdouble) y)-y0, y1-((gdouble) y));
+
+  if ( dx < 0 ) {
+    if ( dy < 0 ) {
+      shortest_distance = sqrt((dx*dx) + (dy*dy));
+    }
+    else {
+      shortest_distance = fabs(dx);
+    }
+  }
+  else {
+    if ( dy < 0 ) {
+      shortest_distance = fabs(dy);
+    }
+    else {
+      shortest_distance = min(dx,dy);
+    }
+  }
+
+  return shortest_distance;
+}
 
diff --git a/libgeda/src/o_circle_basic.c b/libgeda/src/o_circle_basic.c
index 0a58d4e..fc7e49a 100644
--- a/libgeda/src/o_circle_basic.c
+++ b/libgeda/src/o_circle_basic.c
@@ -1133,4 +1133,34 @@ void o_circle_print_hatch(TOPLEVEL *toplevel, FILE *fp,
   }
 }
 
+/*! \brief Calculates the distance between the given point and the closest
+ * point on the perimeter of the circle.
+ *
+ *  \param [in] object The object, where object->circle != NULL.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return The shortest distance from the object to the point.  With an
+ *  invalid parameter, this function returns G_MAXDOUBLE.
+ */
+gdouble o_circle_shortest_distance(CIRCLE *circle, gint x, gint y)
+{
+  gdouble distance_to_center;
+  gdouble dx;
+  gdouble dy;
+  gdouble shortest_distance;
+
+  if (circle == NULL) {
+    g_critical("o_circle_shortest_distance(): circle == NULL\n");
+    return FALSE;
+  }
+
+  dx = ((gdouble) x) - ((gdouble) circle->center_x);
+  dy = ((gdouble) y) - ((gdouble) circle->center_y);
+
+  distance_to_center = sqrt((dx*dx) + (dy*dy));
+
+  shortest_distance = fabs(distance_to_center - circle->radius);
+
+  return shortest_distance;
+}
 
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 39703fb..716ad64 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -1507,3 +1507,43 @@ done:
   g_free(outside);
   g_free(refdes);
 }
+
+/*! \brief Calculates the distance between the given point and the closest
+ * point on an object within the complex object.
+ *
+ *  \param [in] object The object, where object->complex != NULL.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return The shortest distance from the object to the point. If the
+ *  distance cannot be calculated, this function returns a really large
+ *  number (G_MAXDOUBLE).  With an invalid parameter, this function returns
+ *  G_MAXDOUBLE.
+ */
+gdouble o_complex_shortest_distance(COMPLEX *complex, gint x, gint y)
+{
+  gdouble distance;
+  gdouble shortest_distance = G_MAXDOUBLE;
+  OBJECT *temp;
+
+  if (complex == NULL) {
+    g_critical("o_complex_shortest_distance(): complex == NULL\n");
+    return G_MAXDOUBLE;
+  }
+
+  temp = complex->prim_objs;
+
+  if (temp != NULL) {
+    temp = temp->next;
+  }
+
+  while (temp != NULL) {
+    distance = o_shortest_distance(temp, x, y);
+
+    shortest_distance = min(shortest_distance, distance);
+
+    temp = temp->next;
+  }
+
+  return shortest_distance;
+}
+
diff --git a/libgeda/src/o_line_basic.c b/libgeda/src/o_line_basic.c
index 034f0dd..625206a 100644
--- a/libgeda/src/o_line_basic.c
+++ b/libgeda/src/o_line_basic.c
@@ -1234,3 +1234,65 @@ double o_line_length(OBJECT *object)
                 
   return(length);
 }
+
+/*! \brief Calculates the distance between the given point and the closest
+ *  point on the given line segment.
+ *
+ *  If the closest point on the line resides beyond the line segment's
+ *  end point, this function returns the distance from the given point to the
+ *  closest end point.
+ *
+ *  \param [in] object The object, where object->line != NULL.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return The shortest distance from the object to the point.  With an
+ *  invalid parameter, this function returns G_MAXDOUBLE.
+ */
+gdouble o_line_shortest_distance(LINE *line, gint x, gint y)
+{
+  gdouble cx;
+  gdouble cy;
+  gdouble dx;
+  gdouble dx0;
+  gdouble dy;
+  gdouble dy0;
+  gdouble ldx;
+  gdouble ldy;
+  gdouble lx0;
+  gdouble ly0;
+  gdouble shortest_distance;
+  gdouble t;
+
+  if (line == NULL) {
+    g_critical("o_line_shortest_distance(): line == NULL\n");
+    return G_MAXDOUBLE;
+  }
+
+  lx0 = (double) line->x[0];
+  ly0 = (double) line->y[0];
+  ldx = ((double) line->x[1]) - ((double) line->x[0]);
+  ldy = ((double) line->y[1]) - ((double) line->y[0]);
+
+  /* calculate parametric value of perpendicular intersection */
+  dx0 = ldx * ( x - lx0 );
+  dy0 = ldy * ( y - ly0 );
+
+  t = (dx0 + dy0) / ((ldx*ldx) + (ldy*ldy));
+
+  /* constrain the parametric value to a point on the line */
+  t = max(t, 0);
+  t = min(t, 1);
+
+  /* calculate closest point on the line */
+  cx = t * ldx + lx0;
+  cy = t * ldy + ly0;
+
+  /* calculate distance to closest point */
+  dx = x-cx;
+  dy = y-cy;
+
+  shortest_distance = sqrt( (dx*dx) + (dy*dy) );
+
+  return shortest_distance;
+}
+
diff --git a/libgeda/src/o_picture.c b/libgeda/src/o_picture.c
index acc9b0c..e86649a 100644
--- a/libgeda/src/o_picture.c
+++ b/libgeda/src/o_picture.c
@@ -1036,3 +1036,46 @@ GdkPixbuf *o_picture_pixbuf_from_buffer (gchar *file_content,
 
   return pixbuf;
 }
+
+/*! \brief Calculates the distance between the given point and the closest
+ * point in the picture.
+ *
+ *  Interrior points within the picture return a distance of zero.
+ *
+ *  \param [in] object The object, where object->picture != NULL.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return The shortest distance from the object to the point.  With an
+ *  invalid parameter, this function returns G_MAXDOUBLE.
+ */
+gdouble o_picture_shortest_distance(PICTURE *picture, gint x, gint y)
+{
+  gdouble dx;
+  gdouble dy;
+  gdouble shortest_distance;
+  gdouble x0;
+  gdouble x1;
+  gdouble y0;
+  gdouble y1;
+
+  if (picture == NULL) {
+    g_critical("o_picture_shortest_distance(): picture == NULL\n");
+    return G_MAXDOUBLE;
+  }
+
+  x0 = (gdouble) min(picture->upper_x, picture->lower_x);
+  x1 = (gdouble) max(picture->upper_x, picture->lower_x);
+  y0 = (gdouble) min(picture->upper_y, picture->lower_y);
+  y1 = (gdouble) max(picture->upper_y, picture->lower_y);
+
+  dx = min(((gdouble) x)-x0, x1-((gdouble) x));
+  dy = min(((gdouble) y)-y0, y1-((gdouble) y));
+
+  dx = min(dx, 0);
+  dy = min(dy, 0);
+
+  shortest_distance = sqrt((dx*dx) + (dy*dy));
+
+  return shortest_distance;
+}
+
diff --git a/libgeda/src/o_text_basic.c b/libgeda/src/o_text_basic.c
index 468b442..8c1dc92 100644
--- a/libgeda/src/o_text_basic.c
+++ b/libgeda/src/o_text_basic.c
@@ -1852,3 +1852,45 @@ void o_text_mirror_world(TOPLEVEL *toplevel,
   o_text_recreate(toplevel, object);
 }
 
+/*! \brief Calculates the distance between the given point and the closest
+ *  point on the text.
+ *
+ *  This function will calculate the distance to the text regardless
+ *  if the text is visible or not.
+ *
+ *  \param [in] object The object, where object->text != NULL.
+ *  \param [in] x The x coordinate of the given point.
+ *  \param [in] y The y coordinate of the given point.
+ *  \return The shortest distance from the object to the point. If the
+ *  distance cannot be calculated, this function returns a really large
+ *  number (G_MAXDOUBLE).  With an invalid parameter, this funciton
+ *  returns G_MAXDOUBLE.
+ */
+gdouble o_text_shortest_distance(TEXT *text, gint x, gint y)
+{
+  gdouble distance;
+  gdouble shortest_distance = G_MAXDOUBLE;
+  OBJECT *temp;
+
+  if (text == NULL) {
+    g_critical("o_text_shortest_distance(): text == NULL\n");
+    return G_MAXDOUBLE;
+  }
+
+  temp = text->prim_objs;
+
+  if (temp != NULL) {
+    temp = temp->next;
+  }
+
+  while (temp != NULL) {
+    distance = o_shortest_distance(temp, x, y);
+
+    shortest_distance = min(shortest_distance, distance);
+
+    temp = temp->next;
+  }
+
+  return shortest_distance;
+}
+




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs