988 const unsigned int min_quad_edges = 2;
992 lwerror(
"pta_unstroke called with null pointarray");
1002 lwerror(
"pta_unstroke needs implementation for npoints < 4");
1006 num_edges = points->
npoints - 1;
1007 edges_in_arcs =
lwalloc(num_edges + 1);
1008 memset(edges_in_arcs, 0, num_edges + 1);
1012 while( i < num_edges-2 )
1014 unsigned int arc_edges;
1015 double num_quadrants;
1023 memcpy(&first, &a1,
sizeof(
POINT4D));
1025 for( j = i+3; j < num_edges+1; j++ )
1033 LWDEBUGF(4,
"pt_continues_arc #%d", current_arc);
1035 for ( k = j-1; k > j-4; k-- )
1036 edges_in_arcs[k] = current_arc;
1041 LWDEBUG(4,
"pt_continues_arc = false");
1046 memcpy(&a1, &a2,
sizeof(
POINT4D));
1047 memcpy(&a2, &a3,
sizeof(
POINT4D));
1048 memcpy(&a3, &b,
sizeof(
POINT4D));
1057 arc_edges = j - 1 - i;
1058 LWDEBUGF(4,
"arc defined by %d edges found", arc_edges);
1059 if ( first.
x == b.
x && first.
y == b.
y ) {
1060 LWDEBUG(4,
"arc is a circle");
1067 if ( p2_side >= 0 ) angle = -angle;
1069 if ( angle < 0 ) angle = 2 * M_PI + angle;
1070 num_quadrants = ( 4 * angle ) / ( 2 * M_PI );
1071 LWDEBUGF(4,
"arc angle (%g %g, %g %g, %g %g) is %g (side is %d), quadrants:%g", first.
x, first.
y, center.
x, center.
y, b.
x, b.
y, angle, p2_side, num_quadrants);
1074 if ( arc_edges < min_quad_edges * num_quadrants ) {
1075 LWDEBUGF(4,
"Not enough edges for a %g quadrants arc, %g needed", num_quadrants, min_quad_edges * num_quadrants);
1076 for ( k = j-1; k >= i; k-- )
1077 edges_in_arcs[k] = 0;
1085 edges_in_arcs[i] = 0;
1090 #if POSTGIS_DEBUG_LEVEL > 3
1092 char *edgestr =
lwalloc(num_edges+1);
1093 for ( i = 0; i < num_edges; i++ )
1095 if ( edges_in_arcs[i] )
1096 edgestr[i] = 48 + edges_in_arcs[i];
1100 edgestr[num_edges] = 0;
1101 LWDEBUGF(3,
"edge pattern %s", edgestr);
1107 edge_type = edges_in_arcs[0];
1109 for( i = 1; i < num_edges; i++ )
1111 if( edge_type != edges_in_arcs[i] )
1116 edge_type = edges_in_arcs[i];
1122 end = num_edges - 1;
1126 if ( outcol->
ngeoms == 1 )
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
void lwcollection_free(LWCOLLECTION *col)
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
void * lwalloc(size_t size)
#define LW_TRUE
Return types for functions with status returns.
double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, POINT2D *result)
Determines the center of the circle defined by the three given points.
int ptarray_has_z(const POINTARRAY *pa)
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
int ptarray_has_m(const POINTARRAY *pa)
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
static double lw_arc_angle(const POINT2D *a, const POINT2D *b, const POINT2D *c)
Return ABC angle in radians TODO: move to lwalgorithm.
static int pt_continues_arc(const POINT4D *a1, const POINT4D *a2, const POINT4D *a3, const POINT4D *b)
Returns LW_TRUE if b is on the arc formed by a1/a2/a3, but not within that portion already described ...
static LWGEOM * geom_from_pa(const POINTARRAY *pa, int32_t srid, int is_arc, int start, int end)