PostGIS  3.2.2dev-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 237 of file lwalgorithm.c.

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

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

Here is the caller graph for this function: