PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ ptarray_dp_findsplit_in_place()

static uint32_t ptarray_dp_findsplit_in_place ( const POINTARRAY pts,
uint32_t  it_first,
uint32_t  it_last,
double  max_distance_sqr 
)
static

Definition at line 1610 of file ptarray.c.

1611 {
1612  uint32_t split = it_first;
1613  if ((it_first - it_last) < 2)
1614  return it_first;
1615 
1616  const POINT2D *A = getPoint2d_cp(pts, it_first);
1617  const POINT2D *B = getPoint2d_cp(pts, it_last);
1618 
1619  if (distance2d_sqr_pt_pt(A, B) < DBL_EPSILON)
1620  {
1621  /* If p1 == p2, we can just calculate the distance from each point to A */
1622  for (uint32_t itk = it_first + 1; itk < it_last; itk++)
1623  {
1624  const POINT2D *pk = getPoint2d_cp(pts, itk);
1625  double distance_sqr = distance2d_sqr_pt_pt(pk, A);
1626  if (distance_sqr > max_distance_sqr)
1627  {
1628  split = itk;
1629  max_distance_sqr = distance_sqr;
1630  }
1631  }
1632  return split;
1633  }
1634 
1635  /* This is based on distance2d_sqr_pt_seg, but heavily inlined here to avoid recalculations */
1636  double ba_x = (B->x - A->x);
1637  double ba_y = (B->y - A->y);
1638  double ab_length_sqr = (ba_x * ba_x + ba_y * ba_y);
1639  /* To avoid the division by ab_length_sqr in the 3rd path, we normalize here
1640  * and multiply in the first two paths [(dot_ac_ab < 0) and (> ab_length_sqr)] */
1641  max_distance_sqr *= ab_length_sqr;
1642  for (uint32_t itk = it_first + 1; itk < it_last; itk++)
1643  {
1644  const POINT2D *C = getPoint2d_cp(pts, itk);
1645  double distance_sqr;
1646  double ca_x = (C->x - A->x);
1647  double ca_y = (C->y - A->y);
1648  double dot_ac_ab = (ca_x * ba_x + ca_y * ba_y);
1649 
1650  if (dot_ac_ab <= 0.0)
1651  {
1652  distance_sqr = distance2d_sqr_pt_pt(C, A) * ab_length_sqr;
1653  }
1654  else if (dot_ac_ab >= ab_length_sqr)
1655  {
1656  distance_sqr = distance2d_sqr_pt_pt(C, B) * ab_length_sqr;
1657  }
1658  else
1659  {
1660  double s_numerator = ca_x * ba_y - ca_y * ba_x;
1661  distance_sqr = s_numerator * s_numerator; /* Missing division by ab_length_sqr on purpose */
1662  }
1663 
1664  if (distance_sqr > max_distance_sqr)
1665  {
1666  split = itk;
1667  max_distance_sqr = distance_sqr;
1668  }
1669  }
1670  return split;
1671 }
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:97
static double distance2d_sqr_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition: lwinline.h:33
double y
Definition: liblwgeom.h:390
double x
Definition: liblwgeom.h:390

References distance2d_sqr_pt_pt(), getPoint2d_cp(), POINT2D::x, and POINT2D::y.

Referenced by ptarray_simplify_in_place().

Here is the call graph for this function:
Here is the caller graph for this function: