PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ 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 234 of file lwalgorithm.c.

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

Here is the caller graph for this function: