From c6c5d81f1be33d8a009c77702655b3df3fcc0413 Mon Sep 17 00:00:00 2001 From: rishabh-997 Date: Sat, 15 Aug 2020 01:39:18 +0530 Subject: [PATCH 1/7] Added Jarvis Algorithm to compute convex hull Fixed code formatting Fixed code formatting Fixed code formatting Added Jarvis algorithm to compute convex hull Capitalized class name Added requested changes Added requested changes Added jarvis algorithm Added jarvis algorithm to compute convex hull --- geometry/jarvis_algorithm.cpp | 178 ++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 geometry/jarvis_algorithm.cpp diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp new file mode 100644 index 000000000..84f7de4bc --- /dev/null +++ b/geometry/jarvis_algorithm.cpp @@ -0,0 +1,178 @@ +/** + * @file + * @brief Implementation of [Jarvis’s Algorithm](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 +#include +#include +#include + +/** + * @namespace geometry + * @brief Geometry algorithms + */ +namespace geometry { + /** + * Structure defining the x and y co-ordinates of the given + * point in space + */ + struct Point { + int x, y; + }; + + /** + * @namespace jarvis + * @brief Functions for [Jarvis’s Algorithm](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm + */ + namespace jarvis { + /** + * Class which can be called from main and is globally available + * throughout the code + */ + class Convexhull { + public: + std::vector points; + int size; + + /** + * Constructor of given class + * + * @param pointList list of all points in the space + * @param n number of points in space + */ + Convexhull(std::vector pointList, int n) { + points = std::move(pointList); + size = n; + } + + /** + * Creates convex hull of a set of n points. + * There must be 3 points at least for the convex hull to exist + * + * returns an vector array containing points in space + * which enclose all given points thus forming a hull + */ + std::vector getConvexHull() const { + // Initialize Result + std::vector 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; + } + + /** + * + * @param p first point selected + * @param q adjacent point for q + * @param r adjacent point for q + * @returns the geometric orientation for the three points + * 0 -> Linear + * 1 -> Clock Wise + * 2 -> Anti Clock Wise + */ + static int orientation(Point p, Point q, 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 + */ +static void test() { + std::vector points = {{0, 3}, + {2, 2}, + {1, 1}, + {2, 1}, + {3, 0}, + {0, 0}, + {3, 3} + }; + int n = points.size(); + geometry::jarvis::Convexhull hull(points, n); + std::vector actualPoint; + actualPoint = hull.getConvexHull(); + + std::vector 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); + } + std::cout << "Test implementations passed!\n"; +} + +/** Driver Code */ +int main() { + test(); + return 0; +} From e59559af0f97f0f2996a71a13b1872a8c874a9b8 Mon Sep 17 00:00:00 2001 From: rishabh-997 Date: Sat, 15 Aug 2020 13:05:28 +0530 Subject: [PATCH 2/7] Added jarvis algorithm --- geometry/jarvis_algorithm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index 84f7de4bc..9a1b4ea8d 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -73,7 +73,7 @@ namespace geometry { * Creates convex hull of a set of n points. * There must be 3 points at least for the convex hull to exist * - * returns an vector array containing points in space + * @returns an vector array containing points in space * which enclose all given points thus forming a hull */ std::vector getConvexHull() const { From 686ceb3cfad6192ddfa9d174113d68afcb818ab9 Mon Sep 17 00:00:00 2001 From: Rishabh Agarwal <45125121+rishabh-997@users.noreply.github.com> Date: Sun, 16 Aug 2020 22:12:37 +0530 Subject: [PATCH 3/7] Update geometry/jarvis_algorithm.cpp Co-authored-by: David Leal --- geometry/jarvis_algorithm.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index 9a1b4ea8d..c0e906886 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -145,6 +145,7 @@ namespace geometry { /** * Test function + * @returns void */ static void test() { std::vector points = {{0, 3}, From ff4792d369ce453ebcb97b1b68ad1c39a4b8301b Mon Sep 17 00:00:00 2001 From: Rishabh Agarwal <45125121+rishabh-997@users.noreply.github.com> Date: Sun, 16 Aug 2020 22:12:56 +0530 Subject: [PATCH 4/7] Update geometry/jarvis_algorithm.cpp Co-authored-by: David Leal --- geometry/jarvis_algorithm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index c0e906886..ff31207a3 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -46,7 +46,7 @@ namespace geometry { /** * @namespace jarvis - * @brief Functions for [Jarvis’s Algorithm](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm + * @brief Functions for [Jarvis’s](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm */ namespace jarvis { /** From bfed4c8fba4900a7545576858297476b5268ac81 Mon Sep 17 00:00:00 2001 From: Rishabh Agarwal <45125121+rishabh-997@users.noreply.github.com> Date: Sun, 16 Aug 2020 22:26:13 +0530 Subject: [PATCH 5/7] Update geometry/jarvis_algorithm.cpp Co-authored-by: David Leal --- geometry/jarvis_algorithm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index ff31207a3..85716e2fd 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -1,6 +1,6 @@ /** * @file - * @brief Implementation of [Jarvis’s Algorithm](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) algorithm. + * @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 From d21f56e8363c10e956bf015bd33e78a408861217 Mon Sep 17 00:00:00 2001 From: rishabh-997 Date: Mon, 17 Aug 2020 02:36:30 +0530 Subject: [PATCH 6/7] Added Jarvi algo to find convex hull --- geometry/jarvis_algorithm.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index 85716e2fd..d471a52a4 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -36,19 +36,19 @@ * @brief Geometry algorithms */ namespace geometry { - /** - * Structure defining the x and y co-ordinates of the given - * point in space - */ - struct Point { - int x, y; - }; - /** * @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 @@ -148,7 +148,7 @@ namespace geometry { * @returns void */ static void test() { - std::vector points = {{0, 3}, + std::vector points = {{0, 3}, {2, 2}, {1, 1}, {2, 1}, @@ -158,10 +158,10 @@ static void test() { }; int n = points.size(); geometry::jarvis::Convexhull hull(points, n); - std::vector actualPoint; + std::vector actualPoint; actualPoint = hull.getConvexHull(); - std::vector expectedPoint = {{0, 3}, + std::vector expectedPoint = {{0, 3}, {0, 0}, {3, 0}, {3, 3}}; From bf610fb91dad7f62aeee7c647ddf43dcbc0fe92e Mon Sep 17 00:00:00 2001 From: rishabh-997 Date: Mon, 17 Aug 2020 02:46:38 +0530 Subject: [PATCH 7/7] Added Jarvi algo to find convex hull --- geometry/jarvis_algorithm.cpp | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/geometry/jarvis_algorithm.cpp b/geometry/jarvis_algorithm.cpp index d471a52a4..ae5b1b5a6 100644 --- a/geometry/jarvis_algorithm.cpp +++ b/geometry/jarvis_algorithm.cpp @@ -26,7 +26,6 @@ * @author [Rishabh Agarwal](https://github.com/rishabh-997) */ -#include #include #include #include @@ -54,19 +53,19 @@ namespace geometry { * throughout the code */ class Convexhull { - public: std::vector points; int size; + public: /** * Constructor of given class * * @param pointList list of all points in the space * @param n number of points in space */ - Convexhull(std::vector pointList, int n) { - points = std::move(pointList); - size = n; + explicit Convexhull(const std::vector &pointList) { + points = pointList; + size = points.size(); } /** @@ -120,16 +119,18 @@ namespace geometry { } /** - * + * 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 the geometric orientation for the three points - * 0 -> Linear - * 1 -> Clock Wise - * 2 -> Anti Clock Wise + * + * @returns 0 -> Linear + * @returns 1 -> Clock Wise + * @returns 2 -> Anti Clock Wise */ - static int orientation(Point p, Point q, Point r) { + 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) { @@ -149,22 +150,21 @@ namespace geometry { */ static void test() { std::vector points = {{0, 3}, - {2, 2}, - {1, 1}, - {2, 1}, - {3, 0}, - {0, 0}, - {3, 3} + {2, 2}, + {1, 1}, + {2, 1}, + {3, 0}, + {0, 0}, + {3, 3} }; - int n = points.size(); - geometry::jarvis::Convexhull hull(points, n); + geometry::jarvis::Convexhull hull(points); std::vector actualPoint; actualPoint = hull.getConvexHull(); std::vector expectedPoint = {{0, 3}, - {0, 0}, - {3, 0}, - {3, 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);