PostGIS  2.4.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 comparasion of distance but just sending every possible combination further to lw_dist2d_pt_seg

Definition at line 1817 of file measures.c.

References DIST_MAX, DIST_MIN, DISTPTS::distance, lw_dist2d_pt_seg(), LW_FALSE, LW_TRUE, LWDEBUGF, lwerror(), DISTPTS::mode, DISTPTS::p1, DISTPTS::p2, r, s, DISTPTS::twisted, POINT2D::x, and POINT2D::y.

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

1818 {
1819  double s_top, s_bot,s;
1820  double r_top, r_bot,r;
1821 
1822  LWDEBUGF(2, "lw_dist2d_seg_seg [%g,%g]->[%g,%g] by [%g,%g]->[%g,%g]",
1823  A->x,A->y,B->x,B->y, C->x,C->y, D->x, D->y);
1824 
1825  /*A and B are the same point */
1826  if ( ( A->x == B->x) && (A->y == B->y) )
1827  {
1828  return lw_dist2d_pt_seg(A,C,D,dl);
1829  }
1830  /*U and V are the same point */
1831 
1832  if ( ( C->x == D->x) && (C->y == D->y) )
1833  {
1834  dl->twisted= ((dl->twisted) * (-1));
1835  return lw_dist2d_pt_seg(D,A,B,dl);
1836  }
1837  /* AB and CD are line segments */
1838  /* from comp.graphics.algo
1839 
1840  Solving the above for r and s yields
1841  (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
1842  r = ----------------------------- (eqn 1)
1843  (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
1844 
1845  (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
1846  s = ----------------------------- (eqn 2)
1847  (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
1848  Let P be the position vector of the intersection point, then
1849  P=A+r(B-A) or
1850  Px=Ax+r(Bx-Ax)
1851  Py=Ay+r(By-Ay)
1852  By examining the values of r & s, you can also determine some other limiting conditions:
1853  If 0<=r<=1 & 0<=s<=1, intersection exists
1854  r<0 or r>1 or s<0 or s>1 line segments do not intersect
1855  If the denominator in eqn 1 is zero, AB & CD are parallel
1856  If the numerator in eqn 1 is also zero, AB & CD are collinear.
1857 
1858  */
1859  r_top = (A->y-C->y)*(D->x-C->x) - (A->x-C->x)*(D->y-C->y);
1860  r_bot = (B->x-A->x)*(D->y-C->y) - (B->y-A->y)*(D->x-C->x);
1861 
1862  s_top = (A->y-C->y)*(B->x-A->x) - (A->x-C->x)*(B->y-A->y);
1863  s_bot = (B->x-A->x)*(D->y-C->y) - (B->y-A->y)*(D->x-C->x);
1864 
1865  if ( (r_bot==0) || (s_bot == 0) )
1866  {
1867  if ((lw_dist2d_pt_seg(A,C,D,dl)) && (lw_dist2d_pt_seg(B,C,D,dl)))
1868  {
1869  dl->twisted= ((dl->twisted) * (-1)); /*here we change the order of inputted geometrys and that we notice by changing sign on dl->twisted*/
1870  return ((lw_dist2d_pt_seg(C,A,B,dl)) && (lw_dist2d_pt_seg(D,A,B,dl))); /*if all is successful we return true*/
1871  }
1872  else
1873  {
1874  return LW_FALSE; /* if any of the calls to lw_dist2d_pt_seg goes wrong we return false*/
1875  }
1876  }
1877 
1878  s = s_top/s_bot;
1879  r= r_top/r_bot;
1880 
1881  if (((r<0) || (r>1) || (s<0) || (s>1)) || (dl->mode == DIST_MAX))
1882  {
1883  if ((lw_dist2d_pt_seg(A,C,D,dl)) && (lw_dist2d_pt_seg(B,C,D,dl)))
1884  {
1885  dl->twisted= ((dl->twisted) * (-1)); /*here we change the order of inputted geometrys and that we notice by changing sign on dl->twisted*/
1886  return ((lw_dist2d_pt_seg(C,A,B,dl)) && (lw_dist2d_pt_seg(D,A,B,dl))); /*if all is successful we return true*/
1887  }
1888  else
1889  {
1890  return LW_FALSE; /* if any of the calls to lw_dist2d_pt_seg goes wrong we return false*/
1891  }
1892  }
1893  else
1894  {
1895  if (dl->mode == DIST_MIN) /*If there is intersection we identify the intersection point and return it but only if we are looking for mindistance*/
1896  {
1897  POINT2D theP;
1898 
1899  if (((A->x==C->x)&&(A->y==C->y))||((A->x==D->x)&&(A->y==D->y)))
1900  {
1901  theP.x = A->x;
1902  theP.y = A->y;
1903  }
1904  else if (((B->x==C->x)&&(B->y==C->y))||((B->x==D->x)&&(B->y==D->y)))
1905  {
1906  theP.x = B->x;
1907  theP.y = B->y;
1908  }
1909  else
1910  {
1911  theP.x = A->x+r*(B->x-A->x);
1912  theP.y = A->y+r*(B->y-A->y);
1913  }
1914  dl->distance=0.0;
1915  dl->p1=theP;
1916  dl->p2=theP;
1917  }
1918  return LW_TRUE;
1919 
1920  }
1921  lwerror("unspecified error in function lw_dist2d_seg_seg");
1922  return LW_FALSE; /*If we have come here something is wrong*/
1923 }
char * r
Definition: cu_in_wkt.c:24
int mode
Definition: measures.h:54
POINT2D p1
Definition: measures.h:52
double x
Definition: liblwgeom.h:328
#define DIST_MIN
Definition: measures.h:44
#define LW_FALSE
Definition: liblwgeom.h:77
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
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 occation to lw_dist2d_pt_pt Before i...
Definition: measures.c:2205
POINT2D p2
Definition: measures.h:53
double y
Definition: liblwgeom.h:328
char * s
Definition: cu_in_wkt.c:23
int twisted
Definition: measures.h:55
double distance
Definition: measures.h:51
#define DIST_MAX
Definition: measures.h:43
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
Here is the call graph for this function:
Here is the caller graph for this function: