PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ 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:355
double x
Definition: liblwgeom.h:355
double z
Definition: liblwgeom.h:355
double y
Definition: liblwgeom.h:355

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

Referenced by ptarray_locate_between_m().

Here is the caller graph for this function: