PostGIS  3.4.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 226 of file lwalgorithm.c.

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