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

◆ clip_seg_by_m_range()

static int clip_seg_by_m_range ( POINT4D p1,
POINT4D p2,
double  m0,
double  m1 
)
static

Definition at line 303 of file lwgeom_functions_lrs.c.

304{
305 double dM0, dM1, dX, dY, dZ;
306 POINT4D *tmp;
307 int swapped=0;
308 int ret=0;
309
310 POSTGIS_DEBUGF(3, "m0: %g m1: %g", m0, m1);
311
312 /* Handle corner case of m values being the same */
313 if ( p1->m == p2->m )
314 {
315 /* out of range, no clipping */
316 if ( p1->m < m0 || p1->m > m1 )
317 return 0;
318
319 /* inside range, no clipping */
320 return 1;
321 }
322
323 /*
324 * Order points so that p1 has the smaller M
325 */
326 if ( p1->m > p2->m )
327 {
328 tmp=p2;
329 p2=p1;
330 p1=tmp;
331 swapped=1;
332 }
333
334 /*
335 * The M range is not intersected, segment
336 * fully out of range, no clipping.
337 */
338 if ( p2->m < m0 || p1->m > m1 )
339 return 0;
340
341 /*
342 * The segment is fully inside the range,
343 * no clipping.
344 */
345 if ( p1->m >= m0 && p2->m <= m1 )
346 return 1;
347
348 /*
349 * Segment intersects range, lets compute
350 * the proportional location of the two
351 * measures wrt p1/p2 m range.
352 *
353 * if p1 and p2 have the same measure
354 * this should never be reached (either
355 * both inside or both outside)
356 *
357 */
358 dM0=(m0-p1->m)/(p2->m-p1->m); /* delta-M0 */
359 dM1=(m1-p2->m)/(p2->m-p1->m); /* delta-M1 */
360 dX=p2->x-p1->x;
361 dY=p2->y-p1->y;
362 dZ=p2->z-p1->z;
363
364 POSTGIS_DEBUGF(3, "dM0:%g dM1:%g", dM0, dM1);
365 POSTGIS_DEBUGF(3, "dX:%g dY:%g dZ:%g", dX, dY, dZ);
366 POSTGIS_DEBUGF(3, "swapped: %d", swapped);
367
368 /*
369 * First point out of range, project
370 * it on the range
371 */
372 if ( p1->m < m0 )
373 {
374 /*
375 * To prevent rounding errors, then if m0==m1 and p2 lies within the range, copy
376 * p1 as a direct copy of p2
377 */
378 if (m0 == m1 && p2->m <= m1)
379 {
380 memcpy(p1, p2, sizeof(POINT4D));
381
382 POSTGIS_DEBUG(3, "Projected p1 on range (as copy of p2)");
383 }
384 else
385 {
386 /* Otherwise interpolate coordinates */
387 p1->x += (dX*dM0);
388 p1->y += (dY*dM0);
389 p1->z += (dZ*dM0);
390 p1->m = m0;
391
392 POSTGIS_DEBUG(3, "Projected p1 on range");
393 }
394
395 if ( swapped ) ret |= 0x0100;
396 else ret |= 0x0010;
397 }
398
399 /*
400 * Second point out of range, project
401 * it on the range
402 */
403 if ( p2->m > m1 )
404 {
405 /*
406 * To prevent rounding errors, then if m0==m1 and p1 lies within the range, copy
407 * p2 as a direct copy of p1
408 */
409 if (m0 == m1 && p1->m >= m0)
410 {
411 memcpy(p2, p1, sizeof(POINT4D));
412
413 POSTGIS_DEBUG(3, "Projected p2 on range (as copy of p1)");
414 }
415 else
416 {
417 /* Otherwise interpolate coordinates */
418 p2->x += (dX*dM1);
419 p2->y += (dY*dM1);
420 p2->z += (dZ*dM1);
421 p2->m = m1;
422
423 POSTGIS_DEBUG(3, "Projected p2 on range");
424 }
425
426 if ( swapped ) ret |= 0x0010;
427 else ret |= 0x0100;
428 }
429
430 /* Clipping occurred */
431 return ret;
432
433}
double m
Definition liblwgeom.h:400
double x
Definition liblwgeom.h:400
double z
Definition liblwgeom.h:400
double y
Definition liblwgeom.h:400

References POINT4D::m, POINT4D::x, POINT4D::y, and POINT4D::z.

Referenced by ptarray_locate_between_m().

Here is the caller graph for this function: