25template<
typename T1,
typename T2>
26T1
_ccw(
const Eigen::Vector2<T1>& a,
27 const Eigen::Vector2<T1>& b,
28 const Eigen::MatrixBase<T2>& c) {
29 return (b.x() - a.x()) * (c.y() - a.y()) - (b.y() - a.y()) * (c.x() - a.x());
38 const Eigen::Vector2<T>& b) {
39 return (a.x() < b.x() || (a.x() == b.x() && a.y() < b.y()));
45 const Eigen::Vector2<T>& pivot;
47 _ccwSorter(
const Eigen::Vector2<T>& inPivot) : pivot(inPivot) { }
49 bool operator()(
const Eigen::Vector2<T>& a,
const Eigen::Vector2<T>& b) {
50 return _ccw(pivot, a, b) < 0;
60 const Eigen::Vector2<T>& b) {
61 return sqrt((b.x() - a.x()) * (b.x() - a.x()) + (b.y() - a.y()) * (b.y() - a.y()));
69template<
typename T1,
typename T2>
71 const Eigen::Vector2<T1>& b,
72 const Eigen::MatrixBase<T2>& p) {
73 return fabs((b.x() - a.x()) * (a.y() - p.y()) - (b.y() - a.y()) * (a.x() - p.x())) /
_segmentLen(a, b);
83 const Eigen::Vector2<T>& b,
84 const std::vector<Eigen::Vector2<T> >& v) {
88 for (
size_t i = 1; i < v.size(); ++i) {
90 if (distCurr > distMax) {
99template<
typename T1,
typename T2>
101 const Eigen::Vector2<T1>& b,
102 const Eigen::MatrixX2<T2>& v) {
106 for (
size_t i = 1; i < v.rows(); ++i) {
108 if (distCurr > distMax) {
122[[deprecated(
"Use 'quickHull2D' instead")]]
123std::vector<Eigen::Vector2<T> >
giftWrapping(std::vector<Eigen::Vector2<T> > v) {
126 swap(v[0], *min_element(v.begin(), v.end(),
_isLeftOf<T>));
128 std::vector<Eigen::Vector2<T> > hull;
133 hull.push_back(v[0]);
134 swap(v[0], *min_element(v.begin() + 1, v.end(),
_ccwSorter(v[0])));
135 }
while (v[0] != hull[0]);
145[[deprecated(
"Use 'quickHull2D' instead")]]
146std::vector<Eigen::Vector2<T> >
GrahamScan(std::vector<Eigen::Vector2<T> > v) {
148 swap(v[0], *min_element(v.begin(), v.end(),
_isLeftOf<T>));
155 std::vector<Eigen::Vector2<T> > hull;
157 hull.push_back(*it++);
158 hull.push_back(*it++);
159 hull.push_back(*it++);
161 while (it != v.end()) {
163 while (
_ccw(*(hull.rbegin() + 1), *(hull.rbegin()), *it) >= 0) {
166 hull.push_back(*it++);
177[[deprecated(
"Use 'quickHull2D' instead")]]
178std::vector<Eigen::Vector2<T> >
monotoneChain(std::vector<Eigen::Vector2<T> > v) {
183 std::vector<Eigen::Vector2<T> > lower;
184 for (
auto it = v.begin(); it != v.end(); ++it) {
186 while (lower.size() >= 2 &&
_ccw(*(lower.rbegin() + 1), *(lower.rbegin()), *it) >= 0) {
189 lower.push_back(*it);
193 std::vector<Eigen::Vector2<T> > upper;
194 for (
auto it = v.rbegin(); it != v.rend(); ++it) {
196 while (upper.size() >= 2 &&
_ccw(*(upper.rbegin() + 1), *(upper.rbegin()), *it) >= 0) {
199 upper.push_back(*it);
202 std::vector<Eigen::Vector2<T> > hull;
203 hull.insert(hull.end(), lower.begin(), lower.end());
206 hull.insert(hull.end(), upper.begin() + 1, upper.end() - 1);
218 const std::vector<Eigen::Vector2<T> >& v,
219 const Eigen::Vector2<T>& a,
220 const Eigen::Vector2<T>& b,
221 std::vector<Eigen::Vector2<T> >& hull)
230 std::vector<Eigen::Vector2<T> > left;
232 if (
_ccw(a, f, p) > 0) {
242 std::vector<Eigen::Vector2<T> > right;
244 if (
_ccw(f, b, p) > 0) {
256 const std::vector<Eigen::Vector2<T> >& v)
259 Eigen::Vector2<T> a = *min_element(v.begin(), v.end(),
_isLeftOf<T>);
260 Eigen::Vector2<T> b = *max_element(v.begin(), v.end(),
_isLeftOf<T>);
263 std::vector<Eigen::Vector2<T> > left, right;
265 _ccw(a, b, p) > 0 ? left.push_back(p) : right.push_back(p);
268 std::vector<Eigen::Vector2<T> > hull;
282 hull.push_back(hull[0]);
295 const Eigen::MatrixX2<T>& v,
296 const Eigen::Vector2<T>& a,
297 const Eigen::Vector2<T>& b,
298 Eigen::MatrixX2<T>& hull,
308 Eigen::MatrixX2<T> left(v.rows(), 2);
310 for (ptrdiff_t i = 0; i < v.rows(); i++){
311 if (
_ccw(a, f, v.row(i)) > 0) {
312 left.row(il) = v.row(i);
316 left.conservativeResize(il, 2);
324 Eigen::MatrixX2<T> right(v.rows(), 2);
326 for (ptrdiff_t i = 0; i < v.rows(); i++){
327 if (
_ccw(f, b, v.row(i)) > 0) {
328 right.row(ir) = v.row(i);
332 right.conservativeResize(ir, 2);
341 const Eigen::MatrixX2<T>& v)
344 Eigen::VectorX<ptrdiff_t> idx =
345 Eigen::ArrayX<ptrdiff_t>::LinSpaced(
346 v.rows(), 0, v.rows()-1);
366 Eigen::Vector2<T> a = *std::min_element(
367 v.rowwise().begin(), v.rowwise().end(),
370 Eigen::Vector2<T> b = *std::max_element(
371 v.rowwise().begin(), v.rowwise().end(),
375 Eigen::MatrixX2<T> left(v.rows(), 2);
376 Eigen::MatrixX2<T> right(v.rows(), 2);
379 for (ptrdiff_t i = 0; i < v.rows(); i++){
380 if (
_ccw(a, b, v.row(i)) > 0){
381 left.row(il) = v.row(i);
384 right.row(ir) = v.row(i);
388 left.conservativeResize(il, 2);
389 right.conservativeResize(ir, 2);
392 Eigen::MatrixX2<T> hull(v.rows(), 2);
411 hull.row(ih) = hull.row(0);
414 hull.conservativeResize(ih, 2);
Basic namespace.
Definition h5base.h:29
T1 _ccw(const Eigen::Vector2< T1 > &a, const Eigen::Vector2< T1 > &b, const Eigen::MatrixBase< T2 > &c)
_ccw The z-value of the cross product of segments (a, b) and (a, c). Positive means c is _ccw from (a...
Definition h5easyhull.h:26
bool _isLeftOf(const Eigen::Vector2< T > &a, const Eigen::Vector2< T > &b)
_isLeftOf Returns true if a is lexicographically before b.
Definition h5easyhull.h:37
T1 _segmentDist(const Eigen::Vector2< T1 > &a, const Eigen::Vector2< T1 > &b, const Eigen::MatrixBase< T2 > &p)
_segmentDist The unsigned distance of p from segment (a, b).
Definition h5easyhull.h:70
size_t _getFarthestInd(const Eigen::Vector2< T > &a, const Eigen::Vector2< T > &b, const std::vector< Eigen::Vector2< T > > &v)
_getFarthestInd Returns the index of the farthest point from segment (a, b).
Definition h5easyhull.h:82
T _segmentLen(const Eigen::Vector2< T > &a, const Eigen::Vector2< T > &b)
_segmentLen The length of segment (a, b).
Definition h5easyhull.h:59
std::vector< Eigen::Vector2< T > > giftWrapping(std::vector< Eigen::Vector2< T > > v)
giftWrapping The gift-wrapping algorithm for convex hull. https://en.wikipedia.org/wiki/Gift_wrapping...
Definition h5easyhull.h:123
std::vector< Eigen::Vector2< T > > monotoneChain(std::vector< Eigen::Vector2< T > > v)
monotoneChain The monotone chain algorithm for convex hull.
Definition h5easyhull.h:178
Eigen::VectorX< ptrdiff_t > sort(const Eigen::DenseBase< D > &v)
sort return indexes such that v_sorted = v(ind).
Definition h5sort.h:32
std::vector< Eigen::Vector2< T > > GrahamScan(std::vector< Eigen::Vector2< T > > v)
GrahamScan The Graham scan algorithm for convex hull. https://en.wikipedia.org/wiki/Graham_scan.
Definition h5easyhull.h:146
void quickHull2D(const std::vector< Eigen::Vector2< T > > &v, const Eigen::Vector2< T > &a, const Eigen::Vector2< T > &b, std::vector< Eigen::Vector2< T > > &hull)
quickHull2D Recursive call of the quickHull2D algorithm.
Definition h5easyhull.h:217
The _ccwSorter struct Used to sort points in _ccw order about a pivot.
Definition h5easyhull.h:44