清华计算几何-ConvexHull(凸包)-求极边

前言

清华计算几何-ConvexHull(凸包)-求极点InTriangle/ToLeft Test-优快云博客

上篇博客描述了一种从点集合暴力求解极点的算法,复杂度为O(n4), 耗费相当高. 下面介绍一种优于暴力求极点的算法

极边(extremity edge)

和极点概念类似, 如果点集合中,存在两个点连成一条线, 其他点都在这条边的同一侧,则这条线为极边(extremity edge), 这两个点为极点。

算法思路

遍历所有的边, 判断其他点是否都在这条边的同一侧。

算法复杂度: O(n3), n2用于遍历所有边,n用于遍历所有点

伪代码实现

代码实现

#include <iostream>
#include <vector>

using namespace std;

struct Point
{
	float x;
	float y;
	bool extreme;
};

float Area2(const Point& inPointA, const Point& inPointB, const Point& inPointC)
{
	float value =
		inPointA.x * inPointB.y - inPointA.y * inPointB.x
		+ inPointB.x * inPointC.y - inPointB.y * inPointC.x
		+ inPointC.x * inPointA.y - inPointC.y * inPointA.x;

	return value;
}


bool IsLeftTest(const Point& inPointA, const Point& inPointB, const Point& inPointC)
{
	return Area2(inPointA, inPointB, inPointC) > 0;
}


void CheckExtrmtiEdge(vector<Point>& inPoints, int idxA, int idxB)
{
	bool bLeftEmpty = true;
	bool bRightEmpty = true;
	int pointNum = inPoints.size();

	for (int idx = 0; idx < pointNum; idx++)
	{
		if (idx != idxA && idx != idxB)
		{

			if (IsLeftTest(inPoints[idx], inPoints[idxA], inPoints[idxB]))
			{
				bLeftEmpty = false;
			}
			else
			{
				bRightEmpty = false;
			}

			if (!bLeftEmpty && !bRightEmpty)
				break;
		}
	}

	if (bLeftEmpty || bRightEmpty)
	{
		inPoints[idxA].extreme = true;
		inPoints[idxB].extreme = true;
	}
}


void GetEpFromExtrmtiEdge(vector<Point>& inPoints)
{
	int pointNum = inPoints.size();
	for (auto& point : inPoints)
	{
		point.extreme = false;
	}

	for (int idxA = 0; idxA < pointNum; idxA++)
	{
		for (int idxB = idxA + 1; idxB < pointNum; idxB++)
		{
			CheckExtrmtiEdge(inPoints, idxA, idxB);
		}
	}


}


int main()
{
    std::cout << "Hello World!\n";

	// point set contruct
	vector<Point> inPoints =
	{
		{0, 0},
		{-1, -1},
		{5, 2},
		{4, 5},
		{3, 3},
		{-1, 3},
		{2, 2},
		{-3, 2},
	};


	GetEpFromExtrmtiEdge(inPoints);

	for (int index = 0; index < inPoints.size(); index++)
	{
		if (inPoints[index].extreme)
		{
			printf("(%f, %f)\n", inPoints[index].x, inPoints[index].y);
		}
	}

}

运行结果

对于和上节同样的数据集,得出的结果一致

参考资料 

[1]清华计算几何 P13-P15

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值