【问题标题】:How to find the intersection point of a 3D curve and a 3D surface?如何找到 3D 曲线和 3D 曲面的交点?
【发布时间】:2015-12-28 02:21:47
【问题描述】:

我试图找到曲线和 3D 表面的交点,但没有运气。曲面为圆锥形,曲线为双曲线,如图所示。 CONE AND THE CURVE

这模拟了光线照射到某个表面。我尝试使用二分法,但它似乎不起作用。然后我尝试了牛顿的算法,但结果仍然不好。

还有其他适合解决这类问题的好的算法吗?

【问题讨论】:

  • 我真的不明白:你有两条曲线在 3D 空间中相交吗?您是否知道曲线在 3D 中几乎肯定不会相交,如果它们是随机定位的?或者你需要将一些双曲曲线与一个圆锥曲面相交?
  • @stgatilov,我只使用一条曲线与曲面相交,我已经知道曲线和曲面的功能。我想做的是找到交点,仅此而已。只是一个寻根问题。在 2D 中,二分法非常有用且简单。但在 3D 中,我认为二分法不再有效(由于函数的复杂性)。
  • 您可能想查看区间牛顿法 - 请参阅 wikipedia - interval arithmetic。我没有自己尝试过这个,但它似乎基本上是基本牛顿方法的一个强大而可靠的版本 - 能够保证找到所有根 IIRC,即使存在浮点舍入错误,这通常是“数学上正确”的方法在实践中失败的原因。
  • 什么叫双曲线?你的意思是双曲线吗?如果是,这是一条平面曲线,您可以将问题重铸为 2D 中两个圆锥曲线的交点。您的绘图甚至似乎表明曲线属于圆锥!
  • @stgatilov 谢谢

标签: algorithm computational-geometry intersection numerical-methods


【解决方案1】:

以参数形式给出的曲线

x = fx(t)
y = fy(t)
z = fz(t)

和曲面通过一个方程的形式

g(x,y,z) = 0

只需插入曲线函数,二等分就可以工作:

g(fx(t), fy(t), fz(t)) = 0

唯一的问题是找到合适的起点 t1 和 t2,其中 g 符号相反。

【讨论】:

  • 谢谢。还有一个问题,如果我的轮廓也是参数形式(不能写成 g(x,y,z) = 0)怎么办?
  • 不能用那种形式表达吗?例如一个圆锥是x^2 + y^2 - z = 0
  • 嗯,是斜锥,所以~~~~~
  • 所以我不知道怎么写。我试图找到 g(x,y,z) 形式,但仍然没有运气。谢谢
  • @Henry:我认为z 在圆锥方程中也必须平方。
【解决方案2】:

问题

您正在搜索曲线-曲面相交算法。请注意,曲线和曲面都可以以 implicit 形式或 parametric 形式表示。隐式形式的表面由方程 F(x, y, z) = 0 定义,它是 x, y 的二次多项式, z 在圆锥曲面的情况下。参数形式的曲面由其参数的点值函数 S(u, v) 定义(例如,您可以使用沿锥轴的距离和极角作为锥面的参数)。曲线通常仅以参数形式描述,作为带有参数 t 的函数 C(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 可能希望从它们中运行牛顿迭代,以使交点精确。

这里是一个示例算法的概要:

  1. 从单个曲线段(整个输入曲线)和单个曲面开始 一块(整个表面),以及这些块的一个潜在相交对 (PIP)。
  2. 将每个曲线段细分为两半(按参数),将每个曲面段细分为四个象限(按两个参数)。
  3. 对于每个旧 PIP,检查所有 8 对半曲线与曲面象限。如果它们确实不相交,请忘记它们。如果它们可以相交,请将它们另存为新的 PIP。
  4. 除非所有片段都足够小,否则从第 2 步开始重复使用新片段和 PIP-s。

对于每一对曲线段和曲面段,您必须检查它们是否可能相交,这可以通过检查它们的轴对齐边界框来轻松完成。此外,您可以将曲线和曲面表示为 NURBS,在这种情况下,您可以使用凸包作为更紧密的边界体积。

一般来说,这种算法有很多变化和改进。我建议您阅读以下文献以获得更深入的知识:

  • 用于计算机辅助设计和制造的形状查询。
    1. chapter 4:用于根求解器
    2. section 5.7: 用于曲面相交
  • PhD of Michael Hohmeyer
    1. 第 4.5 节:曲线与曲面相交
    2. 第 4.1 和 4.2 节:用于凸包相交(如果你足够勇敢的话)。

底线

如果您正在寻找一个简单且可行的解决方案,并且您确定双曲线和圆锥是您唯一需要担心的事情,那么您最好使用圆锥的隐式定义并使用一些标准数值求解四次方程算法来自一个可供您使用的好库。

【讨论】:

  • 非常感谢,我的锥体是斜锥体,所以我把它写成参数化的,这就是为什么我觉得二分法在这里有点难用。
  • @user49114:我相信任何斜圆锥都是普通的椭圆锥。此外,您可以直接将其写为二次隐式曲面。想象它位于原点的顶点,基平面平行于Oxy平面,基圆的中心点为P0 = (x0, y0, z0),半径为r。表示t = z/z0,那么方程应该是(x - x0*t)^2 + (y - y0*t)^2 = (r * t)^2,显然是x,y,z的二次方。
猜你喜欢
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多