如果我有一定长度的Catmull-Rom spline,我如何计算其在一定距离的位置?通常,要计算catmull rom样条曲线中的点,您输入一个介于0和1之间的值以通过比例获取其位置,我该如何对距离进行此操作?例如,如果我的样条曲线长度为30个单位,我怎样才能在距离8处获得它的位置?
我问的原因是因为似乎catmull rom样条曲线在[0,1]域中给出点并不能保证它会给你那个距离进入样条曲线的点,例如如果我输入0.5到a长度为30的catmull romspline并不意味着我将在样条曲线的15处获得位置,除非样条本身实际上是一条直线。
答案 0 :(得分:3)
通常的方法是存储每个段的长度,然后找出一个段的部分长度,你用ε值增加t并计算2个点之间的线性距离,直到你找到答案。显然,你的epsilon越小,你获得的结果越好,但它会给出惊人的好结果。我用这种方法沿着catmul-rom以恒定的速度移动,你看不到它加速和减速......它以恒定的速度移动。显然,取决于你的细分市场有多紧,你的epsilon值需要改变,但一般来说,你可以选择一个“足够好”的epsilon,一切都会好的。
非迭代地找到答案是非常昂贵的(我已经看到了一段时间的推导并且它并不漂亮;))。你将不得不有一个微小的epsilon值来改善性能......
答案 1 :(得分:3)
另一个链接:
Anti-Grain Geometry库中的Adaptive Subdivision of Bezier Curves
主要是在像素网格上绘制贝塞尔曲线的不同问题
用宽刷子,但看到最后
(补充:) Antigrain还有一个可爱的例子/ bspline.cpp
你可以移动结并改变中间点的数量。
答案 2 :(得分:1)
Goz的答案是准确的 - 这是related discussion about length of Bezier curves。海报的总结是,与计算确切答案相比,进行近似计算(并且更简单)更少。这是适用的,因为您可以更改参数样条曲线的基础,因此您可以将Catmull-Rom曲线转换为贝塞尔曲线段。
对于近似,你基本上将它分解为具有简单分析长度的基元,然后将所有简单长度相加。虽然大多数人使用线段,但您确实会收缩。您可以通过使用小段来最小化误差,但是近似值总是小于非线性曲线的真实长度。
如果你需要更高的精度,那么paper from jgt会讨论如何使用圆作为近似基元,这显然更快/更准确,但实现起来并不困难。它们包括一个示例C实现。