PostGIS  3.7.0dev-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 2316 of file measures.c.

2317 {
2318  double r;
2319 
2320  LWDEBUG(2, "lw_dist2d_pt_seg called");
2321 
2322  /*if start==end, then use pt distance */
2323  if ((A->x == B->x) && (A->y == B->y))
2324  {
2325  LWDEBUG(2, "lw_dist2d_pt_seg found first and last segment points being the same");
2326  return lw_dist2d_pt_pt(p, A, dl);
2327  }
2328 
2329 
2330  /*
2331  * otherwise, we use comp.graphics.algorithms
2332  * Frequently Asked Questions method
2333  *
2334  * (1) AC dot AB
2335  * r = ---------
2336  * ||AB||^2
2337  * r has the following meaning:
2338  * r=0 P = A
2339  * r=1 P = B
2340  * r<0 P is on the backward extension of AB
2341  * r>1 P is on the forward extension of AB
2342  * 0<r<1 P is interior to AB
2343  */
2344 
2345  r = ((p->x - A->x) * (B->x - A->x) + (p->y - A->y) * (B->y - A->y)) /
2346  ((B->x - A->x) * (B->x - A->x) + (B->y - A->y) * (B->y - A->y));
2347 
2348  LWDEBUGF(2, "lw_dist2d_pt_seg found r = %.15g", r);
2349 
2350  /*This is for finding the maxdistance.
2351  the maxdistance have to be between two vertices, compared to mindistance which can be between two vertices.*/
2352  if (dl->mode == DIST_MAX)
2353  {
2354  if (r >= 0.5)
2355  return lw_dist2d_pt_pt(p, A, dl);
2356  else /* (r < 0.5) */
2357  return lw_dist2d_pt_pt(p, B, dl);
2358  }
2359 
2360  if (r < 0) /*If p projected on the line is outside point A*/
2361  return lw_dist2d_pt_pt(p, A, dl);
2362  if (r >= 1) /*If p projected on the line is outside point B or on point B*/
2363  return lw_dist2d_pt_pt(p, B, dl);
2364 
2365  /*If the point p is on the segment this is a more robust way to find out that*/
2366  if ((((A->y - p->y) * (B->x - A->x) == (A->x - p->x) * (B->y - A->y))) && (dl->mode == DIST_MIN))
2367  {
2368  dl->distance = 0.0;
2369  dl->p1 = *p;
2370  dl->p2 = *p;
2371  }
2372 
2373 
2374  /*
2375  (2)
2376  (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
2377  s = -----------------------------
2378  L^2
2379 
2380  Then the distance from C to P = |s|*L.
2381  */
2382 
2383  double s = ((A->y - p->y) * (B->x - A->x) - (A->x - p->x) * (B->y - A->y)) /
2384  ((B->x - A->x) * (B->x - A->x) + (B->y - A->y) * (B->y - A->y));
2385 
2386  double dist = fabs(s) * sqrt(((B->x - A->x) * (B->x - A->x) + (B->y - A->y) * (B->y - A->y)));
2387  if ( dist < dl->distance )
2388  {
2389  dl->distance = dist;
2390  {
2391  POINT2D c;
2392  c.x = A->x + r * (B->x - A->x);
2393  c.y = A->y + r * (B->y - A->y);
2394  if (dl->twisted > 0)
2395  {
2396  dl->p1 = *p;
2397  dl->p2 = c;
2398  }
2399  else
2400  {
2401  dl->p1 = c;
2402  dl->p2 = *p;
2403  }
2404  }
2405  }
2406 
2407  return LW_TRUE;
2408 }
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
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:2413
#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_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: