PostGIS  3.1.6dev-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 2250 of file measures.c.

2251 {
2252  POINT2D c;
2253  double r;
2254  /*if start==end, then use pt distance */
2255  if ((A->x == B->x) && (A->y == B->y))
2256  return lw_dist2d_pt_pt(p, A, dl);
2257 
2258  /*
2259  * otherwise, we use comp.graphics.algorithms
2260  * Frequently Asked Questions method
2261  *
2262  * (1) AC dot AB
2263  * r = ---------
2264  * ||AB||^2
2265  * r has the following meaning:
2266  * r=0 P = A
2267  * r=1 P = B
2268  * r<0 P is on the backward extension of AB
2269  * r>1 P is on the forward extension of AB
2270  * 0<r<1 P is interior to AB
2271  */
2272 
2273  r = ((p->x - A->x) * (B->x - A->x) + (p->y - A->y) * (B->y - A->y)) /
2274  ((B->x - A->x) * (B->x - A->x) + (B->y - A->y) * (B->y - A->y));
2275 
2276  /*This is for finding the maxdistance.
2277  the maxdistance have to be between two vertexes, compared to mindistance which can be between two vertexes.*/
2278  if (dl->mode == DIST_MAX)
2279  {
2280  if (r >= 0.5)
2281  return lw_dist2d_pt_pt(p, A, dl);
2282  else /* (r < 0.5) */
2283  return lw_dist2d_pt_pt(p, B, dl);
2284  }
2285 
2286  if (r < 0) /*If p projected on the line is outside point A*/
2287  return lw_dist2d_pt_pt(p, A, dl);
2288  if (r >= 1) /*If p projected on the line is outside point B or on point B*/
2289  return lw_dist2d_pt_pt(p, B, dl);
2290 
2291  /*If the point p is on the segment this is a more robust way to find out that*/
2292  if ((((A->y - p->y) * (B->x - A->x) == (A->x - p->x) * (B->y - A->y))) && (dl->mode == DIST_MIN))
2293  {
2294  lw_dist2d_distpts_set(dl, 0, p, p);
2295  }
2296 
2297  /*If the projection of point p on the segment is between A and B
2298  then we find that "point on segment" and send it to lw_dist2d_pt_pt*/
2299  c.x = A->x + r * (B->x - A->x);
2300  c.y = A->y + r * (B->y - A->y);
2301 
2302  return lw_dist2d_pt_pt(p, &c, dl);
2303 }
char * r
Definition: cu_in_wkt.c:24
static void lw_dist2d_distpts_set(DISTPTS *dl, double distance, const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:78
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:2308
#define DIST_MIN
Definition: measures.h:44
#define DIST_MAX
Definition: measures.h:43
int mode
Definition: measures.h:54
double y
Definition: liblwgeom.h:404
double x
Definition: liblwgeom.h:404

References DIST_MAX, DIST_MIN, lw_dist2d_distpts_set(), lw_dist2d_pt_pt(), DISTPTS::mode, r, 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: