CPoint basicXY;
// 查找基准点
CPoint CH_FindBasicPoint(std::list<CPoint>& ptSet){
float tempX = 0.0f;
float tempY = 0.0f;
std::list<CPoint>::iterator pt = ptSet.begin();;
tempX = pt->x;
tempY = pt->y;
// 先找到最小Y点
for (pt++; pt != ptSet.end(); pt++)
{
if(tempY > pt->y || (tempY == pt->y && tempX > pt->x))
{
tempY = pt->y;
tempX = pt->x;
}
}
// 获取最小X,最小Y点
return CPoint(tempX,tempY);
}
// 计算向量ab与X轴的夹角
float CH_CalAngle(const CPoint& a,const CPoint& b){
return (b.x-a.x)/sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
}
// 计算向量PQ叉积
float CH_XProduct(const CPoint& P,const CPoint& Q){
return P.x*Q.y-P.y*Q.x;
}
// 比较
bool CH_Compare(const CPoint& a,const CPoint& b){
return CH_CalAngle(basicXY,a) > CH_CalAngle(basicXY,b);
}
// 向量排序
void CH_VectorSort(std::list<CPoint>& ptSet,std::vector<CPoint>& chSet){
std::list<CPoint>::iterator pt;
for (pt = ptSet.begin(); pt != ptSet.end(); pt++)
{
if (pt->x != basicXY.x || pt->y != basicXY.y)
{
// 忽略基点
// 方向由基点到选择点
chSet.push_back(CPoint(pt->x,pt->y));
}
}
// 向量夹角排序 从小到大排序 逆时针
std::sort(chSet.begin(),chSet.end(),CH_Compare);
// 将基点存入
chSet.insert(chSet.begin(),CPoint(basicXY.x,basicXY.y));
}
// 回溯消除所有 逆时针的点
void CH_BackTrack(std::vector<CPoint>& chSet,int& startPos,int& endPos){
int curPos = startPos;
for ( ; curPos < endPos && curPos < chSet.size();curPos++)
{
CPoint P = CPoint(chSet[curPos].x-chSet[curPos-1].x,chSet[curPos].y-chSet[curPos-1].y);
CPoint Q = CPoint(chSet[curPos-1].x-chSet[curPos-2].x,chSet[curPos-1].y-chSet[curPos-2].y);
if(CH_XProduct(P,Q) > 0)
{
// 向量叉积 > 0 顺时针 < 0 逆时针 = 0 共线
// 顺时针 删除
chSet.erase(chSet.begin()+curPos-1);
CH_BackTrack(chSet,startPos,curPos);
--endPos;
--curPos;
}
}
}
// 得到凸包
void CH_GetConvexHull(std::vector<CPoint>& chSet){
// 点 或 线 或 三角形
if (chSet.size() <= 3)
{
return;
}
// 回溯删除 所有 顺时针的点
int startPos = 2;
int endPos = chSet.size();
CH_BackTrack(chSet,startPos,endPos);
}
void CH_ConvexHull(std::list<CPoint>& ptSet,std::vector<CPoint>& chSet){
// 找出基点
basicXY = CH_FindBasicPoint(ptSet);
// 向量排序 逆时针 根据向量夹角
CH_VectorSort(ptSet,chSet);
// 获得凸包
CH_GetConvexHull(chSet);
}
凸包
最新推荐文章于 2023-10-11 21:16:42 发布