Angular Sweep Algorithm In C++

In this article, we will discuss the Angular Sweep Algorithm in C++ with its implementation.

It means that we need to determine the greatest number of points that are included (lying inside the circle rather than on its borders) by a circle of radius r given a set of 2-D points. For this, the angular sweep algorithm is the most efficient technique. In computational geometry, the Angular Sweep Algorithm is used for several purposes, including determining the convex hull of a set of points.

The convex hull of a set of points can be found using the Angular Sweep Algorithm in the following examples:

Example 1:

Input: {{0, 3}, {1, 1}, {2, 2}, {4, 4}, {0, 0}, {1, 2}, {3, 1}, {3, 3}}

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 determines the greatest number of points that a fixed-radius circle with radius "R" may surround given "n" points on a 2-Dimensional plane.

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 us take an example to illustrate the Angular Sweep Algorithm in C++.

Example

#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:

Input Required

This code uses input(). Please provide values below: