代码之家  ›  专栏  ›  技术社区  ›  Liam

是否有具有三维样条函数的Java库?

  •  2
  • Liam  · 技术社区  · 17 年前

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

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

    我看到Java3D的kbrotoposscalesplinepathinterpolator执行这样的计算,但它与API的scenegraph模型相关联,我不知道如何返回所需的值。

    7 回复  |  直到 17 年前
        1
  •  4
  •   Community Mohan Dere    9 年前

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

    Quoting from that article :

    被称为“控制点”。其中一个 指定的曲线将通过 并非所有类型的问题都是如此 样条曲线。

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

    要计算曲线上的点,请使用两个 点是必需的,如图所示 左边该点由 值t,表示 两个最近点之间的距离

    不过,您应该注意,如果Catmull Rom样条曲线在需要急转弯时靠得太近,它们可能会在控制点处导致小循环。

    看上图,想象p1和p3紧挨着,在p2下方(基本上压缩图片的右侧)。Catmull Rom样条曲线很可能从p0向下,像现在一样通过p1,沿着p2的右侧,从右到左穿过p2,从左手侧向下,从左到右穿过p3。

    这是样条曲线构造的结果。

        2
  •  3
  •   Liam    17 年前

    对于任何一个在曲线背后挣扎数学的人来说,你可能会发现 this

    允许 T 从0.0循环到1.0。

    对于中的每对点 灰色 绿色 .

    对于中的每对点 绿色 设置,计算一个点,它们之间的一小部分(使用t)。这一点如图所示 黑色 .

    T

    第二幅图像显示了重复的相同过程,其中包含一个额外的点和一个额外的插值级别。

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

    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

        3
  •  3
  •   Liam    16 年前

    http://www.mvps.org/directx/articles/catmull/ ,但幸运的是,您不需要了解它是如何工作的。请记住,与线性插值不同,线性插值只需要两个点,Catmull Rom样条曲线插值在两端使用一个额外的点。所以如果你想要一条穿过10个点的样条曲线,你需要12个。

    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
    
        4
  •  1
  •   Andrei Krotkov    17 年前

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

    推荐文章