896 const unsigned int min_quad_edges = 2;
900 lwerror(
"pta_unstroke called with null pointarray");
910 lwerror(
"pta_unstroke needs implementation for npoints < 4");
914 num_edges = points->
npoints - 1;
915 edges_in_arcs =
lwalloc(num_edges + 1);
916 memset(edges_in_arcs, 0, num_edges + 1);
920 while( i < num_edges-2 )
922 unsigned int arc_edges;
923 double num_quadrants;
931 memcpy(&first, &a1,
sizeof(
POINT4D));
933 for( j = i+3; j < num_edges+1; j++ )
941 LWDEBUGF(4,
"pt_continues_arc #%d", current_arc);
943 for ( k = j-1; k > j-4; k-- )
944 edges_in_arcs[k] = current_arc;
949 LWDEBUG(4,
"pt_continues_arc = false");
954 memcpy(&a1, &a2,
sizeof(
POINT4D));
955 memcpy(&a2, &a3,
sizeof(
POINT4D));
956 memcpy(&a3, &b,
sizeof(
POINT4D));
965 arc_edges = j - 1 - i;
966 LWDEBUGF(4,
"arc defined by %d edges found", arc_edges);
967 if ( first.
x == b.
x && first.
y == b.
y ) {
975 if ( p2_side >= 0 ) angle = -angle;
977 if ( angle < 0 ) angle = 2 * M_PI + angle;
978 num_quadrants = ( 4 * angle ) / ( 2 * M_PI );
979 LWDEBUGF(4,
"arc angle (%g %g, %g %g, %g %g) is %g (side is %d), quandrants:%g", first.
x, first.
y, center.
x, center.
y, b.
x, b.
y, angle, p2_side, num_quadrants);
982 if ( arc_edges < min_quad_edges * num_quadrants ) {
983 LWDEBUGF(4,
"Not enough edges for a %g quadrants arc, %g needed", num_quadrants, min_quad_edges * num_quadrants);
984 for ( k = j-1; k >= i; k-- )
985 edges_in_arcs[k] = 0;
993 edges_in_arcs[i] = 0;
998 #if POSTGIS_DEBUG_LEVEL > 3 1000 char *edgestr =
lwalloc(num_edges+1);
1001 for ( i = 0; i < num_edges; i++ )
1003 if ( edges_in_arcs[i] )
1004 edgestr[i] = 48 + edges_in_arcs[i];
1008 edgestr[num_edges] = 0;
1009 LWDEBUGF(3,
"edge pattern %s", edgestr);
1015 edge_type = edges_in_arcs[0];
1017 for( i = 1; i < num_edges; i++ )
1019 if( edge_type != edges_in_arcs[i] )
1024 edge_type = edges_in_arcs[i];
1030 end = num_edges - 1;
1034 if ( outcol->
ngeoms == 1 )
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.
static double lw_arc_angle(const POINT2D *a, const POINT2D *b, const POINT2D *c)
Return ABC angle in radians TODO: move to lwalgorithm.
#define LWDEBUG(level, msg)
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 ...
#define LW_TRUE
Return types for functions with status returns.
static LWGEOM * geom_from_pa(const POINTARRAY *pa, int srid, int is_arc, int start, int end)
int ptarray_has_m(const POINTARRAY *pa)
void lwcollection_free(LWCOLLECTION *col)
int ptarray_has_z(const POINTARRAY *pa)
void * lwalloc(size_t size)
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
#define LWDEBUGF(level, msg,...)
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)