PostGIS  2.2.8dev-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 290 of file lwgeom_functions_lrs.c.

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

Referenced by ptarray_locate_between_m().

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