15 #include <boost/range/adaptor/reversed.hpp>
27 namespace lar_cluster3d {
30 fKinkAngle(kinkAngle), fMinEdgeDistance(minEdgeDistance), fPoints(pointListIn), fConvexHullArea(0.)
61 float deltaX = std::get<0>(
p1) - std::get<0>(p0);
62 float deltaY = std::get<1>(
p1) - std::get<1>(p0);
63 float dCheckX = std::get<0>(p2) - std::get<0>(p0);
64 float dCheckY = std::get<1>(p2) - std::get<1>(p0);
66 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)
97 if (point != lastPoint) area += 0.5 *
crossProduct(center,lastPoint,point);
110 Point pMinMin = pointList.front();
113 PointList::const_iterator pMinMaxItr = std::find_if(pointList.begin(),pointList.end(),[pMinMin](
const auto& elem){
return std::get<0>(elem) != std::get<0>(pMinMin);});
115 Point pMinMax = *(--pMinMaxItr);
120 Point pMaxMax = pointList.back();
123 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);});
125 Point pMaxMin = *(--pMaxMinItr);
133 lowerHullList.push_back(pMinMin);
136 for(
auto curPoint : pointList)
139 if (
isLeft(pMinMin,pMaxMin,curPoint))
continue;
146 while(lowerHullList.size() > 1)
148 Point lastPoint = lowerHullList.back();
150 lowerHullList.pop_back();
152 Point nextToLastPoint = lowerHullList.back();
154 if (
isLeft(nextToLastPoint,lastPoint,curPoint))
156 lowerHullList.push_back(lastPoint);
161 lowerHullList.push_back(curPoint);
167 upperHullList.push_back(pMaxMax);
169 for(
auto curPoint : boost::adaptors::reverse(pointList))
174 if (
isLeft(pMaxMax,pMinMax,curPoint))
continue;
177 while(upperHullList.size() > 1)
179 Point lastPoint = upperHullList.back();
181 upperHullList.pop_back();
183 Point nextToLastPoint = upperHullList.back();
185 if (
isLeft(nextToLastPoint,lastPoint,curPoint))
187 upperHullList.push_back(lastPoint);
192 upperHullList.push_back(curPoint);
198 if (pMaxMin == pMaxMax) upperHullList.pop_front();
202 if (pMinMin != pMinMax)
fConvexHull.push_back(pMinMin);
209 PointList::const_iterator nextPointItr =
fConvexHull.begin();
210 PointList::const_iterator firstPointItr = nextPointItr++;
212 float maxSeparation(0.);
223 Point firstPoint = *firstPointItr++;
224 Point nextPoint = *nextPointItr;
225 Eigen::Vector2f firstEdge(std::get<0>(*firstPointItr) - std::get<0>(firstPoint), std::get<1>(*firstPointItr) - std::get<1>(firstPoint));
228 firstEdge.normalize();
230 PointList::const_iterator endPointItr = nextPointItr;
234 Point endPoint = *endPointItr;
235 Eigen::Vector2f nextEdge(std::get<0>(endPoint) - std::get<0>(nextPoint), std::get<1>(endPoint) - std::get<1>(nextPoint));
238 nextEdge.normalize();
241 if (firstEdge.dot(nextEdge) < 0.)
243 Eigen::Vector2f separation(std::get<0>(nextPoint) - std::get<0>(firstPoint), std::get<1>(nextPoint) - std::get<1>(firstPoint));
244 float separationDistance = separation.norm();
246 if (separationDistance > maxSeparation)
248 extremePoints.first = firstPoint;
249 extremePoints.second = nextPoint;
250 maxSeparation = separationDistance;
258 nextPointItr = endPointItr;
259 nextPoint = endPoint;
267 if (firstPointItr == nextPointItr) nextPointItr++;
294 PointList::iterator pointItr =
fConvexHull.begin();
299 Point lastPoint = *pointItr++;
304 Point curPoint = *pointItr++;
305 Eigen::Vector2f lastEdge(std::get<0>(curPoint) - std::get<0>(lastPoint), std::get<1>(curPoint) - std::get<1>(lastPoint));
307 lastEdge.normalize();
311 Point& nextPoint = *pointItr++;
313 Eigen::Vector2f nextEdge(std::get<0>(nextPoint) - std::get<0>(curPoint), std::get<1>(nextPoint) - std::get<1>(curPoint));
317 nextEdge.normalize();
324 curPoint = nextPoint;
337 PointList::const_iterator curPointItr =
fConvexHull.begin();
338 Point prevPoint = *curPointItr++;
339 Point curPoint = *curPointItr;
342 PointPair closestEdge(prevPoint,curPoint);
344 closestDistance = std::numeric_limits<float>::max();
349 if (curPoint != prevPoint)
352 float xPrevToPoint = (std::get<0>(point) - std::get<0>(prevPoint));
353 float yPrevToPoint = (std::get<1>(point) - std::get<1>(prevPoint));
354 float xPrevToCur = (std::get<0>(curPoint) - std::get<0>(prevPoint));
355 float yPrevToCur = (std::get<1>(curPoint) - std::get<1>(prevPoint));
356 float edgeLength = std::sqrt(xPrevToCur * xPrevToCur + yPrevToCur * yPrevToCur);
359 float projection = ((xPrevToPoint * xPrevToCur) + (yPrevToPoint * yPrevToCur)) / edgeLength;
362 Point docaPoint(std::get<0>(prevPoint) + projection * xPrevToCur / edgeLength,
363 std::get<1>(prevPoint) + projection * yPrevToCur / edgeLength, 0);
365 if (projection > edgeLength) docaPoint = curPoint;
366 if (projection < 0) docaPoint = prevPoint;
368 float xDocaDist = std::get<0>(point) - std::get<0>(docaPoint);
369 float yDocaDist = std::get<1>(point) - std::get<1>(docaPoint);
370 float docaDist = xDocaDist * xDocaDist + yDocaDist * yDocaDist;
372 if (docaDist < closestDistance)
374 closestEdge =
PointPair(prevPoint,curPoint);
375 closestDistance = docaDist;
379 prevPoint = curPoint;
380 curPoint = *curPointItr++;
383 closestDistance = std::sqrt(closestDistance);
process_name opflash particleana ie x
MinMaxPointPair fMinMaxPointPair
double closestDistance(const TVector3 &line0, const TVector3 &line1, const TVector3 &p)
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.
process_name opflash particleana ie ie y
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
physics associatedGroupsWithLeft p1