[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