15 #include <boost/range/adaptor/reversed.hpp> 30 : fKinkAngle(kinkAngle)
31 , fMinEdgeDistance(minEdgeDistance)
32 , fPoints(pointListIn)
62 float deltaX = std::get<0>(p1) - std::get<0>(p0);
63 float deltaY = std::get<1>(p1) - std::get<1>(p0);
64 float dCheckX = std::get<0>(p2) - std::get<0>(p0);
65 float dCheckY = std::get<1>(p2) - std::get<1>(p0);
67 return ((deltaX * dCheckY) - (deltaY * dCheckX));
87 x += std::get<0>(point);
88 y += std::get<1>(point);
91 Point center(x / n, y / n, 0);
93 Point lastPoint = fConvexHull.front();
95 for (
const auto& point : fConvexHull) {
96 if (point != lastPoint) area += 0.5 *
crossProduct(center, lastPoint, point);
109 Point pMinMin = pointList.front();
113 std::find_if(pointList.begin(), pointList.end(), [pMinMin](
const auto& elem) {
114 return std::get<0>(elem) != std::get<0>(pMinMin);
117 Point pMinMax = *(--pMinMaxItr);
122 Point pMaxMax = pointList.back();
125 PointList::const_reverse_iterator pMaxMinItr =
126 std::find_if(pointList.rbegin(), pointList.rend(), [pMaxMax](
const auto& elem) {
127 return std::get<0>(elem) != std::get<0>(pMaxMax);
130 Point pMaxMin = *(--pMaxMinItr);
138 lowerHullList.push_back(pMinMin);
141 for (
auto curPoint : pointList) {
143 if (
isLeft(pMinMin, pMaxMin, curPoint))
continue;
150 while (lowerHullList.size() > 1) {
151 Point lastPoint = lowerHullList.back();
153 lowerHullList.pop_back();
155 Point nextToLastPoint = lowerHullList.back();
157 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)) {
175 if (
isLeft(pMaxMax, pMinMax, curPoint))
continue;
178 while (upperHullList.size() > 1) {
179 Point lastPoint = upperHullList.back();
181 upperHullList.pop_back();
183 Point nextToLastPoint = upperHullList.back();
185 if (
isLeft(nextToLastPoint, lastPoint, curPoint)) {
186 upperHullList.push_back(lastPoint);
191 upperHullList.push_back(curPoint);
195 std::copy(lowerHullList.begin(), lowerHullList.end(), std::back_inserter(
fConvexHull));
197 if (pMaxMin == pMaxMax) upperHullList.pop_front();
199 std::copy(upperHullList.begin(), upperHullList.end(), std::back_inserter(
fConvexHull));
201 if (pMinMin != pMinMax)
fConvexHull.push_back(pMinMin);
211 float maxSeparation(0.);
221 Point firstPoint = *firstPointItr++;
222 Point nextPoint = *nextPointItr;
223 Eigen::Vector2f firstEdge(std::get<0>(*firstPointItr) - std::get<0>(firstPoint),
224 std::get<1>(*firstPointItr) - std::get<1>(firstPoint));
227 firstEdge.normalize();
232 Point endPoint = *endPointItr;
233 Eigen::Vector2f nextEdge(std::get<0>(endPoint) - std::get<0>(nextPoint),
234 std::get<1>(endPoint) - std::get<1>(nextPoint));
237 nextEdge.normalize();
240 if (firstEdge.dot(nextEdge) < 0.) {
241 Eigen::Vector2f separation(std::get<0>(nextPoint) - std::get<0>(firstPoint),
242 std::get<1>(nextPoint) - std::get<1>(firstPoint));
243 float separationDistance = separation.norm();
245 if (separationDistance > maxSeparation) {
246 extremePoints.first = firstPoint;
247 extremePoints.second = nextPoint;
248 maxSeparation = separationDistance;
256 nextPointItr = endPointItr;
257 nextPoint = endPoint;
265 if (firstPointItr == nextPointItr) nextPointItr++;
296 Point lastPoint = *pointItr++;
301 Point curPoint = *pointItr++;
302 Eigen::Vector2f lastEdge(std::get<0>(curPoint) - std::get<0>(lastPoint),
303 std::get<1>(curPoint) - std::get<1>(lastPoint));
305 lastEdge.normalize();
308 Point& nextPoint = *pointItr++;
310 Eigen::Vector2f nextEdge(std::get<0>(nextPoint) - std::get<0>(curPoint),
311 std::get<1>(nextPoint) - std::get<1>(curPoint));
314 nextEdge.normalize();
317 fKinkPoints.emplace_back(curPoint, lastEdge, nextEdge);
322 curPoint = nextPoint;
330 float& closestDistance)
const 337 Point prevPoint = *curPointItr++;
338 Point curPoint = *curPointItr;
341 PointPair closestEdge(prevPoint, curPoint);
343 closestDistance = std::numeric_limits<float>::max();
347 if (curPoint != prevPoint) {
349 float xPrevToPoint = (std::get<0>(point) - std::get<0>(prevPoint));
350 float yPrevToPoint = (std::get<1>(point) - std::get<1>(prevPoint));
351 float xPrevToCur = (std::get<0>(curPoint) - std::get<0>(prevPoint));
352 float yPrevToCur = (std::get<1>(curPoint) - std::get<1>(prevPoint));
353 float edgeLength = std::sqrt(xPrevToCur * xPrevToCur + yPrevToCur * yPrevToCur);
356 float projection = ((xPrevToPoint * xPrevToCur) + (yPrevToPoint * yPrevToCur)) / edgeLength;
359 Point docaPoint(std::get<0>(prevPoint) + projection * xPrevToCur / edgeLength,
360 std::get<1>(prevPoint) + projection * yPrevToCur / edgeLength,
363 if (projection > edgeLength) docaPoint = curPoint;
364 if (projection < 0) docaPoint = prevPoint;
366 float xDocaDist = std::get<0>(point) - std::get<0>(docaPoint);
367 float yDocaDist = std::get<1>(point) - std::get<1>(docaPoint);
368 float docaDist = xDocaDist * xDocaDist + yDocaDist * yDocaDist;
370 if (docaDist < closestDistance) {
371 closestEdge =
PointPair(prevPoint, curPoint);
372 closestDistance = docaDist;
376 prevPoint = curPoint;
377 curPoint = *curPointItr++;
380 closestDistance = std::sqrt(closestDistance);
384 if (
isLeft(closestEdge.first, closestEdge.second, point)) closestDistance = -closestDistance;
391 float closestDistance;
395 return closestDistance;
std::tuple< float, float, const reco::ClusterHit3D * > Point
projected x,y position and 3D hit
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.
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