【问题标题】:Cone-Line Segment Intersection 2D2D 锥线段相交
【发布时间】:2011-02-20 12:19:35
【问题描述】:

我想知道是否有任何方法可以确定圆锥是否与(有限)线段相交。锥体实际上是一个位于 P(x,y) 处的圆,具有 theta 度视野和半径 r:

我正在尝试在 C# 中执行此操作,但我不知道该怎么做,所以现在这就是我正在做的事情:

  1. 检查线段是否与圆相交;
  2. 如果线段与圆相交,那么我会使用我找到的函数 here 检查线段中的每个点。

但我认为这不是最好的方法。有人有想法吗?

有关其他信息,我需要此功能来制作某种简单的视觉模拟器。

【问题讨论】:

  • @dtb :thanx 帮我插入图片 :)

标签: c# geometry collision-detection


【解决方案1】:

使用Polar Co-ordinates 可能会有所帮助。在这里,不是将一个点表示为 (x,y),而是将其表示为 (r, angle),其中 r 是与原点的距离,而 angle 是与所选轴形成的角度(对应于角度 0)。

在您的情况下,如果您将 P(x,y) 设置为原点,并且将锥体的光线之一设置为角度 = 0,并找到线段端点的极坐标,例如 (r1, ang1) 和 (r2, ang2) 那么您需要满足以下四个条件才能使线段完全位于圆锥体的范围内(包括边界)。

r1 <= r
r2 <= r

ang1 <= theta
ang2 <= theta

其中 r 是圆锥的半径,theta 是视角,您选择了轴,以便逆时针旋转会产生相应的正角。

在极坐标和 (x,y)(称为矩形)坐标之间切换很容易,您可以在我上面给出的 wiki 链接上找到它。

为了确定线段的任何点是否与曲线相交,您可以使用此处给出的直线极坐标方程:http://mathforum.org/dr.math/faq/formulas/faq.polar.html

我们可以使用极坐标范式

R = p sec(ang - omega)

给定线段的两个端点,我们可以计算出p和omega如下:

我们有

p = r1 * cos(ang1-omega) = r2*cos(ang2-omega)

使用cos(x-y) = cos(x)*cos(y) + sin(x)*sin(y) 我们得到

[r1*cos(ang1) - r2*cos(ang2)] * cos(omega) =  [r2*sin(ang2) - r1*sin(ang1)] * sin(omega)

因此,您可以计算tan(omega) = sin(omega)/cos(omega) 并使用arctan(tan 的反函数)得到 omega 的值。一旦你知道什么是 omega,你就可以解出 p。

现在我们需要知道这条线上是否有一些 (R, ang) 组合使得

R <= r
0 <= ang <= theta
min{ang1, ang2} <= ang <= max{ang1, ang2}

(注r为圆锥半径,theta为视角,ang1为P1角度,ang2为P2角度)。

方程可以改写为

Rcos(ang-omega) = p

现在 cos(ang-omega) 在单调性方面是一个表现非常好的函数,您只需要在区间 [min{ang1, ang2}, max{ang1, ang2}] 中考虑它。

您应该能够先进行一些手动操作以简化您的代码。

剩下的交给你。

【讨论】:

  • 谢谢!我想这就是我需要的我会试试这个并很快回来:)
  • @moron..很抱歉,我整个星期都很忙,所以我还没有尝试实施它..但我打算这周去做..我会尽快通知你的。。谢谢! :) 哦,但我有一个问题,所以当只有一半的线段与圆锥相交时,这段代码不起作用。我说对了吗?
  • @nophnoph。我误解了这个问题。你是对的,它只适用于完全交叉(即完全在圆锥内的线段)。
  • @nophnoph:我已经编辑了答案以提供更多可能对您有用的信息。祝你好运!
  • @moron:谢谢你的回答..我明白了,但由于数学对我来说非常难,我很困惑“我们可以在给定两个端点的情况下计算出 p 和 omega线段”。我应该使用哪个方程来找到 p 和 omega?很抱歉问这个简单的问题,但我已经阅读了你给我的链接,但我仍然不明白。谢谢你的帮助:)
【解决方案2】:

我会在谷歌上搜索线/凸多边形相交算法,您的视野由一个三角形和一个圆的一部分组成,可以通过凸多边形以任意精度近似。您的第一步可能仍然有助于排除远未靠近视野的线条。

【讨论】:

    【解决方案3】:

    如果像上面那样保持二维,交点可以计算如下:

    线段的起点是S1,终点是S2。 代码左边缘为沿C1边的向量,右边缘为C2,代码原点为O。

    取(O到S1)和C1形成的向量叉积的Z分量的符号。

    取从(O 到 S2)和 C1 的向量叉积的 Z 分量的符号。如果符号不同,则您的起点和终点位于 C1 的相对两侧,因此它们必须相交。如果不是,请使用 C2 而不是 C1 进行相同的比较。

    如果两边的符号不同,则没有边相交。

    在 3D 中,它有点复杂。我已经用谷歌搜索并多次找到锥形球体交叉点。做线条,会很相似,我只需要考虑一下:)

    “锥形线交叉点”的快速谷歌搜索得到了各种点击。基本思想是从圆锥的原点和直线的起点和终点形成一个平面。一旦你有了它,你可以取那个平面和圆锥方向法线之间的角度。如果该角度小于圆锥上展开的角度,则您有一个交叉点。

    【讨论】:

    • 谢谢!我会试一试..实际上我尝试用谷歌搜索我的问题,但由于我的数学不是很好,我遇到了一些麻烦..:)
    猜你喜欢
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2016-08-08
    • 2011-03-23
    相关资源
    最近更新 更多