return ogeom;
}
+/**
+ * Return ABC angle in radians
+ * TODO: move to lwalgorithm
+ */
+static double
+lw_arc_angle(const POINT2D *a, const POINT2D *b, const POINT2D *c)
+{
+ POINT2D ab, cb;
+
+ ab.x = b->x - a->x;
+ ab.y = b->y - a->y;
+
+ cb.x = b->x - c->x;
+ cb.y = b->y - c->y;
+
+ double dot = (ab.x * cb.x + ab.y * cb.y); /* dot product */
+ double cross = (ab.x * cb.y - ab.y * cb.x); /* cross product */
+
+ double alpha = atan2(cross, dot);
+
+ return alpha;
+}
/**
* Returns LW_TRUE if b is on the arc formed by a1/a2/a3, but not within
{
int a2_side = lw_segment_side(t1, t3, t2);
int b_side = lw_segment_side(t1, t3, tb);
-
+ double angle1 = lw_arc_angle(t1, t2, t3);
+ double angle2 = lw_arc_angle(t2, t3, tb);
+
+ /* Is the angle similar to the previous one ? */
+ diff = fabs(angle1 - angle2);
+ LWDEBUGF(4, " angle1: %g, angle2: %g, diff:%g", angle1, angle2, diff);
+ if ( diff > EPSILON_SQLMM )
+ {
+ return LW_FALSE;
+ }
+
/* Is the point b on the same side of a1/a3 as the mid-point a2 is? */
/* If not, it's in the unbounded part of the circle, so it continues the arc, return true. */
if ( b_side != a2_side )
{
int i = 0, j, k;
POINT4D a1, a2, a3, b;
+ POINT4D first;
char *edges_in_arcs;
int found_arc = LW_FALSE;
int current_arc = 1;
getPoint4d_p(points, i , &a1);
getPoint4d_p(points, i+1, &a2);
getPoint4d_p(points, i+2, &a3);
+ memcpy(&first, &a1, sizeof(POINT4D));
+
for( j = i+3; j < num_edges+1; j++ )
{
LWDEBUGF(4, "i=%d, j=%d", i, j);
current_arc++;
break;
}
+
+ memcpy(&a1, &a2, sizeof(POINT4D));
+ memcpy(&a2, &a3, sizeof(POINT4D));
+ memcpy(&a3, &b, sizeof(POINT4D));
}
/* Jump past all the edges that were added to the arc */
if ( found_arc )
arc_edges = j - 1 - i;
num_quadrants = 1; /* silly guess, TODO: compute */
LWDEBUGF(4, "arc defined by %d edges found", arc_edges);
- if ( a1.x == b.x && a1.y == b.y ) {
+ if ( first.x == b.x && first.y == b.y ) {
LWDEBUG(4, "arc is a circle");
num_quadrants = 4;
}
#179a|
NOTICE: No points or linestrings in input array
#179b|
-#183|CIRCULARSTRING(0 0,0.5 1.2071067812,0 1)
+#183|COMPOUNDCURVE(CIRCULARSTRING(0 0,0.4653039147 1.2062550401,1 0),(1 0,0 1))
#210a|
NOTICE: No points or linestrings in input array
#210b|
#2415.2|MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(10 0,15 1,20 0,18 5,20 10,10 10,10 0)))
#2412|LINESTRING(0 0,10 0,20 0)
#2420|LINESTRING(0 0,10 0,10 10,0 10,0 0)
+#2423|POLYGON((-10 0,-9.2388 3.82683,-7.07107 7.07107,-3.82683 9.2388,0 10,3.82683 9.2388,7.07107 7.07107,9.2388 3.82683,10 0,-10 0))