[dia] [matherr] Fix distance_ellipse_point() against returning NAN
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] [matherr] Fix distance_ellipse_point() against returning NAN
- Date: Mon, 15 Oct 2012 11:14:22 +0000 (UTC)
commit 6b9494fc729475d2f8cf53ee344ba2fd7dbc7f8e
Author: Hans Breuer <hans breuer org>
Date: Mon Oct 15 12:18:22 2012 +0200
[matherr] Fix distance_ellipse_point() against returning NAN
The newest unit test checks DiaObject::distance_from(center), which
revealed some mathematical instability in distance_ellipse_point().
Now this code was copied twice to object implementations.
lib/geometry.c | 2 ++
objects/Istar/actor.c | 33 ++-------------------------------
objects/flowchart/ellipse.c | 9 ++++-----
3 files changed, 8 insertions(+), 36 deletions(-)
---
diff --git a/lib/geometry.c b/lib/geometry.c
index 588d75b..7cf4916 100644
--- a/lib/geometry.c
+++ b/lib/geometry.c
@@ -403,6 +403,8 @@ distance_ellipse_point(const Point *centre, real width, real height,
pt.x *= pt.x;
pt.y *= pt.y; /* pt = (point - centre).^2 */
+ if (pt.x <= 0.0 && pt.y <= 0.0)
+ return 0.0; /* instead of division by zero */
scale = w2 * h2 / (4*h2*pt.x + 4*w2*pt.y);
rad = sqrt((pt.x + pt.y)*scale) + line_width/2;
diff --git a/objects/Istar/actor.c b/objects/Istar/actor.c
index f1e5702..43f8a05 100644
--- a/objects/Istar/actor.c
+++ b/objects/Istar/actor.c
@@ -183,31 +183,6 @@ actor_set_props(Actor *actor, GPtrArray *props)
actor_update_data(actor, ANCHOR_MIDDLE, ANCHOR_MIDDLE);
}
-/* returns the radius of the actor along the ray from the centre of the
- * actor to the point (px, py) */
-static real
-actor_radius(Actor *actor, real px, real py)
-{
- Element *elem = &actor->element;
- real w2 = elem->width * elem->width;
- real h2 = elem->height * elem->height;
- real scale;
-
- /* find the point of intersection between line (x=cx+(px-cx)t; y=cy+(py-cy)t)
- * and actor ((x-cx)^2)/(w/2)^2 + ((y-cy)^2)/(h/2)^2 = 1 */
- /* radius along ray is sqrt((px-cx)^2 * t^2 + (py-cy)^2 * t^2) */
-
- /* normalize coordinates ... */
- px -= elem->corner.x + elem->width / 2;
- py -= elem->corner.y + elem->height / 2;
- /* square them ... */
- px *= px;
- py *= py;
-
- scale = w2 * h2 / (4*h2*px + 4*w2*py);
- return sqrt((px + py)*scale);
-}
-
static real
actor_distance_from(Actor *actor, Point *point)
{
@@ -217,13 +192,9 @@ actor_distance_from(Actor *actor, Point *point)
c.x = elem->corner.x + elem->width / 2;
c.y = elem->corner.y + elem->height/ 2;
- dist = distance_point_point(point, &c);
- rad = actor_radius(actor, point->x, point->y) + ACTOR_BORDER_WIDTH/2;
-
- if (dist <= rad)
- return 0;
- return dist - rad;
+ return distance_ellipse_point (&c, elem->width / 2, elem->height/ 2,
+ ACTOR_BORDER_WIDTH, point);
}
static void
diff --git a/objects/flowchart/ellipse.c b/objects/flowchart/ellipse.c
index 6bed6e2..d3723e5 100644
--- a/objects/flowchart/ellipse.c
+++ b/objects/flowchart/ellipse.c
@@ -231,6 +231,8 @@ ellipse_radius(Ellipse *ellipse, real px, real py)
px *= px;
py *= py;
+ if (px <= 0.0 && py <= 0.0)
+ return 0; /* avoid division by zero */
scale = w2 * h2 / (4*h2*px + 4*w2*py);
return sqrt((px + py)*scale);
}
@@ -244,12 +246,9 @@ ellipse_distance_from(Ellipse *ellipse, Point *point)
c.x = elem->corner.x + elem->width / 2;
c.y = elem->corner.y + elem->height/ 2;
- dist = distance_point_point(point, &c);
- rad = ellipse_radius(ellipse, point->x, point->y) + ellipse->border_width/2;
- if (dist <= rad)
- return 0;
- return dist - rad;
+ return distance_ellipse_point (&c, elem->width / 2, elem->height/ 2,
+ ellipse->border_width, point);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]