1000 const unsigned int min_quad_edges = 2;
1004 lwerror(
"pta_unstroke called with null pointarray");
1014 lwerror(
"pta_unstroke needs implementation for npoints < 4");
1018 num_edges = points->
npoints - 1;
1019 edges_in_arcs =
lwalloc(num_edges + 1);
1020 memset(edges_in_arcs, 0, num_edges + 1);
1024 while( i < num_edges-2 )
1026 unsigned int arc_edges;
1027 double num_quadrants;
1035 memcpy(&first, &a1,
sizeof(
POINT4D));
1037 for( j = i+3; j < num_edges+1; j++ )
1045 LWDEBUGF(4,
"pt_continues_arc #%d", current_arc);
1047 for ( k = j-1; k > j-4; k-- )
1048 edges_in_arcs[k] = current_arc;
1053 LWDEBUG(4,
"pt_continues_arc = false");
1058 memcpy(&a1, &a2,
sizeof(
POINT4D));
1059 memcpy(&a2, &a3,
sizeof(
POINT4D));
1060 memcpy(&a3, &b,
sizeof(
POINT4D));
1069 arc_edges = j - 1 - i;
1070 LWDEBUGF(4,
"arc defined by %d edges found", arc_edges);
1071 if ( first.
x == b.
x && first.
y == b.
y ) {
1072 LWDEBUG(4,
"arc is a circle");
1079 if ( p2_side >= 0 ) angle = -angle;
1081 if ( angle < 0 ) angle = 2 * M_PI + angle;
1082 num_quadrants = ( 4 * angle ) / ( 2 * M_PI );
1083 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);
1086 if ( arc_edges < min_quad_edges * num_quadrants ) {
1087 LWDEBUGF(4,
"Not enough edges for a %g quadrants arc, %g needed", num_quadrants, min_quad_edges * num_quadrants);
1088 for ( k = j-1; k >= i; k-- )
1089 edges_in_arcs[k] = 0;
1097 edges_in_arcs[i] = 0;
1102 #if POSTGIS_DEBUG_LEVEL > 3
1104 char *edgestr =
lwalloc(num_edges+1);
1105 for ( i = 0; i < num_edges; i++ )
1107 if ( edges_in_arcs[i] )
1108 edgestr[i] = 48 + edges_in_arcs[i];
1112 edgestr[num_edges] = 0;
1113 LWDEBUGF(3,
"edge pattern %s", edgestr);
1119 edge_type = edges_in_arcs[0];
1121 for( i = 1; i < num_edges; i++ )
1123 if( edge_type != edges_in_arcs[i] )
1128 edge_type = edges_in_arcs[i];
1134 end = num_edges - 1;
1138 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)