897 const unsigned int min_quad_edges = 2;
901 lwerror(
"pta_unstroke called with null pointarray");
911 lwerror(
"pta_unstroke needs implementation for npoints < 4");
915 num_edges = points->
npoints - 1;
916 edges_in_arcs =
lwalloc(num_edges + 1);
917 memset(edges_in_arcs, 0, num_edges + 1);
921 while( i < num_edges-2 )
923 unsigned int arc_edges;
924 double num_quadrants;
932 memcpy(&first, &a1,
sizeof(
POINT4D));
934 for( j = i+3; j < num_edges+1; j++ )
942 LWDEBUGF(4,
"pt_continues_arc #%d", current_arc);
944 for ( k = j-1; k > j-4; k-- )
945 edges_in_arcs[k] = current_arc;
950 LWDEBUG(4,
"pt_continues_arc = false");
955 memcpy(&a1, &a2,
sizeof(
POINT4D));
956 memcpy(&a2, &a3,
sizeof(
POINT4D));
957 memcpy(&a3, &b,
sizeof(
POINT4D));
966 arc_edges = j - 1 - i;
967 LWDEBUGF(4,
"arc defined by %d edges found", arc_edges);
968 if ( first.
x == b.
x && first.
y == b.
y ) {
976 if ( p2_side >= 0 ) angle = -angle;
978 if ( angle < 0 ) angle = 2 * M_PI + angle;
979 num_quadrants = ( 4 * angle ) / ( 2 * M_PI );
980 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);
983 if ( arc_edges < min_quad_edges * num_quadrants ) {
984 LWDEBUGF(4,
"Not enough edges for a %g quadrants arc, %g needed", num_quadrants, min_quad_edges * num_quadrants);
985 for ( k = j-1; k >= i; k-- )
986 edges_in_arcs[k] = 0;
994 edges_in_arcs[i] = 0;
999 #if POSTGIS_DEBUG_LEVEL > 3
1001 char *edgestr =
lwalloc(num_edges+1);
1002 for ( i = 0; i < num_edges; i++ )
1004 if ( edges_in_arcs[i] )
1005 edgestr[i] = 48 + edges_in_arcs[i];
1009 edgestr[num_edges] = 0;
1010 LWDEBUGF(3,
"edge pattern %s", edgestr);
1016 edge_type = edges_in_arcs[0];
1018 for( i = 1; i < num_edges; i++ )
1020 if( edge_type != edges_in_arcs[i] )
1025 edge_type = edges_in_arcs[i];
1031 end = num_edges - 1;
1035 if ( outcol->
ngeoms == 1 )
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int 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 LWGEOM * geom_from_pa(const POINTARRAY *pa, int srid, int is_arc, int start, int end)
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 ...