例如:
输入:ab /线段/,{1,2,3,4,5,6} /凸多边形沿逆时针顺序的顶点及其坐标/
输出:3-4,5-6
![enter image description here](https://istack.dev59.com/3DjiN.webp)
这个答案有些令人困惑,所以我想用另一种方式提供更多细节。
假设您的数据存储在数组P中,并且您正在检查线U。 p_0是最左下角的点。即p_0.x < p_i.x,并确保在平局的情况下p_0.y < p_i.y。 P按照大多数ConvexHulls的ccw进行排序。您还有p_m,其中m是半程点,即n/2首先。我们将L、M、H定义为二进制搜索索引,其中L= 0,M= n/2,H=n-1。我将编写递归,但您可以展开此操作。
基本情况:
"多边形"数组是否具有n<= 3个点。在这种情况下,只需检查三角形或直线中的每条线与U O(1)的交点。
递归步骤:
通过计算L_m = Line(p_0, p_m)与U的交点p_I来确定是否相交,时间复杂度为O(1)。如果p_I是NULL,我们知道U是从L_m的顺时针或逆时针方向,可以使用有向定向测试(Directed Orientation Test)在O(1)的时间内找到哪个方向是顺时针,如果是逆时针,则使用ConvexLineInt({p_0,p_m,...,p_h},U)进行递归;否则使用ConvexLineInt({p_0,p_l,...,p_m},U)。
如果p_I存在,它必须出现在线L_m中,即它在一个完全有序的集合中,并且我们检查以下情况:
L_m.0 <= p_I <= L_m.1 (在之间) => 返回“线相交”
p_I < L_m.0,即在多边形的左侧。我们计算p_U,它与L_0 = Line(p_0,p_l)相交,O(1)。如果p_U为NULL,则意味着线U在多边形外部。这意味着U是ccw到L_0。由于p_U存在,我们可以检查Orient(L_m,p_U)= w,这不能为0,因为有一个交点。如果w> 0,则交点是ccw,即U只能是ccw到L_m,我们可以像上面一样递归“右”集。否则,该点在下方,U只能是cw到L_m,在“左”集上递归。请注意,我们始终保留p_0,它是我们的枢轴点。
p_I > L_m.1应该是对称的,我将其留作练习。
由于每个检查都是O(1),而且我们将集合分成两个或更多,因此运行时间就是二分搜索的时间,即O(log n)。如果您想要正式一些,请使用主定理。
希望这对你有所帮助! 方向测试:如何判断一个点在直线的左侧还是右侧