Graham(GiftWraping)求凸包算法

step1: 对于一点列,选出y值最小的点;
step2: 将该点列绕该y最小值点逆时针排列;
step3: 判断每一个点的凹凸性。

程序设计:
step1: 确定input和output.
       input: 原始输入的一个点列inputPoints;
       output: 所求凸包上的点构成的点列outputPoints。
step2: 求出inputPoints中y值最小的那个点,并与其第一个元素交换位置,设计函数SortbyAngle()。向量点乘可以得到角的cosin值,用stl中的sort()函数排序。
step3: 求outputPonts,确保放入该点列的三个点是一个凸折线段。

 

类设计如下:

GrahamConvex.h class CGrahamConvex { public: CGrahamConvex(void); ~CGrahamConvex(void); CGrahamConvex(const vector<CPoint>& originalPoints); vector<CPoint> GetOutputPoints(); private: vector<CPoint> inputPoints; void SortbyAngle(); }; GrahamConvex.cpp CGrahamConvex::CGrahamConvex(void) { } CGrahamConvex::CGrahamConvex( const vector<CPoint>& originalPoints ) { inputPoints = originalPoints; } CGrahamConvex::~CGrahamConvex(void) { } struct ID_CosAngle { int idofPoint; double cosAngle; CPoint pos; friend bool operator <(const ID_CosAngle& first, const ID_CosAngle& second) { return first.cosAngle < second.cosAngle; } }; void CGrahamConvex::SortbyAngle() { if (inputPoints.size() == 0) return; //get the id of the y_min point int y_min = INT_MAX; int id_ymin = 0; for (int i = 0; i < (int)inputPoints.size(); i++) { if (y_min > inputPoints[i].y) { id_ymin = i; y_min = inputPoints[i].y; } } //swap the position between point_ymin and the first point of inputPoints CPoint temp = inputPoints[id_ymin]; inputPoints[id_ymin] = inputPoints[0]; inputPoints[0] = temp; // sort the points according to the cos value by default(small-big), so the points a] //arranged clockwisely vector<ID_CosAngle> Id_cosAngles; for (int i = 1; i < (int)inputPoints.size(); i++) { CVector_2D vi(inputPoints[i], inputPoints[0]); double cosAngle = vi.x / vi.Modulus(); ID_CosAngle temp; temp.idofPoint = i; temp.cosAngle = cosAngle; temp.pos = inputPoints[i]; Id_cosAngles.push_back(temp); } sort(Id_cosAngles.begin(), Id_cosAngles.end()); //get sorted inputPoints for (int i = 0; i < (int)Id_cosAngles.size(); i++) { inputPoints[i + 1] = Id_cosAngles[i].pos; } } vector<CPoint> CGrahamConvex::GetOutputPoints() { //sort the inputpoints by angle - here is clockwise SortbyAngle(); //if the input points'number is none or only one, then outputPoints //are the same with the inputPoints if (inputPoints.size() <= 1) { return inputPoints; } //add the points which are convex and remove the points which are concave vector<CPoint> outputPoints; outputPoints.push_back(inputPoints[0]); outputPoints.push_back(inputPoints[1]); for ( int i = 2; i < (int)inputPoints.size(); i++) { //check the current input point with possible output points CVector_2D v1(outputPoints[outputPoints.size() - 1], outputPoints[outputPoints.size() - 2]); CVector_2D v2(inputPoints[i], outputPoints[outputPoints.size() - 1]); if (CrossProductSign(v1, v2) <= 0) { outputPoints.push_back(inputPoints[i]); } else { while (CrossProductSign(v1, v2) >= 0 ) { outputPoints.pop_back(); if (outputPoints.size() > 1) { v1 = CVector_2D(outputPoints[outputPoints.size() - 1], outputPoints[outputPoints.size() - 2]); v2 = CVector_2D(inputPoints[i], outputPoints[outputPoints.size() - 1]); } else { break; } } outputPoints.push_back(inputPoints[i]); } } return outputPoints; }

你可能感兴趣的:(Graham(GiftWraping)求凸包算法)