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.
This commit is contained in:
Werner Almesberger 2015-01-19 02:57:40 -03:00
parent ecb7667c7c
commit 155cfa3d44
1 changed files with 9 additions and 3 deletions

View File

@ -12,6 +12,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
@ -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;
}