PostGIS  3.3.9dev-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 1637 of file measures.c.

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

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

Referenced by lw_dist2d_arc_arc().

Here is the caller graph for this function: