PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ lw_dist2d_seg_seg()

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.

This function is changed so it is not doing any comparison of distance but just sending every possible combination further to lw_dist2d_pt_seg

Definition at line 1840 of file measures.c.

1841 {
1842  double s_top, s_bot, s;
1843  double r_top, r_bot, r;
1844 
1845  /*A and B are the same point */
1846  if ((A->x == B->x) && (A->y == B->y))
1847  {
1848  return lw_dist2d_pt_seg(A, C, D, dl);
1849  }
1850 
1851  /*U and V are the same point */
1852  if ((C->x == D->x) && (C->y == D->y))
1853  {
1854  dl->twisted = ((dl->twisted) * (-1));
1855  return lw_dist2d_pt_seg(D, A, B, dl);
1856  }
1857 
1858  /* AB and CD are line segments */
1859  /* from comp.graphics.algo
1860 
1861  Solving the above for r and s yields
1862  (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
1863  r = ----------------------------- (eqn 1)
1864  (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
1865 
1866  (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
1867  s = ----------------------------- (eqn 2)
1868  (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
1869  Let P be the position vector of the intersection point, then
1870  P=A+r(B-A) or
1871  Px=Ax+r(Bx-Ax)
1872  Py=Ay+r(By-Ay)
1873  By examining the values of r & s, you can also determine some other limiting conditions:
1874  If 0<=r<=1 & 0<=s<=1, intersection exists
1875  r<0 or r>1 or s<0 or s>1 line segments do not intersect
1876  If the denominator in eqn 1 is zero, AB & CD are parallel
1877  If the numerator in eqn 1 is also zero, AB & CD are collinear.
1878 
1879  */
1880  r_top = (A->y - C->y) * (D->x - C->x) - (A->x - C->x) * (D->y - C->y);
1881  r_bot = (B->x - A->x) * (D->y - C->y) - (B->y - A->y) * (D->x - C->x);
1882 
1883  s_top = (A->y - C->y) * (B->x - A->x) - (A->x - C->x) * (B->y - A->y);
1884  s_bot = (B->x - A->x) * (D->y - C->y) - (B->y - A->y) * (D->x - C->x);
1885 
1886  if ((r_bot == 0) || (s_bot == 0))
1887  {
1888  if ((lw_dist2d_pt_seg(A, C, D, dl)) && (lw_dist2d_pt_seg(B, C, D, dl)))
1889  {
1890  /* change the order of inputted geometries and that we notice by changing sign on dl->twisted*/
1891  dl->twisted *= -1;
1892  return ((lw_dist2d_pt_seg(C, A, B, dl)) && (lw_dist2d_pt_seg(D, A, B, dl)));
1893  }
1894  else
1895  return LW_FALSE; /* if any of the calls to lw_dist2d_pt_seg goes wrong we return false*/
1896  }
1897 
1898  s = s_top / s_bot;
1899  r = r_top / r_bot;
1900 
1901  if (((r < 0) || (r > 1) || (s < 0) || (s > 1)) || (dl->mode == DIST_MAX))
1902  {
1903  if ((lw_dist2d_pt_seg(A, C, D, dl)) && (lw_dist2d_pt_seg(B, C, D, dl)))
1904  {
1905  /* change the order of inputted geometries and that we notice by changing sign on dl->twisted*/
1906  dl->twisted *= -1;
1907  return ((lw_dist2d_pt_seg(C, A, B, dl)) && (lw_dist2d_pt_seg(D, A, B, dl)));
1908  }
1909  else
1910  return LW_FALSE; /* if any of the calls to lw_dist2d_pt_seg goes wrong we return false*/
1911  }
1912  else
1913  {
1914  /* If there is intersection we identify the intersection point and return it but only if we are looking
1915  * for mindistance */
1916  if (dl->mode == DIST_MIN)
1917  {
1918  POINT2D theP;
1919 
1920  if (((A->x == C->x) && (A->y == C->y)) || ((A->x == D->x) && (A->y == D->y)))
1921  {
1922  theP.x = A->x;
1923  theP.y = A->y;
1924  }
1925  else if (((B->x == C->x) && (B->y == C->y)) || ((B->x == D->x) && (B->y == D->y)))
1926  {
1927  theP.x = B->x;
1928  theP.y = B->y;
1929  }
1930  else
1931  {
1932  theP.x = A->x + r * (B->x - A->x);
1933  theP.y = A->y + r * (B->y - A->y);
1934  }
1935  lw_dist2d_distpts_set(dl, 0, &theP, &theP);
1936  }
1937  return LW_TRUE;
1938  }
1939 }
char * s
Definition: cu_in_wkt.c:23
char * r
Definition: cu_in_wkt.c:24
#define LW_FALSE
Definition: liblwgeom.h:109
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:108
static void lw_dist2d_distpts_set(DISTPTS *dl, double distance, const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:81
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:2227
#define DIST_MIN
Definition: measures.h:44
#define DIST_MAX
Definition: measures.h:43
int twisted
Definition: measures.h:55
int mode
Definition: measures.h:54
double y
Definition: liblwgeom.h:405
double x
Definition: liblwgeom.h:405

References DIST_MAX, DIST_MIN, lw_dist2d_distpts_set(), lw_dist2d_pt_seg(), LW_FALSE, LW_TRUE, DISTPTS::mode, r, s, DISTPTS::twisted, POINT2D::x, and POINT2D::y.

Referenced by lw_dist2d_arc_arc(), lw_dist2d_ptarray_ptarray(), lw_dist2d_seg_arc(), and rect_leaf_node_distance().

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