Skip to content

Commit

Permalink
Convex Hull
Browse files Browse the repository at this point in the history
  • Loading branch information
raudraroop authored and yshshrm committed Oct 31, 2018
1 parent 73c1bcf commit a4c487e
Showing 1 changed file with 64 additions and 0 deletions.
64 changes: 64 additions & 0 deletions cpp/convexHull.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
struct pt{
long long x, y;
pt(){}
pt(long long _x, long long _y):x(_x), y(_y){}
pt operator+(const pt & p) const { return pt(x + p.x, y + p.y); }
pt operator-(const pt & p) const { return pt(x - p.x, y - p.y); }
long long cross(const pt & p) const { return x * p.y - y * p.x; }
long long dot(const pt & p) const { return x * p.x + y * p.y; }
long long cross(const pt & a, const pt & b) const { return (a - *this).cross(b - *this); }
long long dot(const pt & a, const pt & b) const { return (a - *this).dot(b - *this); }
long long sqrLen() const { return this->dot(*this); }
};

bool lexComp(const pt & l, const pt & r){
return l.x < r.x || (l.x == r.x && l.y < r.y);
}

int sgn(long long val){
return val > 0 ? 1 : (val == 0 ? 0 : -1);
}

vector<pt> seq;
int n;

bool pointInTriangle(pt a, pt b, pt c, pt point){
long long s1 = abs(a.cross(b, c));
long long s2 = abs(point.cross(a, b)) + abs(point.cross(b, c)) + abs(point.cross(c, a));
return s1 == s2;
}

void prepare(vector<pt> & points){
n = points.size();
int pos = 0;
for(int i = 1; i < n; i++){
if(lexComp(points[i], points[pos]))
pos = i;
}
rotate(points.begin(), points.begin() + pos, points.end());

n--;
seq.resize(n);
for(int i = 0; i < n; i++)
seq[i] = points[i + 1] - points[0];
}

bool pointInConvexPolygon(pt point){
if(seq[0].cross(point) != 0 && sgn(seq[0].cross(point)) != sgn(seq[0].cross(seq[n - 1])))
return false;
if(seq[n - 1].cross(point) != 0 && sgn(seq[n - 1].cross(point)) != sgn(seq[n - 1].cross(seq[0])))
return false;

if(seq[0].cross(point) == 0)
return seq[0].sqrLen() >= point.sqrLen();

int l = 0, r = n - 1;
while(r - l > 1){
int mid = (l + r)/2;
int pos = mid;
if(seq[pos].cross(point) >= 0)l = mid;
else r = mid;
}
int pos = l;
return pointInTriangle(seq[pos], seq[pos + 1], pt(0, 0), point);
}

0 comments on commit a4c487e

Please sign in to comment.