diff --git a/ConvexHull/GeneralCaseExamples1.png b/ConvexHull/GeneralCaseExamples1.png new file mode 100644 index 000000000..47b0e66fe Binary files /dev/null and b/ConvexHull/GeneralCaseExamples1.png differ diff --git a/ConvexHull/a.out b/ConvexHull/a.out new file mode 100755 index 000000000..3cc188f66 Binary files /dev/null and b/ConvexHull/a.out differ diff --git a/ConvexHull/convexHullJarviss.cpp b/ConvexHull/convexHullJarviss.cpp new file mode 100644 index 000000000..1270a71f1 --- /dev/null +++ b/ConvexHull/convexHullJarviss.cpp @@ -0,0 +1,57 @@ +#include +#define PB push_back +typedef long long int ll; +using namespace std; + +struct point{ + int x, y; +}; +vector hull; + +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) // p, q, r are colinear + return 0; + else if(val > 0)// Clockwise + return 1; + else // CounterClockwise + return 2; +} + +void convexHull(point *points, int n){ + int l = 0; + if(n < 3) // Hull doesn't exist + return; + for(int i = 1;i < n; i++) // finding the left-most point + if(points[i].x < points[l].x) + l = i; + int start = l, q; + do{ + hull.PB(points[l]); + q = (l + 1) % n; + for(int i = 0;i < n; i++){ + // If i is more counterclockwise than current q, then update q + if(orientation(points[l], points[i], points[q]) == 2) + q = i; + } + l = q; + } + while(l != start); +} + + +int main(){ + int i, n, x, y; + ios_base::sync_with_stdio(false);cin.tie(NULL); + cin >> n; + point points[100100]; + for(i = 0;i < n; i++){ + cin >> x >> y; + points[i].x = x; + points[i].y = y; + } + convexHull(points, n); + for(i = 0;i < hull.size(); i++) + cout << "(" << hull[i].x << ", " << hull[i].y << ")\n"; + return 0; +} diff --git a/ConvexHull/examplesGeneralCase211.png b/ConvexHull/examplesGeneralCase211.png new file mode 100644 index 000000000..1c78e337e Binary files /dev/null and b/ConvexHull/examplesGeneralCase211.png differ diff --git a/ConvexHull/examplesSpecialCase1.png b/ConvexHull/examplesSpecialCase1.png new file mode 100644 index 000000000..7aab94c07 Binary files /dev/null and b/ConvexHull/examplesSpecialCase1.png differ diff --git a/ConvexHull/grahamScan.cpp b/ConvexHull/grahamScan.cpp new file mode 100644 index 000000000..d1fb78c5d --- /dev/null +++ b/ConvexHull/grahamScan.cpp @@ -0,0 +1,98 @@ +#include +#define PB push_back +typedef long long int ll; +using namespace std; + +struct point{ + int x, y; +}; +point p0; + +point nextToTop(stack &s){ + point p = s.top(); + s.pop(); + point res = s.top(); + s.push(p); + return res; +} + +int swap(point &p1, point &p2){ + point temp = p1; + p1 = p2; + p2 = temp; +} + +int disSq(point p1, point p2){ + return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y); +} + +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) // colinear + return 0; + else if(val > 0) // clockwise + return 1; + else // counterClockwise + return 2; +} + +bool cmp(point p1, point p2){ + int o = orientation(p0, p1, p2); + if(o == 0) + return (disSq(p0, p2) >= disSq(p0, p1))? true : false; + else if(o == 2) + return true; + else + return false; +} + +void convexHull(point *points, int n){ + int ymin = points[0].y, min = 0, i; + for(i = 1;i < n; i++){ + int y = points[i].y; + if(y < ymin || (ymin == y && points[i].x < points[min].x)) + ymin = points[i].y, min = i; + } + swap(points[0], points[min]); + p0 = points[0]; + sort(&points[1], &points[1] + n - 1, cmp); // n - 1 signifies the number of elements + int m = 1; + for(i = 1;i < n; i++){ + while(i < n - 1 && orientation(p0, points[i], points[i+1]) == 0) + i++; + points[m] = points[i]; + m++; + } + if(m < 3) // Hull doesn't exist + return; + stack s; + s.push(points[0]); + s.push(points[1]); + s.push(points[2]); + for(i = 3;i < m; i++){ + while(orientation(nextToTop(s), s.top(), points[i]) != 2) + s.pop(); + s.push(points[i]); + } + while(!s.empty()){ + point p = s.top(); + cout << "(" << p.x << ", " << p.y << ")" << endl; + s.pop(); + } +} + +int main(){ + ios_base::sync_with_stdio(false);cin.tie(NULL); + point points[100100]; + int n; + cin >> n; + for(int i = 0;i < n; i++){ + int x, y; + cin >> x >> y; + points[i].x = x; + points[i].y = y; + } + convexHull(points, n); + return 0; +} + diff --git a/ConvexHull/lineIntersect.cpp b/ConvexHull/lineIntersect.cpp new file mode 100644 index 000000000..20531e841 --- /dev/null +++ b/ConvexHull/lineIntersect.cpp @@ -0,0 +1,50 @@ +#include +#define PB push_back +typedef long long int ll; +using namespace std; + +struct Point{ + int x, y; +}; + +// If collinear, do they intersect? i.e. does q lie on 'pr' +bool intersect(Point p, Point q, Point r){ + if(q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y)) + return true; + return false; +} + +// 0 --> colinear +// 1 --> Clockwise +// 2 --> CounterClockwise +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; + if(val > 0) return 1; + if(val < 0) return 2; +} + +int doIntersect(Point p1, Point q1, Point p2, Point q2){ + int o1 = orientation(p1, q1, p2); + int o2 = orientation(p1, q1, q2); + int o3 = orientation(p2, q2, p1); + int o4 = orientation(p2, q2, q1); + if (o1 != o2 && o3 != o4) + return true; + + // Special Cases + // p1, q1 and p2 are colinear and p2 lies on segment p1q1 + if (o1 == 0 && intersect(p1, p2, q1)) return true; + + // p1, q1 and p2 are colinear and q2 lies on segment p1q1 + if (o2 == 0 && intersect(p1, q2, q1)) return true; + + // p2, q2 and p1 are colinear and p1 lies on segment p2q2 + if (o3 == 0 && intersect(p2, p1, q2)) return true; + + // p2, q2 and q1 are colinear and q1 lies on segment p2q2 + if (o4 == 0 && intersect(p2, q1, q2)) return true; + + return false; // Doesn't fall in any of the above cases +} + diff --git a/ConvexHull/pointOrientation.png b/ConvexHull/pointOrientation.png new file mode 100644 index 000000000..64ba2850e Binary files /dev/null and b/ConvexHull/pointOrientation.png differ