4

如果我有一定长度的Catmull-Rom 样条,我如何计算它在一定距离处的位置?通常要计算 catmull rom 样条曲线中的点,您输入一个介于 0 和 1 之间的值以通过比例获取其位置,我该如何计算距离?例如,如果我的样条线长 30 个单位,我如何才能在距离 8 处获得它的位置?

我问的原因是因为似乎在 [0,1] 域中给出点的 catmull rom 样条曲线并不能保证它会给你在样条线的那个距离处的点,例如,如果我将 0.5 输入到 catmull romspline 中长度 30 这并不意味着我会在样条线 15 的距离处获得位置,除非样条线本身实际上是一条直线..

4

3 回答 3

3

通常的方法是存储每个段的长度,然后找出段的部分长度,将 t 增加一个 epsilon 值,并计算 2 个点之间的线性距离,直到你找到答案。显然,您的 epsilon 越小,您获得的结果就越好,但它会产生令人惊讶的好结果。我使用这种方法沿着 catmul-rom 以恒定速度移动,你看不到它加速和减速……它确实以恒定速度移动。显然,取决于您的分段有多紧,您的 epsilon 值需要更改,但一般来说,您可以选择一个“足够好”的 epsilon,一切都会好起来的。

非迭代地找到答案是非常昂贵的(我已经看到了一段时间的推导,它并不漂亮;))。你必须有一个很小的 ​​epsilon 值才能获得更差的性能......

于 2009-10-04T08:52:50.490 回答
3

另一个链接: Anti-Grain Geometry 库中 Bezier Curves 的自适应细分
主要是关于使用宽画笔在像素网格上绘制 Bezier 曲线的不同问题,但请看最后。
(已添加:) Antigrain 还有一个可爱的示例/bspline.cpp,您可以在其中移动结并改变中间点的数量。

于 2009-10-07T15:08:35.283 回答
1

Goz 的回答是准确的 - 这是关于 Bezier 曲线长度的相关讨论。海报的总结是,与计算确切答案相比,进行近似计算更少(而且更简单)。这是适用的,因为您可以更改参数样条曲线的基础,因此您可以将 Catmull-Rom 曲线转换为 Bezier 线段。

为了近似,您基本上是将其分解为具有简单分析长度的基元,然后将所有简单长度相加。虽然大多数人使用线段,但您确实倾向于收缩。您可以通过使用小段来最小化误差,但您的近似值将始终小于非线性曲线的真实长度。

如果您需要更高的准确性,jgt 有一篇论文讨论了如何使用圆作为近似原语,这显然更快/更准确,但实现起来并不难。它们包括一个示例 C 实现。

于 2009-10-07T17:47:41.280 回答