In this guide, we will explore the Angular Sweep Algorithm in C++ along with its practical application.
It implies the necessity to ascertain the maximum number of points encompassed within a circle of radius r (located inside the circle, not on its perimeter) based on a collection of 2-D points. The Angular Sweep Algorithm stands out as the optimal method for this task. Within the realm of computational geometry, the Angular Sweep Algorithm serves various functions, such as identifying the convex hull of a point set.
The Angular Sweep Algorithm is utilized to determine the convex hull of a set of points in the instances below:
Example 1:
{{0, 3}, {1, 1}, {2, 2}, {4, 4}, {0, 0}, {1, 2}, {3, 1}, {3, 3}} can be seen as a collection of pairs of numbers inside curly braces.
Output: {(0, 0), (0, 3), (4, 4), (3, 1), (3, 3)}
Example 2:
Input: {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}}
Output: {(0, 0), (4, 4), (3, 3)}
It calculates the maximum number of points that a circle with a constant radius "R" can enclose among a set of "n" points in a 2D space.
Note: Even if a point is on the circumference, it is still regarded as being inside the circle.
As an example:
Input: R = 1
points = {(8.65844, 5.67258), (4.25496, 6.94715), (7.68547, 7.58552)}
Output: 2
The maximum number of points is 2,
Program:
Let's consider a scenario to demonstrate the Angular Sweep Algorithm in C++.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
struct Point {
int a, b;
};
Point z1; // Global variable for the reference point of the convex hull
Point nextToTop(std::vector<Point>& S1) {
Point p = S1.back();
S1.pop_back();
Point res = S1.back();
S1.push_back(p);
return res;
}
// Utility function to swap two points
void swap(Point& z2, Point& z3) {
Point temp = z2;
z2 = z3;
z2 = temp;
}
// Utility function to find the square of the Euclidean distance between two points
int distSq(Point z2, Point z3) {
return (z2.a - z3.a)*(z2.a - z3.a) + (z2.b - z3.b)*(z2.b - z3.b);
}
// Function to compare two points based on their polar angle
int compare(const void* vp1, const void* vp2) {
Point* z2 = (Point*)vp1;
Point* z3 = (Point*)vp2;
// Find orientation
int orient = (z2->b - z1.b) * (z3->a - z2->a) - (z2->a - z1.a) * (z3->b - z2->b);
if (orient == 0)
return (distSq(z1, *z3) >= distSq(z1, *z2)) ? -1: 1;
return (orient < 0)? -1: 1;
}
// Function to perform the Angular Sweep Algorithm
void convexHull(std::vector<Point>& points) {
// Find the bottommoscpp tutorial
int bmin = points[0].b, min = 0;
for (int i = 1; i < points.size(); i++) {
int b = points[i].b;
// Pick the bottom-most or chose the left-moscpp tutorial in case of a tie
if ((b < bmin) || (bmin == b && points[i].a < points[min].a))
bmin = points[i].b, min = i;
}
// Place the bottom-moscpp tutorial at first position
swap(points[0], points[min]);
// Sort n-1 points concerning the firscpp tutorial
// A point z2 comes before z3 in sorted output if z3 has larger polar angle (in counterclockwise direction) than z2
z1 = points[0];
qsort(&points[1], points.size() - 1, sizeof(Point), compare);
// If two or more points make same angle with z1, remove all but the one that is farthest from z1
int m = 1; // Initialize size of modified array
for (int i = 1; i < points.size(); i++) {
// Keep removing i while angle of i and i+1 is same with respect to z1
while (i < points.size() - 1 && compare(&points[i], &points[i + 1]) == 0)
i++;
points[m] = points[i];
m++; // Update size of modified array
}
if (m < 3) return; // Convex hull not possible
// Create an empty stack and push the first three points to it
std::vector<Point> S1;
S1.push_back(points[0]);
S1.push_back(points[1]);
S1.push_back(points[2]);
// Process remaining n-3 points
for (int i = 3; i < m; i++) {
// Keep removing top while the angle formed by points next-to-top, top, and points[i] makes a non-left turn
while (S1.size() > 1 && ((S1[S1.size() - 1].b - S1[S1.size() - 2].b) * (points[i].a - S1[S1.size() - 1].a) -
(S1[S1.size() - 1].a - S1[S1.size() - 2].a) * (points[i].b - S1[S1.size() - 1].b)) <= 0)
S1.pop_back();
S1.push_back(points[i]);
}
// Print convex hull points
for (int i = 0; i < S1.size(); i++)
std::cout << "(" << S1[i].a << ", " << S1[i].b << ")" << std::endl;
}
int main() {
std::vector<Point> points = {{0, 3}, {1, 1}, {2, 2}, {4, 4},
{0, 0}, {1, 2}, {3, 1}, {3, 3}};
convexHull(points);
return 0;
}
Output: