codeIIEST/Algorithms

View on GitHub
Competitive Coding/Geometry/Convex hull/convex hull jarvis march.cpp

Summary

Maintainability
Test Coverage
#include<bits/stdc++.h>
using namespace std;
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define md 1000000007
#define ll long long int
#define vi vector<int>
#define vll vector<i64>
#define pb push_back
#define all(c) (c).begin(),(c).end()
template< class T > T max2(const T &a,const T &b) {return (a < b ? b : a);}
template< class T > T min2(const T &a,const T &b) {return (a > b ? b : a);}
template< class T > T max3(const T &a, const T &b, const T &c) { return max2(a, max2(b, c)); }
template< class T > T min3(const T &a, const T &b, const T &c) { return min2(a, min2(b, c)); }
template< class T > T gcd(const T a, const T b) { return (b ? gcd<T>(b, a%b) : a); }
template< class T > T lcm(const T a, const T b) { return (a / gcd<T>(a, b) * b); }
template< class T > T mod(const T &a, const T &b) { return (a < b ? a : a % b); }
typedef pair<ll,ll> pi;
typedef struct
{
    int x;
    int y;
}point;
int crossprod(point points[],int a,int b,int c)//This function calculates the crossproduct  of the given two vectors . one vector is ab and other is ac.
{
    point current = points[a];
    point target = points[b];
    point temp  = points[c];
    int y1 = target.y-current.y;
    int x1 = target.x-current.x;
    int x2 = temp.x-current.x;
    int y2 = temp.y-current.y;
    return y2*x1-x2*y1;
}
int closer(point points[],int a,int b,int c)//This function calculates the closer of the given two points from a and returns the index of the closer one.
{
    point current = points[a];
    point target = points[b];
    point temp  = points[c];
    double dist1 = sqrt((current.x-target.x)*(current.x-target.x)-(current.y-target.y)*(current.y-target.y));
    double dist2 = sqrt((current.x-temp.x)*(current.x-temp.x)-(current.y-temp.y)*(current.y-temp.y));
    if(dist1<dist2)
        return b;
    else
        return c;
}
int main()
{
    int n;//no of points
    cin>>n;
    point points[n];
    for(int i=0;i<n;i++)
    {
        cin>>points[i].x>>points[i].y;
    }
    //now we look for the leftmost point
    int index=0,mini=100000;
    for(int i=0;i<n;i++)
    {
        if(points[i].x<mini)
        {
            mini=points[i].x;
            index=i;
        }
    }
    set<int> result;

    result.insert(index);//we add the left most point in the result array
    int current = index;//now our index becomes the index to the current point
    vi colinear;
    while(true)
    {
        int target = 0 ;//consider the starting target to be point with index zero
    for(int i=1;i<n;i++)
    {

        if(current==i)//if the current point and the point we are going to compare are the same then nothing below should be executed
        {
            continue;
        }
        else
        {
            int val = crossprod(points,current,target,i);
            if(val > 0)//If the cross prod value is greater than zero than this means that we the point i is in the left side of the line segement that passes through the target and current so now the target needs to be changed.
            {

                target = i;
                colinear.clear();//we also need to clear the colinear array as the target itself is changed.
            }
            if(val  == 0)
            {
                int close = closer(points,current,target,i);//This gives the index of the closer point.
                if(close == target)
                    target = i;
                colinear.pb(close);
            }
        }
    }
    int len =  colinear.size();
    for(int k = 0;k<len;k++)

    colinear.clear();
    if(target == index)//we should end our search if our target becomes equal to the first index we added in the result
    {
        break;
    }
    else
    {

        result.insert(target);
        current = target;
    }
    }
int len = result.size();
 set<int> :: iterator i= result.begin();
for(;i!=result.end();++i)
{
    cout<<points[(*i)].x<<" "<<points[(*i)].y<<endl;
}


}