【问题标题】:Is there a Java library with 3D spline functions?是否有具有 3D 样条函数的 Java 库?
【发布时间】:2009-06-02 14:27:45
【问题描述】:

特别是,我需要一种方法来表示通过一组已知 3D 点的曲线/样条曲线,以及通过细分/插值找到曲线/样条曲线上其他点的方法。

例如,如果我有一组点 P0 到 PN,我想在穿过 P0 和 P1 的样条曲线上找到 P0 和 P1 之间的 100 个点。

我看到 Java3D 的 KBRotPosScaleSplinePathInterpolator 执行了这样的计算,但它与该 API 的场景图模型相关联,我不知道如何返回我需要的值。

【问题讨论】:

    标签: java math 3d


    【解决方案1】:

    您正在寻找类似Catmull Rom spline 的内容。现实情况是数学不是all that hard to deal with(一些向量矩阵乘法)。我的建议是您只需在代码中实现您真正需要的样条。

    Quoting from that article:

    定义样条的点是 称为“控制点”。中的一个 Catmull-Rom 样条的特点是 指定的曲线将通过 通过所有控制点 - 并非所有类型的 样条。

    要计算曲线上的一个点,需要两个 所需两侧的点 点是必需的,如图所示 左。该点由 a 指定 值 t 表示的部分 两个最近的距离 控制点。

    不过,您应该知道,如果 Catmull-Rom 样条曲线在需要急转弯时靠得太近,可能会导致控制点出现小循环。

    查看上图,想象 p1 和 p3 紧挨着,在 p2 下方(基本上是压缩图片的右侧)。 Catmull-Rom 样条很可能会从 p0 下降,像现在一样通过 p1,从 p2 的右侧上升并从右到左穿过它,从左侧下降并从左到右穿过p3.

    这是样条构造的结果。

    这有点像使用相当硬的柔性管道(就像我在水槽下面一样)。为了让一个较长的部分连接到靠近在一起的点,我必须添加一个循环。

    【讨论】:

      【解决方案2】:

      对于任何在曲线背后苦苦挣扎的人,您可能会发现this 很有用,尤其是下面的图片。这个想法很简单:

      t 从 0.0 循环到 1.0。

      对于 grey 集中的每一对点,计算它们之间距离的一小部分(使用 t)。这些点以绿色显示。

      对于 green 集合中的每一对点,计算它们之间距离的一小部分(使用 t)。该点以黑色显示。

      对于不同的t值,黑点将是一条不同的曲线。

      第二张图片显示了相同的过程,重复了一个额外的点和一个额外的插值级别。

      我发现这比我发现的任何其他选项更容易理解、实现和扩展到 3 维。

      approximating a curve using linear interpolation http://bimixual.org/AnimationLibrary/Bezier_2_big.gif approximating a curve using linear interpolation http://bimixual.org/AnimationLibrary/Bezier_3_big.gif

      【讨论】:

      • 是的,这称为贝塞尔样条。如果/当您需要一条从 P0 穿过 P1、P2 然后也到达 P3 的曲线时,就会出现此样条曲线的问题。如您所见,P1 和 P2 是 Bezier 样条的控制点,但曲线从不接触它们。 Catmull-Rom 样条与此类似,只是 穿过任何控制点。
      • 链接已断开,图像也消失了,截至今天。
      【解决方案3】:

      我对线性插值有很好的理解,但我发现很难掌握样条曲线数学的复杂性。这就是为什么我一直在寻找某种可以提供抽象来隐藏困难数学的库。事实证明,以下功能足以满足我的需求。这是基于在http://www.mvps.org/directx/articles/catmull/ 找到的等式,但幸运的是,您不需要了解它是如何工作的。请记住,与只需要两个点开始的线性插值不同,Catmull-Rom 样条插值在任一端使用一个额外的点。所以如果你想要一条通过 10 个点的样条线,你需要 12 个。

      此函数演示了一维的 Catmull-Rom 样条插值。 (对于 2 或 3 维,只需使用 Y 或 Z 值重复。)此函数将在 p1 和 p2 之间的样条曲线上为我们提供一个点,其中 t 是两者之间距离的比例。

      public class SplineTest {
      
          // Catmull-Rom spline interpolation function
          public static double q(double t, double p0, double p1, double p2, double p3) {
      
              return 0.5 * ((2 * p1) + (-p0 + p2) * t
                      + (2 * p0 - 5 * p1 + 4 * p2 - p3) * (t * t) + (-p0 + 3 * p1 - 3
                      * p2 + p3)
                      * (t * t * t));
          }
      
          public static void main(String[] args) {
              double t = 0.0;
              while (t <= 1.0) {
                  System.out.println(q(t, 5, 10, 20, 10));
                  t += 0.1;
              }
          }
      }
      

      这个程序输出:

      10.0
      10.887500000000001
      12.0
      13.2625
      14.6
      15.9375
      17.2
      18.3125
      19.2
      19.7875
      20.000000000000004
      

      【讨论】:

      • 谷歌搜索了几个小时,终于找到了这样一个简单的公式。我可以验证它在 3D 中非常适合我。
      【解决方案4】:

      据我所知,没有内置库。 Source

      【讨论】:

      【解决方案5】:
      【解决方案6】:

      我还没有尝试过,但很可能很快就会尝试使用随机点输入生成 3d 表面网格:toxiclib as a Spline3d tool

      http://code.google.com/p/toxiclibs

      【讨论】:

        【解决方案7】:

        我刚刚尝试了 libGDX,Apache 许可证 http://github.com/libgtx/libgtx

        它包含一个 BSpline 类,易于使用。

        https://github.com/Graphics3D/ect/blob/master/src/main/java/courbes_bsplines/TestGDXBSpline.java

        【讨论】:

          猜你喜欢
          • 2010-11-08
          • 1970-01-01
          • 2019-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-22
          相关资源
          最近更新 更多