-
-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Added Jarvis Algorithm to compute convex hull #1027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
c6c5d81
Added Jarvis Algorithm to compute convex hull
rishabh-997 e59559a
Added jarvis algorithm
rishabh-997 686ceb3
Update geometry/jarvis_algorithm.cpp
rishabh-997 ff4792d
Update geometry/jarvis_algorithm.cpp
rishabh-997 bfed4c8
Update geometry/jarvis_algorithm.cpp
rishabh-997 d21f56e
Added Jarvi algo to find convex hull
rishabh-997 bf610fb
Added Jarvi algo to find convex hull
rishabh-997 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| /** | ||
| * @file | ||
| * @brief Implementation of [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm. | ||
| * | ||
| * @details | ||
| * Given a set of points in the plane. the convex hull of the set | ||
| * is the smallest convex polygon that contains all the points of it. | ||
| * | ||
| * ### Algorithm | ||
| * The idea of Jarvis’s Algorithm is simple, we start from the leftmost point | ||
| * (or point with minimum x coordinate value) and we | ||
| * keep wrapping points in counterclockwise direction. | ||
| * | ||
| * The idea is to use orientation() here. Next point is selected as the | ||
| * point that beats all other points at counterclockwise orientation, i.e., | ||
| * next point is q if for any other point r, | ||
| * we have “orientation(p, q, r) = counterclockwise”. | ||
| * | ||
| * For Example, | ||
| * If points = {{0, 3}, {2, 2}, {1, 1}, {2, 1}, | ||
| {3, 0}, {0, 0}, {3, 3}}; | ||
| * | ||
| * then the convex hull is | ||
| * (0, 3), (0, 0), (3, 0), (3, 3) | ||
| * | ||
| * @author [Rishabh Agarwal](https://github.com/rishabh-997) | ||
| */ | ||
|
|
||
| #include <vector> | ||
| #include <cassert> | ||
| #include <iostream> | ||
|
|
||
| /** | ||
| * @namespace geometry | ||
| * @brief Geometry algorithms | ||
| */ | ||
| namespace geometry { | ||
| /** | ||
| * @namespace jarvis | ||
| * @brief Functions for [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm | ||
| */ | ||
| namespace jarvis { | ||
| /** | ||
| * Structure defining the x and y co-ordinates of the given | ||
| * point in space | ||
| */ | ||
| struct Point { | ||
| int x, y; | ||
| }; | ||
|
|
||
| /** | ||
| * Class which can be called from main and is globally available | ||
| * throughout the code | ||
| */ | ||
| class Convexhull { | ||
| std::vector<Point> points; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should the variables
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isnt |
||
| int size; | ||
|
|
||
| public: | ||
| /** | ||
| * Constructor of given class | ||
| * | ||
| * @param pointList list of all points in the space | ||
| * @param n number of points in space | ||
| */ | ||
| explicit Convexhull(const std::vector<Point> &pointList) { | ||
| points = pointList; | ||
| size = points.size(); | ||
| } | ||
|
|
||
| /** | ||
| * Creates convex hull of a set of n points. | ||
| * There must be 3 points at least for the convex hull to exist | ||
rishabh-997 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * | ||
| * @returns an vector array containing points in space | ||
| * which enclose all given points thus forming a hull | ||
| */ | ||
| std::vector<Point> getConvexHull() const { | ||
| // Initialize Result | ||
| std::vector<Point> hull; | ||
|
|
||
| // Find the leftmost point | ||
| int leftmost_point = 0; | ||
| for (int i = 1; i < size; i++) { | ||
| if (points[i].x < points[leftmost_point].x) { | ||
| leftmost_point = i; | ||
| } | ||
| } | ||
| // Start from leftmost point, keep moving counterclockwise | ||
| // until reach the start point again. This loop runs O(h) | ||
| // times where h is number of points in result or output. | ||
| int p = leftmost_point, q = 0; | ||
| do { | ||
| // Add current point to result | ||
| hull.push_back(points[p]); | ||
|
|
||
| // Search for a point 'q' such that orientation(p, x, q) | ||
| // is counterclockwise for all points 'x'. The idea | ||
| // is to keep track of last visited most counter clock- | ||
| // wise point in q. If any point 'i' is more counter clock- | ||
| // wise than q, then update q. | ||
| q = (p + 1) % size; | ||
| for (int i = 0; i < size; i++) { | ||
| // If i is more counterclockwise than current q, then | ||
| // update q | ||
| if (orientation(points[p], points[i], points[q]) == 2) { | ||
| q = i; | ||
| } | ||
| } | ||
|
|
||
| // Now q is the most counterclockwise with respect to p | ||
| // Set p as q for next iteration, so that q is added to | ||
| // result 'hull' | ||
| p = q; | ||
|
|
||
| } while (p != leftmost_point); // While we don't come to first point | ||
|
|
||
| return hull; | ||
| } | ||
|
|
||
| /** | ||
| * This function returns the geometric orientation for the three points | ||
| * in a space, ie, whether they are linear ir clockwise or | ||
| * anti-clockwise | ||
| * @param p first point selected | ||
| * @param q adjacent point for q | ||
| * @param r adjacent point for q | ||
| * | ||
| * @returns 0 -> Linear | ||
| * @returns 1 -> Clock Wise | ||
| * @returns 2 -> Anti Clock Wise | ||
| */ | ||
| static int orientation(const Point &p, const Point &q, const Point &r) { | ||
| int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); | ||
|
|
||
| if (val == 0) { | ||
| return 0; | ||
| } | ||
| return (val > 0) ? 1 : 2; | ||
| } | ||
|
|
||
| }; | ||
|
|
||
| } // namespace jarvis | ||
| } // namespace geometry | ||
|
|
||
| /** | ||
| * Test function | ||
rishabh-997 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * @returns void | ||
| */ | ||
| static void test() { | ||
| std::vector<geometry::jarvis::Point> points = {{0, 3}, | ||
| {2, 2}, | ||
| {1, 1}, | ||
| {2, 1}, | ||
| {3, 0}, | ||
| {0, 0}, | ||
| {3, 3} | ||
| }; | ||
| geometry::jarvis::Convexhull hull(points); | ||
| std::vector<geometry::jarvis::Point> actualPoint; | ||
| actualPoint = hull.getConvexHull(); | ||
|
|
||
| std::vector<geometry::jarvis::Point> expectedPoint = {{0, 3}, | ||
| {0, 0}, | ||
| {3, 0}, | ||
| {3, 3}}; | ||
| for (int i = 0; i < expectedPoint.size(); i++) { | ||
| assert(actualPoint[i].x == expectedPoint[i].x); | ||
| assert(actualPoint[i].y == expectedPoint[i].y); | ||
| } | ||
rishabh-997 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| std::cout << "Test implementations passed!\n"; | ||
| } | ||
|
|
||
| /** Driver Code */ | ||
| int main() { | ||
| test(); | ||
| return 0; | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.