我试图找到曲线和3D表面的交点而没有运气。表面呈锥形,曲线呈双曲线,如图所示。 CONE AND THE CURVE
这模拟了光线撞击某个表面。我试图使用二分法,但似乎没有用。然后我尝试了牛顿算法,但结果仍然不好。
还有其他适合解决此类问题的好算法吗?
答案 0 :(得分:1)
以参数形式给出曲线
var arr = new Array();
for (var ta = 1; ta <= 10; ta++) {
arr [ta] = { cta:0,
ccc:0,
crc:0
};
}
arr[6].cta=1;
console.log(arr);
和表面由一个形式的等式
x = fx(t)
y = fy(t)
z = fz(t)
只需插入曲线函数,二分法就可以了:
g(x,y,z) = 0
唯一的问题是找到合适的起点t1和t2,其中g的符号相反。
答案 1 :(得分:0)
您正在搜索曲面交叉算法。请注意,曲线和曲面都可以用隐式形式或参数形式表示。隐式形式的表面由等式 F(x,y,z)= 0 定义,它是 x , y 的二次多项式,在圆锥曲面的情况下 z 。参数形式的曲面由其参数的点值函数 S(u,v)定义(例如,您可以使用沿锥轴的距离和极角作为锥形曲面的参数)。曲线通常仅以参数形式描述,作为函数 C(t),参数 t ,对于双曲线曲线可以是二次曲线。
最简单的情况是将问题视为参数曲线与隐式曲面的交集。在这种情况下,您可以使用单个变量 t 记下单个等式 q(t)= F(C(t))= 0 。当然,牛顿的迭代并不能保证在一般情况下找到所有解,如果找到两个具有不同符号 q(t)的点,则二分法肯定能找到一个解。
在你的情况下, q(t)是一个四次多项式(在将二次曲线参数化放入二次曲面方程之后)。理论上它可以用Ferrari's analytic formula来解决,但我强烈反对它,因为它在数值上非常不稳定。您可以在此处应用任何常用的多项式求解器,例如Jenkins-Traub算法或companion matrix的特征值算法(另请参阅this question)。您还可以使用区间数学方法:例如,您可以递归地将参数 t 的域间隔细分为更小的片段,同时修剪所有肯定不包含零的片段(interval arithmetic会帮你检测这些碎片。)
现在我们可以继续讨论曲线和曲面都是参数化表示的情况。我不知道任何解决方案可以从您的表面是圆锥形并且曲线是双曲线的事实中受益,因此您必须应用一般的曲面交叉算法。或者,您可以将隐式定义的锥体拟合到参数曲面中,然后使用上面的解决方案来处理四次多项式根。
许多可靠的通用交叉算法都是基于细分方法(实际上是间隔数学)。一般的想法是将曲线和曲面连续地分成更小和更小的部分。尽可能地掉落确实不相交的一对件。最后,您将拥有一组小块对,紧密地限制您的交叉点。 Yoy可能希望从它们运行Newton的迭代,以便使交叉点精确。
以下是示例算法的概要:
对于每对曲线片和曲面片,您必须检查它们是否可能相交,这可以通过检查它们的轴对齐边界框来轻松完成。此外,您可以将曲线和曲面表示为NURBS,在这种情况下,您可以使用凸包作为更紧密的边界体积。
通常,此算法有很多变化和改进。我建议以下文献获得更深入的知识:
如果您正在寻找一个简单而有效的解决方案,并且您确信双曲线和锥体是您唯一需要担心的事情,那么您最好使用锥的隐式定义并用一些解决四次方程来自一个好的库的标准数值算法。