PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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);
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.
#define OUT_DOUBLE_BUFFER_SIZE
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition lwalgorithm.c:70
int lwprint_double(double d, int maxdd, char *buf)
Definition lwprint.c:463
#define LWDEBUG(level, msg)
Definition lwgeom_log.h:101
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
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:97
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.
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: