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