Cone-Line Segment Intersection 2D

时间:2010-05-17 16:46:17

标签: c# geometry collision-detection

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

Illustration http://img180.imageshack.us/img180/3461/conevision.png

我正在尝试用C#做,但我不知道该怎么做,所以现在这就是我正在做的事情:

  1. 检查线段是否与圆相交;
  2. 如果线段与圆相交,那么我使用找到here的函数检查线段中的每个点。
  3. 但我不认为这是最好的方法。有没有人有想法?

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

3 个答案:

答案 0 :(得分:2)

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

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

r1 <= r
r2 <= r

ang1 <= theta
ang2 <= theta

其中r是圆锥的半径,theta是视角,你选择轴,使逆时针旋转给出相应的正角。

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

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

我们可以使用Polar普通表格

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}]中考虑它。

您应该首先进行一些手动操作,以简化代码。

我会把剩下的留给你。

答案 1 :(得分:0)

我在谷歌周围寻找线/凸多边形交叉算法,你的视野由一个三角形和一个圆的一部分组成,它可以通过凸多边形逼近任何精度。您的第一步可能仍然有用,可以排除在视野附近无处可寻的线。

答案 2 :(得分:0)

如果你像上面那样保持2D,可以按如下方式计算交点:

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

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

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

如果双方的标志不同,则没有边缘交叉。

在3D中,它有点复杂。我用谷歌搜索并发现锥形球体交叉任意次。对于线条来说,这非常类似,我只需要考虑一下:)

'锥线交叉口'的快速谷歌得到了各种各样的点击。基本思想是从圆锥的原点和直线的起点和终点形成一个平面。一旦你有了这个,你可以采取该平面和锥体方向正常之间的角度。如果该角度小于锥体上的展开角度,则会有一个交点。