PostGIS  2.1.10dev-r@@SVN_REVISION@@
static POINTARRAY* lwcircle_segmentize ( POINT4D p1,
POINT4D p2,
POINT4D p3,
uint32_t  perQuad 
)
static

Definition at line 103 of file lwsegmentize.c.

References interpolate_arc(), lw_arc_center(), LW_FALSE, lw_segment_side(), LW_TRUE, LWDEBUG, POINT4D::m, ptarray_append_point(), ptarray_construct_empty(), POINT2D::x, POINT4D::x, POINT2D::y, POINT4D::y, and POINT4D::z.

Referenced by lwcircstring_segmentize().

104 {
105  POINT2D center;
106  POINT2D *t1 = (POINT2D*)p1;
107  POINT2D *t2 = (POINT2D*)p2;
108  POINT2D *t3 = (POINT2D*)p3;
109  POINT4D pt;
110  int p2_side = 0;
111  int clockwise = LW_TRUE;
112  double radius; /* Arc radius */
113  double increment; /* Angle per segment */
114  double a1, a2, a3, angle;
115  POINTARRAY *pa;
116  int is_circle = LW_FALSE;
117 
118  LWDEBUG(2, "lwcircle_calculate_gbox called.");
119 
120  radius = lw_arc_center(t1, t2, t3, &center);
121  p2_side = lw_segment_side(t1, t3, t2);
122 
123  /* Matched start/end points imply circle */
124  if ( p1->x == p3->x && p1->y == p3->y )
125  is_circle = LW_TRUE;
126 
127  /* Negative radius signals straight line, p1/p2/p3 are colinear */
128  if ( (radius < 0.0 || p2_side == 0) && ! is_circle )
129  return NULL;
130 
131  /* The side of the p1/p3 line that p2 falls on dictates the sweep
132  direction from p1 to p3. */
133  if ( p2_side == -1 )
134  clockwise = LW_TRUE;
135  else
136  clockwise = LW_FALSE;
137 
138  increment = fabs(M_PI_2 / perQuad);
139 
140  /* Angles of each point that defines the arc section */
141  a1 = atan2(p1->y - center.y, p1->x - center.x);
142  a2 = atan2(p2->y - center.y, p2->x - center.x);
143  a3 = atan2(p3->y - center.y, p3->x - center.x);
144 
145  /* p2 on left side => clockwise sweep */
146  if ( clockwise )
147  {
148  increment *= -1;
149  /* Adjust a3 down so we can decrement from a1 to a3 cleanly */
150  if ( a3 > a1 )
151  a3 -= 2.0 * M_PI;
152  if ( a2 > a1 )
153  a2 -= 2.0 * M_PI;
154  }
155  /* p2 on right side => counter-clockwise sweep */
156  else
157  {
158  /* Adjust a3 up so we can increment from a1 to a3 cleanly */
159  if ( a3 < a1 )
160  a3 += 2.0 * M_PI;
161  if ( a2 < a1 )
162  a2 += 2.0 * M_PI;
163  }
164 
165  /* Override angles for circle case */
166  if( is_circle )
167  {
168  a3 = a1 + 2.0 * M_PI;
169  a2 = a1 + M_PI;
170  increment = fabs(increment);
171  clockwise = LW_FALSE;
172  }
173 
174  /* Initialize point array */
175  pa = ptarray_construct_empty(1, 1, 32);
176 
177  /* Sweep from a1 to a3 */
179  for ( angle = a1 + increment; clockwise ? angle > a3 : angle < a3; angle += increment )
180  {
181  pt.x = center.x + radius * cos(angle);
182  pt.y = center.y + radius * sin(angle);
183  pt.z = interpolate_arc(angle, a1, a2, a3, p1->z, p2->z, p3->z);
184  pt.m = interpolate_arc(angle, a1, a2, a3, p1->m, p2->m, p3->m);
185  ptarray_append_point(pa, &pt, LW_FALSE);
186  }
187  return pa;
188 }
double x
Definition: liblwgeom.h:308
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.
Definition: lwalgorithm.c:228
double m
Definition: liblwgeom.h:308
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:57
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
double x
Definition: liblwgeom.h:284
static double interpolate_arc(double angle, double a1, double a2, double a3, double zm1, double zm2, double zm3)
Definition: lwsegmentize.c:81
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_TRUE, then a duplicate point will not be added.
Definition: ptarray.c:141
#define LW_FALSE
Definition: liblwgeom.h:52
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:51
double y
Definition: liblwgeom.h:284
double z
Definition: liblwgeom.h:308
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition: lwalgorithm.c:62
double y
Definition: liblwgeom.h:308

Here is the call graph for this function:

Here is the caller graph for this function: