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

◆ lw_arc_center()

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.

In the event the circle is complete, the midpoint of the segment defined by the first and second points is returned. If the points are collinear, as determined by equal slopes, then -1.0 is returned. If the interior point is coincident with either end point, they are taken as collinear. For non-collinear cases, arc radious is returned.

Definition at line 244 of file lwalgorithm.c.

245{
246 POINT2D c;
247 double cx, cy, cr;
248 double dx21, dy21, dx31, dy31, h21, h31, d;
249
250 c.x = c.y = 0.0;
251
252 LWDEBUGF(2, "lw_arc_center called (%.16f,%.16f), (%.16f,%.16f), (%.16f,%.16f).", p1->x, p1->y, p2->x, p2->y, p3->x, p3->y);
253
254 /* Closed circle */
255 if (fabs(p1->x - p3->x) < EPSILON_SQLMM &&
256 fabs(p1->y - p3->y) < EPSILON_SQLMM)
257 {
258 cx = p1->x + (p2->x - p1->x) / 2.0;
259 cy = p1->y + (p2->y - p1->y) / 2.0;
260 c.x = cx;
261 c.y = cy;
262 *result = c;
263 cr = sqrt(pow(cx - p1->x, 2.0) + pow(cy - p1->y, 2.0));
264 return cr;
265 }
266
267 /* Using cartesian eguations from page https://en.wikipedia.org/wiki/Circumscribed_circle */
268 dx21 = p2->x - p1->x;
269 dy21 = p2->y - p1->y;
270 dx31 = p3->x - p1->x;
271 dy31 = p3->y - p1->y;
272
273 h21 = pow(dx21, 2.0) + pow(dy21, 2.0);
274 h31 = pow(dx31, 2.0) + pow(dy31, 2.0);
275
276 /* 2 * |Cross product|, d<0 means clockwise and d>0 counterclockwise sweeping angle */
277 d = 2 * (dx21 * dy31 - dx31 * dy21);
278
279 /* Check colinearity, |Cross product| = 0 */
280 if (fabs(d) < EPSILON_SQLMM)
281 return -1.0;
282
283 /* Calculate centroid coordinates and radius */
284 cx = p1->x + (h21 * dy31 - h31 * dy21) / d;
285 cy = p1->y - (h21 * dx31 - h31 * dx21) / d;
286 c.x = cx;
287 c.y = cy;
288 *result = c;
289 cr = sqrt(pow(cx - p1->x, 2) + pow(cy - p1->y, 2));
290
291 LWDEBUGF(2, "lw_arc_center center is (%.16f,%.16f)", result->x, result->y);
292
293 return cr;
294}
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition cu_print.c:267
#define EPSILON_SQLMM
Tolerance used to determine equality.
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390

References EPSILON_SQLMM, LWDEBUGF, result, POINT2D::x, and POINT2D::y.

Referenced by lw_arc_calculate_gbox_cartesian_2d(), lw_arc_length(), lw_arc_side(), lw_dist2d_arc_arc(), lw_dist2d_pt_arc(), lw_dist2d_seg_arc(), lwarc_linearize(), pointArray_svg_arc(), pt_continues_arc(), pta_unstroke(), ptarrayarc_raycast_intersections(), and test_lw_arc_center().

Here is the caller graph for this function: