您的位置:首页 > 其它

Graham(GiftWraping)求凸包算法

2010-02-02 15:14 435 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: