15 #include <boost/range/adaptor/reversed.hpp> 18 #include <Eigen/Dense> 32 fKinkAngle(kinkAngle), fMinEdgeDistance(minEdgeDistance), fPoints(pointListIn), fConvexHullArea(0.)
63 float deltaX = std::get<0>(p1) - std::get<0>(p0);
64 float deltaY = std::get<1>(p1) - std::get<1>(p0);
65 float dCheckX = std::get<0>(p2) - std::get<0>(p0);
66 float dCheckY = std::get<1>(p2) - std::get<1>(p0);
68 return ((deltaX * dCheckY) - (deltaY * dCheckX));
89 x += std::get<0>(point);
90 y += std::get<1>(point);
93 Point center(x/n,y/n,0);
95 Point lastPoint = fConvexHull.front();
97 for(
const auto& point : fConvexHull)
99 if (point != lastPoint) area += 0.5 *
crossProduct(center,lastPoint,point);
112 Point pMinMin = pointList.front();
115 PointList::const_iterator pMinMaxItr = std::find_if(pointList.begin(),pointList.end(),[pMinMin](
const auto& elem){
return std::get<0>(elem) != std::get<0>(pMinMin);});
117 Point pMinMax = *(--pMinMaxItr);
122 Point pMaxMax = pointList.back();
125 PointList::const_reverse_iterator pMaxMinItr = std::find_if(pointList.rbegin(),pointList.rend(),[pMaxMax](
const auto& elem){
return std::get<0>(elem) != std::get<0>(pMaxMax);});
127 Point pMaxMin = *(--pMaxMinItr);
135 lowerHullList.push_back(pMinMin);
138 for(
auto curPoint : pointList)
141 if (
isLeft(pMinMin,pMaxMin,curPoint))
continue;
148 while(lowerHullList.size() > 1)
150 Point lastPoint = lowerHullList.back();
152 lowerHullList.pop_back();
154 Point nextToLastPoint = lowerHullList.back();
156 if (
isLeft(nextToLastPoint,lastPoint,curPoint))
158 lowerHullList.push_back(lastPoint);
163 lowerHullList.push_back(curPoint);
169 upperHullList.push_back(pMaxMax);
171 for(
auto curPoint : boost::adaptors::reverse(pointList))
176 if (
isLeft(pMaxMax,pMinMax,curPoint))
continue;
179 while(upperHullList.size() > 1)
181 Point lastPoint = upperHullList.back();
183 upperHullList.pop_back();
185 Point nextToLastPoint = upperHullList.back();
187 if (
isLeft(nextToLastPoint,lastPoint,curPoint))
189 upperHullList.push_back(lastPoint);
194 upperHullList.push_back(curPoint);
198 std::copy(lowerHullList.begin(),lowerHullList.end(),std::back_inserter(
fConvexHull));
200 if (pMaxMin == pMaxMax) upperHullList.pop_front();
202 std::copy(upperHullList.begin(),upperHullList.end(),std::back_inserter(
fConvexHull));
204 if (pMinMin != pMinMax)
fConvexHull.push_back(pMinMin);
214 float maxSeparation(0.);
225 Point firstPoint = *firstPointItr++;
226 Point nextPoint = *nextPointItr;
227 Eigen::Vector2f firstEdge(std::get<0>(*firstPointItr) - std::get<0>(firstPoint), std::get<1>(*firstPointItr) - std::get<1>(firstPoint));
230 firstEdge.normalize();
236 Point endPoint = *endPointItr;
237 Eigen::Vector2f nextEdge(std::get<0>(endPoint) - std::get<0>(nextPoint), std::get<1>(endPoint) - std::get<1>(nextPoint));
240 nextEdge.normalize();
243 if (firstEdge.dot(nextEdge) < 0.)
245 Eigen::Vector2f separation(std::get<0>(nextPoint) - std::get<0>(firstPoint), std::get<1>(nextPoint) - std::get<1>(firstPoint));
246 float separationDistance = separation.norm();
248 if (separationDistance > maxSeparation)
250 extremePoints.first = firstPoint;
251 extremePoints.second = nextPoint;
252 maxSeparation = separationDistance;
260 nextPointItr = endPointItr;
261 nextPoint = endPoint;
269 if (firstPointItr == nextPointItr) nextPointItr++;
301 Point lastPoint = *pointItr++;
306 Point curPoint = *pointItr++;
307 Eigen::Vector2f lastEdge(std::get<0>(curPoint) - std::get<0>(lastPoint), std::get<1>(curPoint) - std::get<1>(lastPoint));
309 lastEdge.normalize();
313 Point& nextPoint = *pointItr++;
315 Eigen::Vector2f nextEdge(std::get<0>(nextPoint) - std::get<0>(curPoint), std::get<1>(nextPoint) - std::get<1>(curPoint));
319 nextEdge.normalize();
326 curPoint = nextPoint;
340 Point prevPoint = *curPointItr++;
341 Point curPoint = *curPointItr;
344 PointPair closestEdge(prevPoint,curPoint);
351 if (curPoint != prevPoint)
354 float xPrevToPoint = (std::get<0>(point) - std::get<0>(prevPoint));
355 float yPrevToPoint = (std::get<1>(point) - std::get<1>(prevPoint));
356 float xPrevToCur = (std::get<0>(curPoint) - std::get<0>(prevPoint));
357 float yPrevToCur = (std::get<1>(curPoint) - std::get<1>(prevPoint));
358 float edgeLength = std::sqrt(xPrevToCur * xPrevToCur + yPrevToCur * yPrevToCur);
361 float projection = ((xPrevToPoint * xPrevToCur) + (yPrevToPoint * yPrevToCur)) / edgeLength;
364 Point docaPoint(std::get<0>(prevPoint) + projection * xPrevToCur / edgeLength,
365 std::get<1>(prevPoint) + projection * yPrevToCur / edgeLength, 0);
367 if (projection > edgeLength) docaPoint = curPoint;
368 if (projection < 0) docaPoint = prevPoint;
370 float xDocaDist = std::get<0>(point) - std::get<0>(docaPoint);
371 float yDocaDist = std::get<1>(point) - std::get<1>(docaPoint);
372 float docaDist = xDocaDist * xDocaDist + yDocaDist * yDocaDist;
374 if (docaDist < closestDistance)
376 closestEdge =
PointPair(prevPoint,curPoint);
377 closestDistance = docaDist;
381 prevPoint = curPoint;
382 curPoint = *curPointItr++;
385 closestDistance = std::sqrt(closestDistance);
389 if (
isLeft(closestEdge.first,closestEdge.second,point)) closestDistance = -closestDistance;
396 float closestDistance;
400 return closestDistance;
MinMaxPointPair fMinMaxPointPair
std::list< Point > PointList
The list of the projected points.
float crossProduct(const Point &p0, const Point &p1, const Point &p2) const
Gets the cross product of line from p0 to p1 and p0 to p2.
std::pair< Point, Point > PointPair
Implements a ConvexHull for use in clustering.
float Area() const
Computes the area of the enclosed convext hull.
std::tuple< float, float, const reco::ClusterHit3D * > Point
projected x,y position and 3D hit
PointPair findNearestEdge(const Point &, float &) const
Given an input Point, find the nearest edge.
float findNearestDistance(const Point &) const
Given an input point, find the distance to the nearest edge/point.
const reco::ConvexHullKinkTupleList & getKinkPoints()
Find the points with the largest angles.
std::list< ConvexHullKinkTuple > ConvexHullKinkTupleList
const PointList & getConvexHull() const
recover the list of convex hull vertices
reco::ConvexHullKinkTupleList fKinkPoints
const PointList & getExtremePoints()
Find the two points on the hull which are furthest apart.
bool isLeft(const Point &p0, const Point &p1, const Point &pCheck) const
Determines whether a point is to the left, right or on line specifiec by p0 and p1.
ConvexHull(const PointList &, float=0.85, float=0.35)
Constructor.
const PointList & fPoints
virtual ~ConvexHull()
Destructor.