PostGIS  3.6.1dev-r@@SVN_REVISION@@

◆ lw_dist2d_pt_seg()

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 it was handling occasions where r was between 0 and 1 internally and just returning the distance without identifying the points.

To get this points it was necessary to change and it also showed to be about 10faster.

Definition at line 2217 of file measures.c.

2218 {
2219  double r;
2220 
2221  LWDEBUG(2, "lw_dist2d_pt_seg called");
2222 
2223  /*if start==end, then use pt distance */
2224  if ((A->x == B->x) && (A->y == B->y))
2225  {
2226  LWDEBUG(2, "lw_dist2d_pt_seg found first and last segment points being the same");
2227  return lw_dist2d_pt_pt(p, A, dl);
2228  }
2229 
2230 
2231  /*
2232  * otherwise, we use comp.graphics.algorithms
2233  * Frequently Asked Questions method
2234  *
2235  * (1) AC dot AB
2236  * r = ---------
2237  * ||AB||^2
2238  * r has the following meaning:
2239  * r=0 P = A
2240  * r=1 P = B
2241  * r<0 P is on the backward extension of AB
2242  * r>1 P is on the forward extension of AB
2243  * 0<r<1 P is interior to AB
2244  */
2245 
2246  r = ((p->x - A->x) * (B->x - A->x) + (p->y - A->y) * (B->y - A->y)) /
2247  ((B->x - A->x) * (B->x - A->x) + (B->y - A->y) * (B->y - A->y));
2248 
2249  LWDEBUGF(2, "lw_dist2d_pt_seg found r = %.15g", r);
2250 
2251  /*This is for finding the maxdistance.
2252  the maxdistance have to be between two vertices, compared to mindistance which can be between two vertices.*/
2253  if (dl->mode == DIST_MAX)
2254  {
2255  if (r >= 0.5)
2256  return lw_dist2d_pt_pt(p, A, dl);
2257  else /* (r < 0.5) */
2258  return lw_dist2d_pt_pt(p, B, dl);
2259  }
2260 
2261  if (r < 0) /*If p projected on the line is outside point A*/
2262  return lw_dist2d_pt_pt(p, A, dl);
2263  if (r >= 1) /*If p projected on the line is outside point B or on point B*/
2264  return lw_dist2d_pt_pt(p, B, dl);
2265 
2266  /*If the point p is on the segment this is a more robust way to find out that*/
2267  if ((((A->y - p->y) * (B->x - A->x) == (A->x - p->x) * (B->y - A->y))) && (dl->mode == DIST_MIN))
2268  {
2269  lw_dist2d_distpts_set(dl, 0, p, p);
2270  }
2271 
2272 
2273  /*
2274  (2)
2275  (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
2276  s = -----------------------------
2277  L^2
2278 
2279  Then the distance from C to P = |s|*L.
2280  */
2281 
2282  double s = ((A->y - p->y) * (B->x - A->x) - (A->x - p->x) * (B->y - A->y)) /
2283  ((B->x - A->x) * (B->x - A->x) + (B->y - A->y) * (B->y - A->y));
2284 
2285  double dist = fabs(s) * sqrt(((B->x - A->x) * (B->x - A->x) + (B->y - A->y) * (B->y - A->y)));
2286  if ( dist < dl->distance )
2287  {
2288  dl->distance = dist;
2289  {
2290  POINT2D c;
2291  c.x = A->x + r * (B->x - A->x);
2292  c.y = A->y + r * (B->y - A->y);
2293  if (dl->twisted > 0)
2294  {
2295  dl->p1 = *p;
2296  dl->p2 = c;
2297  }
2298  else
2299  {
2300  dl->p1 = c;
2301  dl->p2 = *p;
2302  }
2303  }
2304  }
2305 
2306  return LW_TRUE;
2307 }
char * s
Definition: cu_in_wkt.c:23
char * r
Definition: cu_in_wkt.c:24
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:101
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:106
static double distance(double x1, double y1, double x2, double y2)
Definition: lwtree.c:1032
static void lw_dist2d_distpts_set(DISTPTS *dl, double distance, const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:81
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...
Definition: measures.c:2312
#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:390
double x
Definition: liblwgeom.h:390

References DIST_MAX, DIST_MIN, distance(), DISTPTS::distance, lw_dist2d_distpts_set(), lw_dist2d_pt_pt(), LW_TRUE, LWDEBUG, LWDEBUGF, DISTPTS::mode, DISTPTS::p1, DISTPTS::p2, r, s, DISTPTS::twisted, POINT2D::x, and POINT2D::y.

Referenced by lw_dist2d_pt_arc(), lw_dist2d_pt_ptarray(), lw_dist2d_seg_arc(), lw_dist2d_seg_seg(), lw_dist2d_selected_seg_seg(), rect_leaf_node_distance(), and rect_leaf_node_intersects().

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