二维圆锥与线段的相交问题

3

我想知道是否有办法确定圆锥体是否与一条(有限的)线段相交。该圆锥实际上是位于P(x,y)处,具有θ度视野和半径r的圆:

Illustration

我正在尝试用C#完成这个任务,但是我不知道该怎么做,所以目前我的做法是:

  1. 检查线段是否与圆相交;
  2. 如果线段与圆相交,则使用一个我在这里找到的函数检查线段中的每个点。

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

另外,我需要这个函数来制作一种简单的视觉模拟器。


@dtb:感谢您帮助我插入图片 :) - nophnoph
3个回答

2
使用极坐标可能会有所帮助。在这里,您不是将点表示为(x,y),而是表示为(r,角度),其中r是距离原点的距离,角度是与所选轴(对应于角度0)成的角度。
在您的情况下,如果将P(x,y)设置为原点,并将锥体的一个射线作为角度= 0,则找到线段端点的极坐标,例如(r1,ang1)和(r2,ang2),则需要满足以下四个条件,才能使该线段完全位于(包括边界)锥体内。
r1 <= r
r2 <= r

ang1 <= theta
ang2 <= theta

其中,r是圆锥的半径,theta是视角的角度,并且您选择了轴,使得逆时针旋转会得到相应的正角度。
在极坐标和直角坐标(x,y)之间切换很容易,在我上面提供的维基链接中可以找到它。
为了确定线段的任何点是否与曲线相交,您可以使用这里给出的极坐标线的极坐标方程:Link 我们可以使用极坐标法线形式。
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}]内考虑它。
你应该先进行一些手动操作,以简化你的代码。
剩下的部分就交给你了。

0

我会在谷歌上搜索线段/凸多边形相交算法,因为你的视野由一个三角形和一个可以通过凸多边形以任何精度逼近的圆形部分组成。你的第一步可能仍然有用,可以排除与视野毫无关系的线段。


0

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

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

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

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

如果两侧的符号都相同,则没有边缘相交。

在3D中,情况会更加复杂。我已经搜索了许多次圆锥体相交。对于线条,做法非常相似,我只需要再考虑一下:)

快速谷歌搜索“圆锥线相交”可以得到各种结果。基本思路是从圆锥的起点和终点形成一个平面。一旦你有了这个平面,就可以计算出该平面与圆锥方向法线之间的夹角。如果该角度小于圆锥张角,则表示它们相交。

谢谢!我会试一试的。 实际上,我已经尝试过在谷歌上搜索我的问题,但由于我的数学不是很好,所以遇到了一些困难.. :) - nophnoph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接