1582{
1584 double radius_A, radius_B, d;
1586 int pt_in_arc_A, pt_in_arc_B;
1587
1589 lwerror(
"lw_dist2d_arc_arc only supports mindistance");
1590
1591
1592
1593
1600
1601
1604
1605
1606 if (radius_A < 0 && radius_B < 0)
1608
1609
1610 if (radius_A < 0)
1612
1613
1614 if (radius_B < 0)
1616
1617
1619
1620
1623
1624
1625 if (radius_B > radius_A)
1626 {
1629 double td;
1630 tmp = B1;
1631 B1 = A1;
1632 A1 = tmp;
1633 tmp = B2;
1634 B2 = A2;
1635 A2 = tmp;
1636 tmp = B3;
1637 B3 = A3;
1638 A3 = tmp;
1639 TP = CB;
1640 CB = CA;
1641 CA = TP;
1642 td = radius_B;
1643 radius_B = radius_A;
1644 radius_A = td;
1645 }
1646
1647
1648 if (d == (radius_A + radius_B))
1649 {
1650 D.
x = CA.
x + (CB.
x - CA.
x) * radius_A / d;
1651 D.
y = CA.
y + (CB.
y - CA.
y) * radius_A / d;
1652
1655
1656
1657 if (pt_in_arc_A && pt_in_arc_B)
1658 {
1663 }
1664 }
1665
1666
1667 else if (d > (radius_A + radius_B) || d < (radius_A - radius_B) )
1668 {
1670
1671
1672
1673
1674 XA.
x = CA.
x + (CB.
x - CA.
x) * radius_A / d;
1675 XA.
y = CA.
y + (CB.
y - CA.
y) * radius_A / d;
1676 XB.
x = CB.
x + (CA.
x - CB.
x) * radius_B / d;
1677 XB.
y = CB.
y + (CA.
y - CB.
y) * radius_B / d;
1678
1681
1682
1683
1684 if (pt_in_arc_A && pt_in_arc_B)
1685 {
1687 }
1688 }
1689
1690
1691 else if (d < (radius_A + radius_B))
1692 {
1694
1695 double a = (radius_A * radius_A - radius_B * radius_B + d * d) / (2 * d);
1696
1697 double h = sqrt(radius_A * radius_A - a * a);
1698
1699
1700 D.
x = CA.
x + (CB.
x - CA.
x) * a / d;
1701 D.
y = CA.
y + (CB.
y - CA.
y) * a / d;
1702
1703
1704 E.
x = D.
x + (D.
y - CA.
y) * h / a;
1705 E.
y = D.
y + (D.
x - CA.
x) * h / a;
1706
1707
1710
1711 if (pt_in_arc_A && pt_in_arc_B)
1712 {
1713 dl->
p1 = dl->
p2 = E;
1716 }
1717
1718
1719 F.
x = D.
x - (D.
y - CA.
y) * h / a;
1720 F.
y = D.
y - (D.
x - CA.
x) * h / a;
1721
1722
1725
1726 if (pt_in_arc_A && pt_in_arc_B)
1727 {
1728 dl->
p1 = dl->
p2 = F;
1731 }
1732 }
1733 else
1734 {
1735 lwerror(
"lw_dist2d_arc_arc: arcs neither touch, intersect nor are disjoint! INCONCEIVABLE!");
1737 }
1738
1739
1740
1741 if (pt_in_arc_A && !pt_in_arc_B)
1742 {
1746 }
1747
1748
1749 else if (pt_in_arc_B && !pt_in_arc_A)
1750 {
1754 }
1755
1756 else
1757 {
1763 }
1764
1766}
#define LW_TRUE
Return types for functions with status returns.
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.
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) .
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.
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
int lw_dist2d_pt_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, DISTPTS *dl)
int lw_dist2d_arc_arc_concentric(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, double radius_A, const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, double radius_B, const POINT2D *CENTER, DISTPTS *dl)
int lw_dist2d_seg_seg(const POINT2D *A, const POINT2D *B, const POINT2D *C, const POINT2D *D, DISTPTS *dl)
Finds the shortest distance between two segments.
int lw_dist2d_seg_arc(const POINT2D *A1, const POINT2D *A2, const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, DISTPTS *dl)
Calculate the shortest distance between an arc and an edge.
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...