PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ lw_dist2d_pt_arc()

int lw_dist2d_pt_arc ( const POINT2D P,
const POINT2D A1,
const POINT2D A2,
const POINT2D A3,
DISTPTS dl 
)

Definition at line 1512 of file measures.c.

1513 {
1514  double radius_A, d;
1515  POINT2D C; /* center of circle defined by arc A */
1516  POINT2D X; /* point circle(A) where line from C to P crosses */
1517 
1518  if (dl->mode < 0)
1519  lwerror("lw_dist2d_pt_arc does not support maxdistance mode");
1520 
1521  /* What if the arc is a point? */
1522  if (lw_arc_is_pt(A1, A2, A3))
1523  return lw_dist2d_pt_pt(P, A1, dl);
1524 
1525  /* Calculate centers and radii of circles. */
1526  radius_A = lw_arc_center(A1, A2, A3, &C);
1527 
1528  /* This "arc" is actually a line (A2 is colinear with A1,A3) */
1529  if (radius_A < 0.0)
1530  return lw_dist2d_pt_seg(P, A1, A3, dl);
1531 
1532  /* Distance from point to center */
1533  d = distance2d_pt_pt(&C, P);
1534 
1535  /* P is the center of the circle */
1536  if (FP_EQUALS(d, 0.0))
1537  {
1538  dl->distance = radius_A;
1539  dl->p1 = *A1;
1540  dl->p2 = *P;
1541  return LW_TRUE;
1542  }
1543 
1544  /* X is the point on the circle where the line from P to C crosses */
1545  X.x = C.x + (P->x - C.x) * radius_A / d;
1546  X.y = C.y + (P->y - C.y) * radius_A / d;
1547 
1548  /* Is crossing point inside the arc? Or arc is actually circle? */
1549  if (p2d_same(A1, A3) || lw_pt_in_arc(&X, A1, A2, A3))
1550  {
1551  lw_dist2d_pt_pt(P, &X, dl);
1552  }
1553  else
1554  {
1555  /* Distance is the minimum of the distances to the arc end points */
1556  lw_dist2d_pt_pt(A1, P, dl);
1557  lw_dist2d_pt_pt(A3, P, dl);
1558  }
1559  return LW_TRUE;
1560 }
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:107
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.
Definition: lwalgorithm.c:229
#define FP_EQUALS(A, B)
int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3)
Returns true if arc A is actually a point (all vertices are the same) .
Definition: lwalgorithm.c:106
int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3)
Returns true if P is on the same side of the plane partition defined by A1/A3 as A2 is.
Definition: lwalgorithm.c:86
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition: lwalgorithm.c:50
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:2397
int lw_dist2d_pt_seg(const POINT2D *p, const POINT2D *A, const POINT2D *B, DISTPTS *dl)
lw_dist2d_comp from p to line A->B This one is now sending every occasion to lw_dist2d_pt_pt Before i...
Definition: measures.c:2305
int lw_dist2d_pt_pt(const POINT2D *thep1, const POINT2D *thep2, DISTPTS *dl)
Compares incoming points and stores the points closest to each other or most far away from each other...
Definition: measures.c:2365
POINT2D p1
Definition: measures.h:52
POINT2D p2
Definition: measures.h:53
int mode
Definition: measures.h:54
double distance
Definition: measures.h:51
double y
Definition: liblwgeom.h:376
double x
Definition: liblwgeom.h:376

References DISTPTS::distance, distance2d_pt_pt(), FP_EQUALS, lw_arc_center(), lw_arc_is_pt(), lw_dist2d_pt_pt(), lw_dist2d_pt_seg(), lw_pt_in_arc(), LW_TRUE, lwerror(), DISTPTS::mode, DISTPTS::p1, DISTPTS::p2, p2d_same(), POINT2D::x, and POINT2D::y.

Referenced by lw_dist2d_arc_arc(), lw_dist2d_pt_ptarrayarc(), lw_dist2d_seg_arc(), rect_leaf_node_distance(), rect_leaf_node_intersects(), and test_lw_dist2d_pt_arc().

Here is the call graph for this function:
Here is the caller graph for this function: