PostGIS 3.0.6dev-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 229 of file lwalgorithm.c.

230{
231 POINT2D c;
232 double cx, cy, cr;
233 double dx21, dy21, dx31, dy31, h21, h31, d;
234
235 c.x = c.y = 0.0;
236
237 LWDEBUGF(2, "lw_arc_center called (%.16f,%.16f), (%.16f,%.16f), (%.16f,%.16f).", p1->x, p1->y, p2->x, p2->y, p3->x, p3->y);
238
239 /* Closed circle */
240 if (fabs(p1->x - p3->x) < EPSILON_SQLMM &&
241 fabs(p1->y - p3->y) < EPSILON_SQLMM)
242 {
243 cx = p1->x + (p2->x - p1->x) / 2.0;
244 cy = p1->y + (p2->y - p1->y) / 2.0;
245 c.x = cx;
246 c.y = cy;
247 *result = c;
248 cr = sqrt(pow(cx - p1->x, 2.0) + pow(cy - p1->y, 2.0));
249 return cr;
250 }
251
252 /* Using cartesian eguations from page https://en.wikipedia.org/wiki/Circumscribed_circle */
253 dx21 = p2->x - p1->x;
254 dy21 = p2->y - p1->y;
255 dx31 = p3->x - p1->x;
256 dy31 = p3->y - p1->y;
257
258 h21 = pow(dx21, 2.0) + pow(dy21, 2.0);
259 h31 = pow(dx31, 2.0) + pow(dy31, 2.0);
260
261 /* 2 * |Cross product|, d<0 means clockwise and d>0 counterclockwise sweeping angle */
262 d = 2 * (dx21 * dy31 - dx31 * dy21);
263
264 /* Check colinearity, |Cross product| = 0 */
265 if (fabs(d) < EPSILON_SQLMM)
266 return -1.0;
267
268 /* Calculate centroid coordinates and radius */
269 cx = p1->x + (h21 * dy31 - h31 * dy21) / d;
270 cy = p1->y - (h21 * dx31 - h31 * dx21) / d;
271 c.x = cx;
272 c.y = cy;
273 *result = c;
274 cr = sqrt(pow(cx - p1->x, 2) + pow(cy - p1->y, 2));
275
276 LWDEBUGF(2, "lw_arc_center center is (%.16f,%.16f)", result->x, result->y);
277
278 return cr;
279}
#define EPSILON_SQLMM
Tolerance used to determine equality.
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:88
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376

References EPSILON_SQLMM, LWDEBUGF, 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(), pt_continues_arc(), pta_unstroke(), ptarrayarc_contains_point_partial(), and test_lw_arc_center().

Here is the caller graph for this function: