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

◆ 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: