PostGIS  3.3.9dev-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 2227 of file measures.c.

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

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: