PostGIS  3.2.2dev-r@@SVN_REVISION@@

◆ lw_dist2d_circle_circle_intersections()

static uint32_t lw_dist2d_circle_circle_intersections ( const POINT2D cA,
double  rA,
const POINT2D cB,
double  rB,
POINT2D I 
)
static

Calculates the intersection points of two overlapping circles.

This function assumes the circles are known to intersect at one or two points. Specifically, the distance 'd' between their centers must satisfy: d < (rA + rB) and d > fabs(rA - rB) If these conditions are not met, the results are undefined.

Parameters
cA[in] Pointer to the center point of the first circle (A).
rA[in] The radius of the first circle (A).
cB[in] Pointer to the center point of the second circle (B).
rB[in] The radius of the second circle (B).
I[out] Pointer to an array of at least 2 POINT2D structs to store the results. I[0] will contain the first intersection point. If a second exists, it will be in I[1].
Returns
int The number of intersection points found (1 or 2). Returns 0 if the centers are coincident or another error occurs.

Definition at line 1626 of file measures.c.

1630 {
1631  // Vector from center A to center B
1632  double dx = cB->x - cA->x;
1633  double dy = cB->y - cA->y;
1634 
1635  // Distance between the centers
1636  double d = sqrt(dx * dx + dy * dy);
1637 
1638  // 'a' is the distance from the center of circle A to the point P,
1639  // which is the base of the right triangle formed by cA, P, and an intersection point.
1640  double a = (rA * rA - rB * rB + d * d) / (2.0 * d);
1641 
1642  // 'h' is the height of that right triangle.
1643  double h_squared = rA * rA - a * a;
1644 
1645  // Due to floating point errors, h_squared can be slightly negative.
1646  // This happens when the circles are perfectly tangent. Clamp to 0.
1647  if (h_squared < 0.0)
1648  h_squared = 0.0;
1649 
1650  double h = sqrt(h_squared);
1651 
1652  // Find the coordinates of point P
1653  double Px = cA->x + a * (dx / d);
1654  double Py = cA->y + a * (dy / d);
1655 
1656  // The two intersection points are found by moving from P by a distance 'h'
1657  // in directions perpendicular to the line connecting the centers.
1658  // The perpendicular vector to (dx, dy) is (-dy, dx).
1659 
1660  // Intersection point 1
1661  I[0].x = Px - h * (dy / d);
1662  I[0].y = Py + h * (dx / d);
1663 
1664  // If h is very close to 0, the circles are tangent and there's only one intersection point.
1665  if (FP_IS_ZERO(h))
1666  return 1;
1667 
1668  // Intersection point 2
1669  I[1].x = Px + h * (dy / d);
1670  I[1].y = Py - h * (dx / d);
1671 
1672  return 2;
1673 }
#define FP_IS_ZERO(A)
double y
Definition: liblwgeom.h:404
double x
Definition: liblwgeom.h:404

References FP_IS_ZERO, POINT2D::x, and POINT2D::y.

Referenced by lw_dist2d_arc_arc().

Here is the caller graph for this function: