PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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 1916 of file measures.c.

1917{
1918 double s_top, s_bot, s;
1919 double r_top, r_bot, r;
1920
1921 /*A and B are the same point */
1922 if ((A->x == B->x) && (A->y == B->y))
1923 {
1924 return lw_dist2d_pt_seg(A, C, D, dl);
1925 }
1926
1927 /*U and V are the same point */
1928 if ((C->x == D->x) && (C->y == D->y))
1929 {
1930 dl->twisted = ((dl->twisted) * (-1));
1931 return lw_dist2d_pt_seg(D, A, B, dl);
1932 }
1933
1934 /* AB and CD are line segments */
1935 /* from comp.graphics.algo
1936
1937 Solving the above for r and s yields
1938 (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
1939 r = ----------------------------- (eqn 1)
1940 (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
1941
1942 (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
1943 s = ----------------------------- (eqn 2)
1944 (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
1945 Let P be the position vector of the intersection point, then
1946 P=A+r(B-A) or
1947 Px=Ax+r(Bx-Ax)
1948 Py=Ay+r(By-Ay)
1949 By examining the values of r & s, you can also determine some other limiting conditions:
1950 If 0<=r<=1 & 0<=s<=1, intersection exists
1951 r<0 or r>1 or s<0 or s>1 line segments do not intersect
1952 If the denominator in eqn 1 is zero, AB & CD are parallel
1953 If the numerator in eqn 1 is also zero, AB & CD are collinear.
1954
1955 */
1956 r_top = (A->y - C->y) * (D->x - C->x) - (A->x - C->x) * (D->y - C->y);
1957 r_bot = (B->x - A->x) * (D->y - C->y) - (B->y - A->y) * (D->x - C->x);
1958
1959 s_top = (A->y - C->y) * (B->x - A->x) - (A->x - C->x) * (B->y - A->y);
1960 s_bot = (B->x - A->x) * (D->y - C->y) - (B->y - A->y) * (D->x - C->x);
1961
1962 if ((r_bot == 0) || (s_bot == 0))
1963 {
1964 if ((lw_dist2d_pt_seg(A, C, D, dl)) && (lw_dist2d_pt_seg(B, C, D, dl)))
1965 {
1966 /* change the order of inputted geometries and that we notice by changing sign on dl->twisted*/
1967 dl->twisted *= -1;
1968 return ((lw_dist2d_pt_seg(C, A, B, dl)) && (lw_dist2d_pt_seg(D, A, B, dl)));
1969 }
1970 else
1971 return LW_FALSE; /* if any of the calls to lw_dist2d_pt_seg goes wrong we return false*/
1972 }
1973
1974 s = s_top / s_bot;
1975 r = r_top / r_bot;
1976
1977 if (((r < 0) || (r > 1) || (s < 0) || (s > 1)) || (dl->mode == DIST_MAX))
1978 {
1979 if ((lw_dist2d_pt_seg(A, C, D, dl)) && (lw_dist2d_pt_seg(B, C, D, dl)))
1980 {
1981 /* change the order of inputted geometries and that we notice by changing sign on dl->twisted*/
1982 dl->twisted *= -1;
1983 return ((lw_dist2d_pt_seg(C, A, B, dl)) && (lw_dist2d_pt_seg(D, A, B, dl)));
1984 }
1985 else
1986 return LW_FALSE; /* if any of the calls to lw_dist2d_pt_seg goes wrong we return false*/
1987 }
1988 else
1989 {
1990 /* If there is intersection we identify the intersection point and return it but only if we are looking
1991 * for mindistance */
1992 if (dl->mode == DIST_MIN)
1993 {
1994 POINT2D theP;
1995
1996 if (((A->x == C->x) && (A->y == C->y)) || ((A->x == D->x) && (A->y == D->y)))
1997 {
1998 theP.x = A->x;
1999 theP.y = A->y;
2000 }
2001 else if (((B->x == C->x) && (B->y == C->y)) || ((B->x == D->x) && (B->y == D->y)))
2002 {
2003 theP.x = B->x;
2004 theP.y = B->y;
2005 }
2006 else
2007 {
2008 theP.x = A->x + r * (B->x - A->x);
2009 theP.y = A->y + r * (B->y - A->y);
2010 }
2011 dl->distance = 0.0;
2012 dl->p1 = theP;
2013 dl->p2 = theP;
2014 }
2015 return LW_TRUE;
2016 }
2017}
char * s
Definition cu_in_wkt.c:23
char * r
Definition cu_in_wkt.c:24
#define LW_FALSE
Definition liblwgeom.h:108
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
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:2305
#define DIST_MIN
Definition measures.h:44
#define DIST_MAX
Definition measures.h:43
POINT2D p1
Definition measures.h:52
POINT2D p2
Definition measures.h:53
int twisted
Definition measures.h:55
int mode
Definition measures.h:54
double distance
Definition measures.h:51
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376

References DIST_MAX, DIST_MIN, DISTPTS::distance, lw_dist2d_pt_seg(), LW_FALSE, LW_TRUE, 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(), 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: