寻找将确定一个点是否在弧的左/右

时间:2018-01-02 03:45:16

标签: c++ algorithm geometry computational-geometry

我目前需要定位一种算法,该算法将确定一个点是否在弧的右侧或左侧。  这是以下算法的扩展,包括弧:

 // 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

这用于绕线数算法。我的目标是扩展此算法以包括弧而不仅仅是线。

这不像这篇文章:How to determine whether a point (X,Y) is contained within an arc section of a circle (i.e. a Pie slice)?

在上面提到的帖子中,作者试图确定该点是否位于弧的中心角内。从一个点可以超出半径但是弧仍然包含所讨论的点的意义上来说,我的略有不同。

我创建了一张我试图描述的图片。请注意,我不是任何方式的抽屉。无论如何,有问题的弧是绿色的。我创建了两条平行线,分别与起始节点和结束节点处的弧相交。这些线条为红色。请原谅我的绘画技巧。即使图中的红线看起来不平行,也可以假设它们是平行的。图纸仅供参考。我在这篇文章中定义了这些线是平行的。这篇文章取代了图纸中的任何内容。这意味着即使图形没有表明线条彼此平行,它们实际上也是假设彼此平行,因为我已经在帖子中说明了这一点。我需要帮助来提出一种算法,该算法将确定一个点是否位于蓝色区域内。请注意,红线可以无限延伸。为了便于讨论,我在蓝色区域中以任意点结束了颜色。

如果该点位于蓝色区域内,我将其视为包含该点的弧。作为旁注,我用C ++编写了这个算法(因此是c ++标签)

我所说的弧的类型是一个圆弧,它有一个起点和终点,一个圆弧角,一个圆心点和半径。

编辑:

Yves和MBo的两个答案包含了我试图解释的更好的图片。请参考这些图片。 MBo包含更好的图片。

正如Yves所描述的那样,我试图测试一个点是否位于由弧和两条平行线界定的半无限板内。这些线与开始和结束节点相交。请参阅MBo绘图以获得更清晰的图片。伊夫第一次画也是一幅清晰的画面。我正在测试该点是否位于阴影区域。

我使用左右术语作为视角。我很抱歉我第一次创建帖子时没有清楚地解释这个问题。想象一下,你正在逆时针方向行进这个弧线。第一个节点是最右边的节点,端节点是最左边的节点。从旅行者的角度来看,该弧(或半无限平板)所包含的点将位于弧的左侧。右边的任何点都在弧外。

2 个答案:

答案 0 :(得分:3)

<强>提示:

如果您的最终目标是实现宽数算法,那么您要问的是测试该点是否位于由两条平行线(例如水平线,例如Yb < Y < Ye)划分的半无限平板内。弧线。

圆圈的等式显示(X - Xc)² + (Y - Yc)² = R²,您可以从中绘制条件X < Xc + √(R²-(Y - Yc)²)。为方便起见,您可以拆分所有弧线,使它们只遇到水平一次。

enter image description here

在其他配置中,您必须考虑另一侧的交叉点X < Xc - √(R²-(Y - Yc)²),但我会给您完整的讨论。 enter image description here

答案 1 :(得分:2)

让你有圆弧中心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,结果为真

enter image description here