PostGIS  3.0.6dev-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 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: