凸包

来源:互联网 发布:java堆和栈的区别 编辑:程序博客网 时间:2024/04/29 12:01
#include <iostream>#include <stack>#include <algorithm>using namespace std;struct point{double x;double y;point(double sx=0, double sy=0):x(sx),y(sy){}};// put the smallest y coordination in the first placevoid adjust_first_element(point* p, int len){if (len <= 0) return;int base_index = 0;for (int i = 0; i<len; ++i){if (p[i].y < p[base_index].y){base_index = i;}else if(p[i].y == p[base_index].y){if (p[i].x < p[base_index].x)base_index = i;}}point t = p[0];p[0] = p[base_index];p[base_index] = t;}bool cmp_great(const point &a, const point &b, const point &base_point){double t = (a.x-base_point.x)*(b.y-base_point.y)-(a.y-base_point.y)*(b.x-base_point.x);return t < 0;}// a is in the left of b?int cmp_left(const point &a, const point &b){double t = a.x*b.y-a.y*b.x;if (t < 0) return -1;if (t == 0) return 0;return 1;}void my_swap(point &a, point &b){point t = a; a = b; b = t;}int partion(point* p, int left, int right){int i = left-1;int j = right;while(1){while (cmp_great(p[right], p[++i], p[0]));while (cmp_great(p[--j], p[right], p[0])) if (0 >= j) break;if (j <= i) break;my_swap(p[i], p[j]);}my_swap(p[right], p[i]);return i;}// sort by anglevoid angle_sort(point* p, int left, int right){if (left>=right) return;int mid = partion(p, left, right);angle_sort(p, left, mid-1);angle_sort(p, mid+1, right);}point get_vector(stack<point> &stk){point a = stk.top(); stk.pop();point b = stk.top(); stk.push(a);return point(a.x - b.x, a.y - b.y);}void convex_hull(point* p, int left, int right, stack<point> &stk){if (right <= left+2) return;stk.push(p[0]);stk.push(p[1]);point vec_a;point vec_b;int flag = 0;for (int i=2; i<=right; ++i){while(stk.size() >1){vec_a = get_vector(stk);vec_b = point(p[i].x - stk.top().x, p[i].y - stk.top().y);flag = cmp_left(vec_a, vec_b);if (flag >= 0) break;stk.pop();}// 相等,则取长向量的点if (0 == flag){point t = stk.top(); stk.pop();vec_b = point(p[i].x - stk.top().x, p[i].y - stk.top().y);if( vec_a.x*vec_a.x+vec_a.y*vec_a.y > vec_b.x*vec_b.x+vec_b.y*vec_b.y)stk.push(t);elsestk.push(p[i]);}elsestk.push(p[i]);}}void show(const point& a){cout<<a.x<<":"<<a.y<<endl;}int main(int argc, char* argv[]){point vec[8] = {point(0,0), point(10,0), point(3,2), point(2,3),point(4,0), point(4,1), point(0,3), point(-1,1)};adjust_first_element(vec, 8);// put the min y int the first placeangle_sort(vec, 1, 7);// sort by polar angle according x coordinatestack<point> stk;convex_hull(vec, 0, 7, stk);while(!stk.empty()){cout<<stk.top().x<<":"<<stk.top().y<<endl;stk.pop();}return 0;}