【问题标题】:Looking for algorithm that will determine if a point is to the left/right of an arc寻找将确定一个点是否在弧的左/右的算法
【发布时间】:2018-06-11 19:52:34
【问题描述】:

我目前需要找到一种算法来确定一个点是在弧的右侧还是左侧。 这是以下算法的扩展以包含弧:

 // 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 图纸以获得更清晰的图片。 Yves 的第一幅画也是清晰的画面。我正在测试该点是否位于阴影区域。

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

【问题讨论】:

  • 这到底是什么弧线?它是沿着圆周发现的典型弧吗?
  • 你可能需要更好的绘图
  • “我在起点和终点创建了两条与圆弧相切的平行线。” 红线看起来根本不与圆弧相切。
  • 算法是一种算法,它不应该是特定于语言的。
  • 真的不清楚你在问什么。 1) left/right 似乎毫无意义。您如何解释顶点在 0 度、45 度、90 度、180 度等处? 2)你的形象没有澄清任何事情。你如何确定每条红线的梯度? 你画的不是切线;我认为你误解了这个术语。 3) 在你能正确定义你的需求之前,没有办法确定给定的算法是否“正确”。

标签: c++ algorithm geometry computational-geometry


【解决方案1】:

提示:

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

圆的方程为(X - Xc)² + (Y - Yc)² = R²,从中可以得出条件X &lt; Xc + √(R²-(Y - Yc)²)。为方便起见,您可以拆分所有弧线,使它们只与水平线相交一次。

在其他配置中,您将不得不考虑另一边的交叉点,X &lt; Xc - √(R²-(Y - Yc)²),但我将完整的讨论留给您。

【讨论】:

  • 是的,这就是我一直试图解释的。我想我会更新我的帖子以反映你在这里写的内容
【解决方案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点的结果为真

【讨论】:

  • 这看起来很棒,对于点 H,如果点仍然在阴影区域但离点 C 更远(大于 R),我认为点 H 仍然是真的?
  • 是的,我考虑无限半波段。
  • 好的,还有,sign函数是什么?我对那个不太熟悉?
  • 例如+1表示正值,0表示零,-1表示负值
  • 好的,我明白了,在第二行中,算法是否在测试结果是否在 0 和 1 之间?
猜你喜欢
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 2011-05-04
  • 2012-03-16
  • 2020-03-24
  • 1970-01-01
  • 2010-10-24
  • 2010-12-23
相关资源
最近更新 更多