PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ pointArray_svg_arc()

static void pointArray_svg_arc ( stringbuffer_t sb,
const POINTARRAY pa,
int  close_ring,
int  relative,
int  precision 
)
static

angles

endAngle - startAngle <= 180 ? "0" : "1"

add MoveTo first point

is circle: need to start at center of circle

add MoveTo center of circle

is circle need to handle differently

Definition at line 162 of file lwout_svg.c.

163 {
164  uint32_t i; //, end;
165  char sx[OUT_DOUBLE_BUFFER_SIZE];
166  char sy[OUT_DOUBLE_BUFFER_SIZE];
167 
168  LWDEBUG(2, "pointArray_svg_arc called.");
169 
170  for (i = 2; i < pa->npoints; i+=2)
171  {
172  LWDEBUGF(3, "assvg_circstring: arc ending at point %d", i);
173  int largeArcFlag, sweepFlag, clockwise;
174  int is_circle = LW_FALSE;
175  double a1, a3;
176  double radius; /* Arc radius */
177  double total_angle;
178  POINT2D center;
179  const POINT2D *t1;
180  const POINT2D *t2;
181  const POINT2D *t3;
182  int p2_side = 0;
183  t1 = getPoint2d_cp(pa, i - 2);
184  t2 = getPoint2d_cp(pa, i - 1);
185  t3 = getPoint2d_cp(pa, i);
186  radius = lw_arc_center(t1, t2, t3, &center);
187  if ( t1->x == t3->x && t1->y == t3->y ){
188  is_circle = LW_TRUE;
189  }
190  p2_side = lw_segment_side(t1, t3, t2);
191  if ( p2_side == -1 )
192  clockwise = LW_TRUE;
193  else
194  clockwise = LW_FALSE;
195  /* Angles of each point that defines the arc section */
196  a1 = atan2(t1->y - center.y, t1->x - center.x)*180/M_PI;
197  //a2 = atan2(t2->y - center.y, t2->x - center.x)*180/M_PI;
198  a3 = atan2(t3->y - center.y, t3->x - center.x)*180/M_PI;
199 
200  LWDEBUGF(2, " center is POINT(%.15g %.15g) - radius:%g", center.x, center.y, radius);
201 
202  total_angle = clockwise ? a1 - a3 : a3 - a1;
203  if (total_angle < 0 ){
204  total_angle += 360;
205  }
206 
207  //stringbuffer_aprintf(sb, "angles (a1 a2 a3): %g %g %g is_circle: %d, total_angle: %g, t1.x: %f, t3.x: %f, t1.y: %f, t3.y: %f ", a1, a2, a3, is_circle, total_angle, t1->x, t3->x, t1->y, t3->y);
208 
210  largeArcFlag = (total_angle <= 180)? 0 : 1;
211  /* The side of the t1/t3 line that t2 falls on dictates the sweep
212  direction from t1 to t3. */
213  sweepFlag = (p2_side == -1) ? 1 : 0;
214  if ( (i == 2) && !is_circle ){
216  lwprint_double(t1->x, precision, sx);
217  lwprint_double(-(t1->y), precision, sy);
218  stringbuffer_aprintf(sb, "%s %s", sx, sy);
219  }
221  if ( (i == 2) && is_circle){
223  lwprint_double(center.x, precision, sx);
224  lwprint_double(-(center.y), precision, sy);
225  stringbuffer_aprintf(sb, "%s %s", sx, sy);
226  }
227  lwprint_double(radius, precision, sx);
228  lwprint_double(0, precision, sy);
230  if (is_circle){
231  //https://stackoverflow.com/questions/5737975/circle-drawing-with-svgs-arc-path
232  lwprint_double(radius*2, precision, sy);
233  stringbuffer_aprintf(sb, " m %s 0 a %s %s 0 1 0 -%s 0", sx, sx, sx, sy);
234  stringbuffer_aprintf(sb, " a %s %s 0 1 0 %s 0", sx, sx, sy);
235  }
236  else {
237  /* Arc radius radius 0 arcflag swipeflag */
238  if (relative){
239  stringbuffer_aprintf(sb, " a %s %s 0 %d %d ", sx, sx, largeArcFlag, sweepFlag);
240  }
241  else {
242  stringbuffer_aprintf(sb, " A %s %s 0 %d %d ", sx, sx, largeArcFlag, sweepFlag);
243  }
244  lwprint_double(t3->x, precision, sx);
245  lwprint_double(-(t3->y), precision, sy);
246  /* end point */
247  stringbuffer_aprintf(sb, "%s %s", sx, sy);
248  }
249  }
250 }
static uint8_t precision
Definition: cu_in_twkb.c:25
#define LW_FALSE
Definition: liblwgeom.h:94
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
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:226
#define OUT_DOUBLE_BUFFER_SIZE
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition: lwalgorithm.c:62
int lwprint_double(double d, int maxdd, char *buf)
Definition: lwprint.c:457
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:101
int stringbuffer_aprintf(stringbuffer_t *s, const char *fmt,...)
Appends a formatted string to the current string buffer, using the format and argument list provided.
Definition: stringbuffer.c:247
double y
Definition: liblwgeom.h:390
double x
Definition: liblwgeom.h:390
uint32_t npoints
Definition: liblwgeom.h:427

References getPoint2d_cp(), lw_arc_center(), LW_FALSE, lw_segment_side(), LW_TRUE, LWDEBUG, LWDEBUGF, lwprint_double(), POINTARRAY::npoints, OUT_DOUBLE_BUFFER_SIZE, precision, stringbuffer_aprintf(), POINT2D::x, and POINT2D::y.

Referenced by assvg_circstring(), and assvg_compound().

Here is the call graph for this function:
Here is the caller graph for this function: