PostGIS  2.2.7dev-r@@SVN_REVISION@@
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 
)

Definition at line 1660 of file measures.c.

References DISTPTS::distance, distance2d_sqr_pt_pt(), lw_segment_side(), LW_TRUE, DISTPTS::p1, DISTPTS::p2, POINT2D::x, and POINT2D::y.

Referenced by lw_dist2d_arc_arc().

1665 {
1666  int seg_size;
1667  double dist_sqr, shortest_sqr;
1668  const POINT2D *P1;
1669  const POINT2D *P2;
1670  POINT2D proj;
1671 
1672  if (radius_A == radius_B)
1673  {
1674  /* Check if B1 or B3 are in the same side as A2 in the A1-A3 arc */
1675  seg_size = lw_segment_side(A1, A3, A2);
1676  if (seg_size == lw_segment_side(A1, A3, B1))
1677  {
1678  dl->p1 = *B1;
1679  dl->p2 = *B1;
1680  dl->distance = 0;
1681  return LW_TRUE;
1682  }
1683  if (seg_size == lw_segment_side(A1, A3, B3))
1684  {
1685  dl->p1 = *B3;
1686  dl->p2 = *B3;
1687  dl->distance = 0;
1688  return LW_TRUE;
1689  }
1690  /* Check if A1 or A3 are in the same side as B2 in the B1-B3 arc */
1691  seg_size = lw_segment_side(B1, B3, B2);
1692  if (seg_size == lw_segment_side(B1, B3, A1))
1693  {
1694  dl->p1 = *A1;
1695  dl->p2 = *A1;
1696  dl->distance = 0;
1697  return LW_TRUE;
1698  }
1699  if (seg_size == lw_segment_side(B1, B3, A3))
1700  {
1701  dl->p1 = *A3;
1702  dl->p2 = *A3;
1703  dl->distance = 0;
1704  return LW_TRUE;
1705  }
1706  }
1707  else
1708  {
1709  /* Check if any projection of B ends are in A*/
1710  seg_size = lw_segment_side(A1, A3, A2);
1711 
1712  /* B1 */
1713  proj.x = CENTER->x + (B1->x - CENTER->x) * radius_A / radius_B;
1714  proj.y = CENTER->y + (B1->y - CENTER->y) * radius_A / radius_B;
1715 
1716  if (seg_size == lw_segment_side(A1, A3, &proj))
1717  {
1718  dl->p1 = proj;
1719  dl->p2 = *B1;
1720  dl->distance = fabs(radius_A - radius_B);
1721  return LW_TRUE;
1722  }
1723  /* B3 */
1724  proj.x = CENTER->x + (B3->x - CENTER->x) * radius_A / radius_B;
1725  proj.y = CENTER->y + (B3->y - CENTER->y) * radius_A / radius_B;
1726  if (seg_size == lw_segment_side(A1, A3, &proj))
1727  {
1728  dl->p1 = proj;
1729  dl->p2 = *B3;
1730  dl->distance = fabs(radius_A - radius_B);
1731  return LW_TRUE;
1732  }
1733 
1734  /* Now check projections of A in B */
1735  seg_size = lw_segment_side(B1, B3, B2);
1736 
1737  /* A1 */
1738  proj.x = CENTER->x + (A1->x - CENTER->x) * radius_B / radius_A;
1739  proj.y = CENTER->y + (A1->y - CENTER->y) * radius_B / radius_A;
1740  if (seg_size == lw_segment_side(B1, B3, &proj))
1741  {
1742  dl->p1 = proj;
1743  dl->p2 = *A1;
1744  dl->distance = fabs(radius_A - radius_B);
1745  return LW_TRUE;
1746  }
1747 
1748  /* A3 */
1749  proj.x = CENTER->x + (A3->x - CENTER->x) * radius_B / radius_A;
1750  proj.y = CENTER->y + (A3->y - CENTER->y) * radius_B / radius_A;
1751  if (seg_size == lw_segment_side(B1, B3, &proj))
1752  {
1753  dl->p1 = proj;
1754  dl->p2 = *A3;
1755  dl->distance = fabs(radius_A - radius_B);
1756  return LW_TRUE;
1757  }
1758  }
1759 
1760  /* Check the shortest between the distances of the 4 ends */
1761  shortest_sqr = dist_sqr = distance2d_sqr_pt_pt(A1, B1);
1762  P1 = A1;
1763  P2 = B1;
1764 
1765  dist_sqr = distance2d_sqr_pt_pt(A1, B3);
1766  if (dist_sqr < shortest_sqr)
1767  {
1768  shortest_sqr = dist_sqr;
1769  P1 = A1;
1770  P2 = B3;
1771  }
1772 
1773  dist_sqr = distance2d_sqr_pt_pt(A3, B1);
1774  if (dist_sqr < shortest_sqr)
1775  {
1776  shortest_sqr = dist_sqr;
1777  P1 = A3;
1778  P2 = B1;
1779  }
1780 
1781  dist_sqr = distance2d_sqr_pt_pt(A3, B3);
1782  if (dist_sqr < shortest_sqr)
1783  {
1784  shortest_sqr = dist_sqr;
1785  P1 = A3;
1786  P2 = B3;
1787  }
1788 
1789  dl->p1 = *P1;
1790  dl->p2 = *P2;
1791  dl->distance = sqrt(shortest_sqr);
1792 
1793  return LW_TRUE;
1794 }
double distance2d_sqr_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:2311
POINT2D p1
Definition: measures.h:25
double x
Definition: liblwgeom.h:312
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:61
POINT2D p2
Definition: measures.h:26
double y
Definition: liblwgeom.h:312
double distance
Definition: measures.h:24
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition: lwalgorithm.c:50

Here is the call graph for this function:

Here is the caller graph for this function: