我在3个空间中有两个环,每个环由法向量,中心坐标和半径表示。 如何确定环是否已链接。即一个圆上的一个点位于另一个圆盘中。
这将在紧密循环中实现,所以我关注性能。我觉得应该有一个封闭的形式解决方案。到目前为止,我只想过迭代解决方案。
任何帮助?
答案 0 :(得分:3)
算法概要:
详细说明:
我假设圆C1和C2由中心点(p1,p2),单位法线轴向量(n1,n2)和半径(r1,r2)给出。
如果某个标量k的n1 == k n2,那么这些平面是平行的或并发的。如果它们是并发的,这就变成了普通的2d问题:检查是否dist(p1,p2)< R1 + R2。
否则,平面在线L处相交。如果圆被链接,则它们必须都与L相交,因为链接意味着它们相互穿过彼此的定义平面。这为您提供了第一次琐碎的拒绝测试。
L由点q和向量v给出。查找v很容易:它只是n1和n2的叉积。 q有点棘手,但我们可以选择最接近线的点
l1(s) = p1 + s (v X n1)
l2(t) = p2 + t (v X n2)
这些线垂直于v,n1和n2,并且位于C1和C2的平面上。他们最接近的点必须在L。
您可以参考this post了解如何找到最近点的点。
最后,圆圈可以相交的唯一方法是它们在L上都有点。如果它们都有,那么考虑C1和L的交点,因为它们与C2有关。如果C1和L有两个交点q11和q12,并且完全其中一个在C2内,则链接起来。由于L在C2的平面上,因此这成为平面圆点测试:
IF dist(p1, q11) < r1 THEN
linked = (dist(p1, q12) > r1)
ELSE
linked = (dist(p1, q11) < r1)
ENDIF
当然这个伪代码对于处理圆圈实际相交的情况有点草率,但应该如何处理它取决于你的应用程序。
答案 1 :(得分:1)
一个相对容易编码的直接解决方案:计算两个平面的交点线并旋转并将所有内容(在我的情况下是定义两个圆的六个点)翻译在一起,以便该线成为Z轴(x = Y = 0)。然后,平面可以围绕Z单独旋转,使得第一个圆C1位于XZ平面上,C2位于YZ平面上。现在中心和半径很容易找到(在我的情况下,我最初没有它们)。这些旋转不会改变链接/无链接属性,并且可以根据具有Z轴的圆的四个交点的顺序容易地确定链接或缺少链接。 (如果其中一个圆不相交x = y = 0,则没有链接。)(我可能会混淆轴,但我认为这样可行。) 谢谢。
答案 2 :(得分:1)
这是3D圆盘交叉问题吗?或者,这是圆圈交叉问题吗?
如果是前者,则有一种快速,封闭的形式算法。首先,清除圆圈太远的情况:dist(CIR1.c, CIR2.c) > CIR1.r + CIR2.r
处理边缘案例:共面圆圈。
将磁盘挤压到其平面,然后将圆与此平面相交。如果有1个或2个交叉点,请测试它们是否符合pointInDisk(p, CIR)
逻辑。报告任何幸存的交叉点。
答案 3 :(得分:0)
计算几何教科书可能有一个很好的解决方案!
但我现在还没有方便的计算几何教科书。如果我现在要根据自己的(非常有限的)直觉推动我自己,我想我会从三维轴对齐的边界框开始。
例如,创建一个“刚好在圆圈内”的边框,以及一个“刚刚在圆圈外”的边界框。我相信弄清楚两个轴对齐的盒子是否重叠是微不足道的(我曾经在二维情况下谈到相关问题的家庭作业第2.1节 - 找到最接近某个点的矩形:http://juliusdavies.ca/uvic/report.html)我怀疑以下断言会成立(但我可能错了):
如果内盒重叠,那么环肯定是连接的。 (我现在认为这是错误的......)
如果外框不重叠,那么它们肯定没有连接---我非常有信心这个断言成立! :-): - )
如果外框重叠,但内框不重叠,则可能会连接它们。
如果我自己动手,那就是我开始的地方。
结论:嗯,我希望你对其他答案有更好的运气。 : - )