寻找将确定点是否在弧的左/右的算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寻找将确定点是否在弧的左/右的算法相关的知识,希望对你有一定的参考价值。
我目前需要定位一种算法,该算法将确定一个点是否在弧的右侧或左侧。这是以下算法的扩展,包括弧:
// isLeft(): tests if a point is Left|On|Right of an infinite line.
// Input: three points P0, P1, and P2
// Return: >0 for P2 left of the line through P0 and P1
// =0 for P2 on the line
// <0 for P2 right of the line
// See: Algorithm 1 "Area of Triangles and Polygons"
inline int
isLeft( Point P0, Point P1, Point P2 )
{
return ( (P1.x - P0.x) * (P2.y - P0.y)
- (P2.x - P0.x) * (P1.y - P0.y) );
}
//===================================================================
此代码是从网站检索的:http://geomalgorithms.com/a03-_inclusion.html
这用于绕组数算法。我的目标是扩展此算法以包括弧而不仅仅是线。
在提到的帖子中,作者试图确定该点是否位于弧的中心角内。从一个点可以超出半径但是弧仍然包含所讨论的点的意义上来说,我的略有不同。
我创建了一张我试图描述的图片。请注意,我不是任何方式的抽屉。无论如何,有问题的弧是绿色的。我创建了两条平行线,分别与起始节点和结束节点处的弧相交。这些线条是红色的。请原谅我的绘画技巧。即使图中的红线看起来不平行,也可以假设它们是平行的。图纸仅供参考。我在这篇文章中定义了这些线是平行的。这篇文章取代了图纸中的任何内容。这意味着即使图形没有表明线条彼此平行,它们实际上也是假设彼此平行,因为我已经在帖子中说明了这一点。我需要帮助来提出一种算法,该算法将确定一个点是否位于蓝色区域内。请注意,红线可以无限延伸。为了便于讨论,我在蓝色区域中以任意点结束了颜色。
如果该点位于蓝色区域内,我将其视为包含该点的弧。作为旁注,我用C ++编写这个算法(因此是c ++标签)
我所说的弧的类型是一个圆弧,它有一个起点和终点,一个圆弧角,一个圆心点和半径。
编辑:
Yves和MBo的两个答案包含了我试图解释的更好的图片。请参考这些图片。 MBo包含更好的图片。
正如Yves所描述的那样,我试图测试一个点是否位于由弧和两条平行线界定的半无限板内。这些线与开始和结束节点相交。请参阅MBo绘图以获得更清晰的图片。伊夫第一次画也是一幅清晰的画面。我正在测试该点是否位于阴影区域。
我使用左右词作为视角。我很抱歉我第一次创建帖子时没有清楚地解释这个问题。想象一下,你正在逆时针方向行进这个弧线。第一个节点是最右边的节点,端节点是最左边的节点。从旅行者的角度来看,该弧(或半无限平板)所包含的点将位于弧的左侧。右边的任何点都在弧外。
让你有圆弧中心C,半径R,结束A和B.
如果我理解你的意愿:
如果点P和中心C位于与AB线相同的半平面上: 检查点P到AB线的投影是否位于AB段的极限内 否则(如果P点和C点在不同的半平面上): 检查从P到C的距离是否不超过R.
if Sign(CrossProduct(P-A,B-A)) = Sign(CrossProduct(C-A,B-A))
Result = DotProduct(P-A, B-A) / DotProduct(B-A, B-A) in range 0..1
else
Result = DotProduct(P-C, P-C) <= R^2
例如,对于点K和H,符号条件为真,对于H,结果为真。对于I和J,符号条件为假,对于点J,结果为真
暗示:
如果你的最终目标是实现宽数算法,你要问的是测试点是否位于由两条平行线(比如水平,如Yb < Y < Ye
)和弧所界定的半无限板内。
圆的等式读取(X - Xc)² + (Y - Yc)² = R²
,从中绘制条件X < Xc + √(R²-(Y - Yc)²)
。为方便起见,您可以拆分所有弧线,使它们只遇到一次水平线。
在其他配置中,您将不得不考虑另一侧的交叉点X < Xc - √(R²-(Y - Yc)²)
,但我会给您完整的讨论。
以上是关于寻找将确定点是否在弧的左/右的算法的主要内容,如果未能解决你的问题,请参考以下文章