From 155cfa3d445721cbafec10a8f8f5b803f751ef4f Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 19 Jan 2015 02:57:40 -0300 Subject: [PATCH] poly2d/p2d_attrib.c (angle_3): prevent acos() domain errors Rounding errors could push us slightly outside the [-1, 1] range, which caused acos() to return NaN, which in turn broke p2d_is_cw, and eventually tripped create_interior_skeleton_and_offset_polygons_with_holes_2. --- poly2d/p2d_attrib.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/poly2d/p2d_attrib.c b/poly2d/p2d_attrib.c index 42ece8c..f4edf5d 100644 --- a/poly2d/p2d_attrib.c +++ b/poly2d/p2d_attrib.c @@ -12,6 +12,7 @@ #include +#include #include #include @@ -27,7 +28,7 @@ static double angle_3(const struct v2d *a, const struct v2d *b, const struct v2d *c) { double ax, ay, bx, by; - double aa, bb; + double cs, aa, bb; double cross, angle; ax = b->x - a->x; @@ -42,8 +43,13 @@ static double angle_3(const struct v2d *a, const struct v2d *b, aa = hypot(ax, ay); bb = hypot(bx, by); - angle = acos((ax * bx + ay * by) / aa / bb) / M_PI * 180.0; - + cs = (ax * bx + ay * by) / aa / bb; + if (cs <= -1) + angle = 180; + else if (cs >= 1) + angle = 0; + else + angle = acos(cs) / M_PI * 180.0; return cross >= 0 ? angle : -angle; }