曲线参数化的Javascript实现(理论篇)
2014-01-30 00:11
323 查看
在关键帧动画的制作过程中,动画师在k物体运动的过程中,一般要确定2个参数:
1)运动轨迹(表示物体运动的路径);
2)速度曲线(表示物体随时间的速度变化)。
对于运动轨迹通常选用一定的样条曲线,通过动画师给出关键点位置,通过曲线插值产生,如之前介绍的一种Cardinal样条曲线。速度曲线就是速度根据时间变化的曲线,速度曲线在一段时间上的积分累加就是运动过的路程(不是位移)。对于简单的运动类型如匀速直线运动(速度曲线是一个常数),匀加速直线运动(速度曲线是一条加速度为斜率的直线方程)都可以直接获得路程随时间变化的方程,从而得到每个时间点在曲线上通过的路径长度。因此就需要在样条曲线上根据运动过的路径的长度来确定物体在曲线上的位置(由坐标(u, P(u))表示),这个过程就是曲线的参数化。
如果速度曲线为V(t),对应的路程曲线为s=A(t),对于给定的一段路程s,需要在Q(u)上找到对应的u点,设样条曲线函数为Q(u),上面的弧长函数为s=A(u),,那么参数化的过程就是把弧长函数表达成反函数的形式
![](http://images.cnitblog.com/blog/555666/201401/291309457501565.png)
,然后代人Q(u),就可以得到一个根据弧长算出曲线上函数值的方程
![](http://images.cnitblog.com/blog/555666/201401/291312567349450.png)
。
弧长函数s=A(u)是路程在u上的积分方程,所以没有解析解(所谓解析解就是通过一个求根方程直接表达成自变量u根据方程的根,如二次函数的求根方程
![](http://images.cnitblog.com/blog/555666/201401/291317529067201.png)
),因此采取数值求解的方法。求解的过程分为两步:
1)计算弧长函数s=A(u)
2)对给定的弧长s,通过二分查找法在A(u)中计算u的值
1.弧长函数s=A(u)的计算
弧长函数就是一个曲线积分的问题,就二维图像来说,如图:
![](http://images.cnitblog.com/blog/555666/201401/300008305787740.png)
在方程Q(u)~Q(u+du)上面每一段
![](http://images.cnitblog.com/blog/555666/201401/292352422661288.png)
,对s进行积分,则
![](http://images.cnitblog.com/blog/555666/201401/292353372818047.png)
其中,
![](http://images.cnitblog.com/blog/555666/201401/292355491091606.png)
因为上述积分函数并非解析可积,一般采用数值积分技术求解,简单的采用扩展是Simpson方法(在以后篇中介绍),则
![](http://images.cnitblog.com/blog/555666/201401/292356396095911.png)
这里的每个f(u)就是我们的样条函数Q(u),一般高阶系数就直接忽略了,对于一段积分s就可以用u值和展开式计算s的值。
2.二分查找
因为弧长函数是严格的单调递增函数(路径长度的累加),那么如图
![](http://images.cnitblog.com/blog/555666/201401/300006590788493.png)
(1)如果S3<Sa, 则u3<ua (红点),
搜索区间更新成[u3,u2].
(2)如果S3>Sa, 则u3>ua (蓝点),
搜索间更新成[u1,u3].
重复上述递归过程,直到||A(u1)-A(u2)||<指定精度ε,就把u1当作匹配的u值
这样我们就得到了每个s值对应的u值。另外,因为对于每一段曲线的弧长函数不同,连接起来的曲线可以用一个弧长表来纪录,如纪录下第一段曲线的总弧长,在第二段曲线上就在第一段曲线的基础上加上去,查找的方法也可以减小计算的时间复杂度,方便二分查找。
1)运动轨迹(表示物体运动的路径);
2)速度曲线(表示物体随时间的速度变化)。
对于运动轨迹通常选用一定的样条曲线,通过动画师给出关键点位置,通过曲线插值产生,如之前介绍的一种Cardinal样条曲线。速度曲线就是速度根据时间变化的曲线,速度曲线在一段时间上的积分累加就是运动过的路程(不是位移)。对于简单的运动类型如匀速直线运动(速度曲线是一个常数),匀加速直线运动(速度曲线是一条加速度为斜率的直线方程)都可以直接获得路程随时间变化的方程,从而得到每个时间点在曲线上通过的路径长度。因此就需要在样条曲线上根据运动过的路径的长度来确定物体在曲线上的位置(由坐标(u, P(u))表示),这个过程就是曲线的参数化。
如果速度曲线为V(t),对应的路程曲线为s=A(t),对于给定的一段路程s,需要在Q(u)上找到对应的u点,设样条曲线函数为Q(u),上面的弧长函数为s=A(u),,那么参数化的过程就是把弧长函数表达成反函数的形式
![](http://images.cnitblog.com/blog/555666/201401/291309457501565.png)
,然后代人Q(u),就可以得到一个根据弧长算出曲线上函数值的方程
![](http://images.cnitblog.com/blog/555666/201401/291312567349450.png)
。
弧长函数s=A(u)是路程在u上的积分方程,所以没有解析解(所谓解析解就是通过一个求根方程直接表达成自变量u根据方程的根,如二次函数的求根方程
![](http://images.cnitblog.com/blog/555666/201401/291317529067201.png)
),因此采取数值求解的方法。求解的过程分为两步:
1)计算弧长函数s=A(u)
2)对给定的弧长s,通过二分查找法在A(u)中计算u的值
1.弧长函数s=A(u)的计算
弧长函数就是一个曲线积分的问题,就二维图像来说,如图:
![](http://images.cnitblog.com/blog/555666/201401/300008305787740.png)
在方程Q(u)~Q(u+du)上面每一段
![](http://images.cnitblog.com/blog/555666/201401/292352422661288.png)
,对s进行积分,则
![](http://images.cnitblog.com/blog/555666/201401/292353372818047.png)
其中,
![](http://images.cnitblog.com/blog/555666/201401/292355491091606.png)
因为上述积分函数并非解析可积,一般采用数值积分技术求解,简单的采用扩展是Simpson方法(在以后篇中介绍),则
![](http://images.cnitblog.com/blog/555666/201401/292356396095911.png)
这里的每个f(u)就是我们的样条函数Q(u),一般高阶系数就直接忽略了,对于一段积分s就可以用u值和展开式计算s的值。
2.二分查找
因为弧长函数是严格的单调递增函数(路径长度的累加),那么如图
![](http://images.cnitblog.com/blog/555666/201401/300006590788493.png)
(1)如果S3<Sa, 则u3<ua (红点),
搜索区间更新成[u3,u2].
(2)如果S3>Sa, 则u3>ua (蓝点),
搜索间更新成[u1,u3].
重复上述递归过程,直到||A(u1)-A(u2)||<指定精度ε,就把u1当作匹配的u值
这样我们就得到了每个s值对应的u值。另外,因为对于每一段曲线的弧长函数不同,连接起来的曲线可以用一个弧长表来纪录,如纪录下第一段曲线的总弧长,在第二段曲线上就在第一段曲线的基础上加上去,查找的方法也可以减小计算的时间复杂度,方便二分查找。
相关文章推荐
- 曲线参数化的Javascript实现(代码篇)
- Atitit. servlet 与 IHttpHandler ashx listen 和HttpModule的区别与联系 原理理论 架构设计 实现机制 java php c#.net js javascript c++ python
- svg中实现文字随曲线走向,HTML直接写和JavaScript创建对象两种方式
- Cardinal样条曲线的Javascript实现(理论篇)
- 原生JavaScript实现连连看游戏(附源码)
- 你知道的javascript的继承有几种实现方式
- javascript如何实现追加或删除表单元素
- JavaScript DOM编程艺术—javascript实现移动元素动画
- JavaScript canvas实现围绕旋转动画
- javascript Ajax 类实现代码
- javascript之对象学习笔记(二)--模拟类实现
- 2014-11-6Android学习------Android画笔实现画曲线--------贝塞尔曲线(二)
- javascript实现多表头分类交叉报表之二:效果图
- JavaScript 实现简单的神经网络算法
- javascript实现的淘宝旅行通用日历组件用法实例
- 30行代码实现JavaScript中的MVC
- 【转】javascript鼠标拉框(框选)的实现
- JavaScript中类的实现
- javascript实现二级级联菜单的简单制作
- Visual C++6.0实现动态曲线4种方法