PostGIS  2.1.10dev-r@@SVN_REVISION@@
static int clip_seg_by_m_range ( POINT4D p1,
POINT4D p2,
double  m0,
double  m1 
)
static

Definition at line 295 of file lwgeom_functions_lrs.c.

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

Referenced by ptarray_locate_between_m().

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

Here is the caller graph for this function: