Skip to content

Commit d0924ca

Browse files
authored
Merge pull request #767 from fer22f/convex-hull
Fix collinear line case in Monotone Chain
2 parents 59c1217 + 487552c commit d0924ca

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

src/geometry/convex-hull.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,10 @@ with the line connecting the last point in the lower convex hull and the current
114114
the previous point once added to the hull.
115115

116116
The final convex hull is obtained from the union of the upper and lower convex hull, forming a clockwise hull, and the implementation is as follows.
117-
If you need collinear points, you just need to include them in the clockwise/counterclockwise routines, by changing `<` to `<=` and `>` to `>=`.
117+
If you need collinear points, you just need to check for them in the clockwise/counterclockwise routines.
118+
However, this allows for a degenerate case where all the input points are collinear in a single line, and the algorithm would output repeated points.
119+
To solve this, we check whether the upper hull contains all the points, and if it does, we just return the points in reverse, as that
120+
is what Graham's implementation would return in this case.
118121

119122
### Implementation
120123

@@ -163,6 +166,10 @@ void convex_hull(vector<pt>& a, bool include_collinear = false) {
163166
}
164167
}
165168

169+
if (include_collinear && up.size() == a.size()) {
170+
reverse(a.begin(), a.end());
171+
return;
172+
}
166173
a.clear();
167174
for (int i = 0; i < (int)up.size(); i++)
168175
a.push_back(up[i]);

test/data/convex_hull.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,21 @@ vector<ConvexHull> convex_hulls = {
4646
{{100,54},{54,100},{100,146},{146,100}}},
4747
{{{4,7},{4,6}, {4,5}, {4,4}, {4,3}, {4,1}, {4,0}, {4,9}, {4,8}, {5,10}, {2,0}, {2,3}, {2,2}, {2,5}, {2,4}, {2,7}, {2,6}, {2,9}, {2,8}, {0,3}, {0,2}, {0,1}, {0,0}, {0,7}, {0,5}, {0,4}, {0,9}, {10,10}, {5,1}, {9,2}, {9,0}, {9,1}, {9,6}, {9,7}, {9,4}, {0,10}, {9,8}, {9,9}, {10,9}, {10,8}, {10,7}, {10,5}, {10,3}, {10,2}, {10,1}, {7,9}, {7,4}, {7,5}, {7,6}, {7,7}, {7,0}, {7,1}, {7,2}, {7,3}, {2,10}, {6,10}, {5,8}, {5,9}, {5,6}, {5,4}, {5,2}, {5,3}, {5,0}, {8,10}, {3,9}, {3,1}, {3,2}, {3,3}, {3,4}, {3,5}, {3,6}, {3,7}, {1,9}, {1,2}, {1,3}, {1,0}, {1,1}, {1,6}, {1,7}, {1,4}, {1,10}, {4,10}, {9,10}, {9,5}, {7,10}, {8,9}, {8,3}, {8,7}, {8,6}, {8,5}, {8,4}, {6,5}, {6,4}, {6,0}, {6,3}, {6,2}, {6,9}, {6,8}, {3,10}},
4848
{{0,0},{0,10},{10,10},{10,1},{9,0}},
49-
{{0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,7},{0,9},{0,10},{1,10},{2,10},{3,10},{4,10},{5,10},{6,10},{7,10},{8,10},{9,10},{10,10},{10,9},{10,8},{10,7},{10,5},{10,3},{10,2},{10,1},{9,0},{7,0},{6,0},{5,0},{4,0},{2,0},{1,0}}}
49+
{{0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,7},{0,9},{0,10},{1,10},{2,10},{3,10},{4,10},{5,10},{6,10},{7,10},{8,10},{9,10},{10,10},{10,9},{10,8},{10,7},{10,5},{10,3},{10,2},{10,1},{9,0},{7,0},{6,0},{5,0},{4,0},{2,0},{1,0}}},
50+
// degenerate cases (single line)
51+
{{{0,0},{1,1},{2,2}},
52+
{{0,0},{2,2}},
53+
{{2,2},{1,1},{0,0}}},
54+
{{{0,0},{1,1},{2,2},{3,3}},
55+
{{0,0},{3,3}},
56+
{{3,3},{2,2},{1,1},{0,0}}},
57+
{{{0,0},{0,1},{0,2},{0,3}},
58+
{{0,0},{0,3}},
59+
{{0,3},{0,2},{0,1},{0,0}}},
60+
{{{0,0},{1,0},{2,0},{3,0}},
61+
{{0,0},{3,0}},
62+
{{3,0},{2,0},{1,0},{0,0}}},
63+
{{{0,0},{1,1},{2,2},{0,2}},
64+
{{0,0},{0,2},{2,2}},
65+
{{2,2},{1,1},{0,0},{0,2}}},
5066
};

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy