2009-06-02 87 views
2

特别是,我需要一种方法来表示通过一组已知3D点的曲线/样条曲线,以及通过细分/内插找到曲线/样条曲线上其他点的方法。是否有一个带有3D样条函数的Java库?

例如,如果我有一组点P0到PN,我想找到P0和P1之间的100个点,这些点位于通过P0和P1的样条上。

我看到Java3D的KBRotPosScaleSplinePathInterpolator执行了这样的计算,但它与该API的场景图模型绑定在一起,我看不到如何返回我需要的值。

回答

1

没有我知道的内置库。 Source

+0

事情已经改变,因为:http://code.google.com/p/toxiclibs提供了一个凉爽Spline3d。 – Martin 2012-02-24 15:12:19

4

您正在寻找类似的产品Catmull Rom spline。事实是,数学并不是all that hard to deal with(一些向量 - 矩阵乘法)。我的建议是,你只需要在代码中实现你真正需要的样条线。

Quoting from that article

限定了花键的点 称为 “控制点”。 Catmull-Rom样条的 特征之一是 ,指定曲线将通过所有控制点 - 这不适用于所有类型的 样条。

An illustration of the Catmull-Rom spline passing through all control points.

为了计算曲线上的点,需要所期望的 点的任一侧上的两个点 ,在 如左图所示。该点由 值t指定,该值表示最接近的两个控制点之间的距离的部分 。

但是,您应该意识到,如果Catmull-Rom样条曲线在需要紧急转弯时彼此靠得太近,可能会在控制点导致小回路。

看一下上面的图片,想象一下p1和p3彼此相邻,在p2下面(基本上压缩图片的右侧)。 Catmull-Rom样条可能会从p0中下来,像现在一样通过p1,在p2的右侧向上并从右向左穿过,从左侧穿过并从左向右穿过P3。

这是样条线构造的结果。

这就像是用相当坚硬的软管(就像我在水槽下)一样工作。为了获得连接点相近的长条件,我必须添加一个循环。

3

对于任何与曲线背后的数学拼搏的人,您可能会发现this有用,特别是下面的图片。这个想法很简单:

t循环从0.0到1.0。

对于灰色集合中的每一对点,计算一个点之间的方式的一小部分(使用t)。这些点显示在绿色

对于绿色集合中的每一对点,计算它们之间的一部分路径(使用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

+0

是的,这被称为贝塞尔样条。如果/当您需要一条从P0通过P1,P2,然后也碰到P3的曲线,则此样条的问题就会出现。正如你所看到的,P1和P2是Bezier样条曲线的控制点,但曲线从未触及它们。 Catmull-Rom样条曲线与此类似,不同之处在于*将*通过以前的控制点。 – 2009-08-06 00:45:54

+0

截至今日,链接被破坏,图像也消失。 – Chris 2014-07-24 16:21:53

2

我对线性插值有很好的理解,但是我发现很难掌握样条数学的复杂性。这就是为什么我正在寻找一种能够提供隐藏困难数学的抽象图书馆。以下功能足以满足我的需求。这是基于在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 
相关问题