凸包

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);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值