Cardinal样条曲线的Javascript实现(理论篇)
首先,要对样条曲线进行插值的原因是:希望通过给定的关键帧点生成一条希望的直线或者曲线。
1.直线插值
生成一条直线,给定直线首尾的关键点P0,P1,就能确定这条直线的特性,比如y=kx+b中的斜率k和y轴偏移值b。通过线性(P0,P1线性相关)插值(线性的给中间插上一定数量的点使看起来连续)的方式就可以得到我们要的线段。
图1.1
2.曲线插值
但是对于曲线来说比较难确定,我们要对于给定的参数生成唯一的一条曲线并且可以进行方便的调整。这里要确定每一小段曲线,我们需要4个参数,首尾点的位置(参数化后的P(u))及他们的方向(在代数上表现为一阶导数P'(u)的值),并进行平滑的过渡,通过插值来实现对中间点的计算。再将每个小段的曲线进行连接。
图2.1
曲线的生成分为两个部分:
1)对每给定的两个关键帧点之间进行插值得到一段曲线(如图2.1)
2)连接两两关键帧点的曲线段(如图2.2对曲线段进行连接)
图2.2
2.1 三次多项式插值
先就两个关键帧点之间的插值做计算。我的理解主要的思想是通过一个参数化的函数曲线去拟合,因此要通过给定的条件(如图2.1中的P(0),P(1),P'(0),P'(1))去确定这个函数的几个系数。然后通过在中间等间距的插点计算根据函数得到的值确定点的位置。这里选择参数化的三次多项式()去拟合这条曲线,通过插值来求得中间点的位置。这里,选择三次多项式的原因是:灵活性和计算速度的折中方案。
1)与更高次多项式相比,三次样条只需较少的计算与存储空间,并且较为稳定;(只需要一个4*4的基函数矩阵)
2)与更低次多项式相比,三次样条在模拟任何曲线形状时显得更灵活。(能满足大多数情况下的曲率调整,比如二次抛物线太对称,一次就是直线)
2.2 曲线连续性
为了保证分段参数曲线从一段到另一端平滑过渡,可以在连接点处要求各种连续性(可以参考微积分中的函数连续性与导数的关系)。
C0连续:有相同的公共点,如图(a)
C1连续:有相同的公共点且公共点处有相同的一阶导数(切线斜率),如图(b)
C2连续:有相同的公共点且有相同的公共点且公共点处有相同的一阶导数和二阶导数(切线斜率的变化率),如图(c)
图2.3
2.3 自然样条曲线
一种简单的插值方法是自然样条插值,就是对如图2.2的一条有n+1个控制点(P0~Pn)n个分段的曲线求三次多项式系数这样就有4n个系数要确定(需要列出4n个方程才能求解出来),通过曲线内部的n-1个点每相邻曲线段公共点的一阶及二阶导数相等且都通过该点,能确定4n-4 [4*(n-1)]个方程,再加上两个“隐含”控制点P0和Pn的二阶导数为0得到4n个方程来求解。缺点是一个点发生了变化其他点都跟着受到影响,这里不做主要展开了。
2.4 Hermite插值
为了解决自然样条曲线不能局部控制的缺点,Hermite插值对每个控制点的切线进行了限制为D(由用户给出),这样切线就变成了D*Pk(D斜率+经过该点),使每个曲线段仅依赖于端点位置的约束。如对每小段曲线的边界条件表示为:
-------公式1
这里P是向量,对于xy分量来说分别都符合这个边界条件。那么如何保证曲线连续的呢?即对于一个连接点Pk-1来说,这段曲线相应的终点为Pk,在下一段曲线里Pk则作为这段曲线的起始点,保证Pk这个点的函数值和导数值相等就可以。现在点的位置都是Pk,导数值都是DPk,二阶导数值都是D。
可以写出向量方程:
其中P和abcd都是向量,可以再xy分量上(2维情况下)分别表达成这种形式,如,y分量也是类似,组合成的表达,可以获得等价的矩阵形式表达:
以及导数的矩阵表达式:
通过公式1,用u=0和u=1替代上面的u就可以得到以下方程:
如Pk=P(0)=[0 0 0 1]*[a b c d]',这里每一个曲线段上的点都被参数化到0~1之间,所以起始点就是P(0),终止点就是P(1),利用线代方法(参考线性方程求解)通过4个参数对多项式系数求解
最后边界条件的表达式如下
其中M*P部分就是通过对Hermite函数推导得到的系数矩阵[a b c d]',Pk和Pk+1由用户给定,DPk和DPk+1由给定D值计算获得,根据不同的控制方式可以生成有不同曲线,Cardinal曲线就是Hermite曲线的一种变形,通过对切线斜率进行控制来控制曲线的平滑度。
2.5 Cardinal样条曲线
因为在Hermite曲线中斜率D还是需要用户给出,Cardinal样条曲线可以由相邻两控制点坐标来计算斜率从而使曲线完全由控制点Pk来决定,但是在这里引入了一个t作为在每个公共点上尖锐程度的控制值。
Cardinal曲线的边界条件方程:
这样控制点Pk和Pk+1处的斜率和弦PkPk+2和PkPk+1成正比(理解为表示比较接近的控制点对曲线曲率的影响)
其中t(称为张量)控制Cardinal样条和输入控制点之间的松紧程度,对曲线的影响程度可以通过下图看出来
通过跟Hermite类似的系数求解方式,将边界条件代入可以得到矩阵表达式:
P(u)
,其中
Cardinal样条曲线的Javascript实现(理论篇)的更多相关文章
- Cardinal样条曲线的Javascript实现(代码篇)
由上一篇文章得到了Cardinal曲线的矩阵表达式,下面就这个矩阵表达式就可以来对曲线进行插值了. 这里选用了JS来实现,完全是因为之前交作业的时候还不知道怎么在Xcode里建完整的C++OpenGL ...
- 曲线参数化的Javascript实现(理论篇)
在关键帧动画的制作过程中,动画师在k物体运动的过程中,一般要确定2个参数: 1)运动轨迹(表示物体运动的路径): 2)速度曲线(表示物体随时间的速度变化). 对于运动轨迹通常选用一定的样条曲线,通过动 ...
- Javascript设计模式理论与实战:工厂方法模式
本文从简单工厂模式的缺点说起,引入工厂方法模式,介绍的工厂方法模式的基本知识,实现要点和应用场景,最后举例进行说明工厂方法模式的应用.在之前的<Javascript设计模式理论与实战:简单工厂模 ...
- 如何编写高质量的 JS 函数(3) --函数式编程[理论篇]
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/EWSqZuujHIRyx8Eb2SSidQ作者:杨昆 [编写高质量函数系列]中, <如何 ...
- PHP丨PHP基础知识之流程控制WHILE循环「理论篇」
昨天讲完FOR循环今天来讲讲他的兄弟WHILE循环!进入正题: while是计算机的一种基本循环模式.当满足条件时进入循环,进入循环后,当条件不满足时,跳出循环.while语句的一般表达式为:whil ...
- PHP丨PHP基础知识之条件语IF判断「理论篇」
if语句是指编程语言(包括c语言.C#.VB.java.php.汇编语言等)中用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一. if语句概述 if语句是指编程语言(包 ...
- Javascript本质第二篇:执行上下文
在上一篇文章<Javascript本质第一篇:核心概念>中,对Javascript执行上下文做了解释,但是这些都是基于Javascript标准中对执行上下文的定义,也就是说理论上的东西,本 ...
- RabbitMQ学习总结 第一篇:理论篇
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- 【PHPsocket编程专题(理论篇)】初步理解TCP/IP、Http、Socket.md
前言 我们平时说的最多的socket是什么呢,实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API).那TCP/IP又是什么呢?TCP/IP是ISO/OS ...
随机推荐
- Discuz论坛安全加固浅析
[51CTO专稿]Discuz! 论坛以其功能完善.效率高效.负载能力,深受被大多数的网站喜爱和青睐.无独有隅,笔者所维护的论坛就是用discuz! 来构建的,从接手时候的7.2到现在x2.0,经历了 ...
- WDA导出文件XLS,WORD
METHOD ONACTIONEXCEL . DATA: LO_NODE TYPE REF TO IF_WD_CONTEXT_NODE, "Node LO_ELEM TYPE REF TO ...
- gulp教程之gulp-rev-append
简介: 使用gulp-rev-append给页面的引用添加版本号,清除页面引用缓存. 1.安装nodejs/全局安装gulp/项目安装gulp/创建package.json和gulpfile.js文件 ...
- 读javascript高级程序设计00-目录
javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...
- Java开发工具安装步骤内容如下
Java开发工具安装步骤内容如下 安装 开发工具 STS 链接下载网址 eclipse 链接下载网址 JDK安装 jdk链接下载地址 Marven环境 marven链接下载地址 Tomcat tomc ...
- React Native 获取网络数据
getMoviesFromApiAsync() { return fetch('http://facebook.github.io/react-native/movies.json') .then(( ...
- 360浏览器兼容模式默认显示ie最高版本
之前写完代码都会放在360浏览器里跑一边,基本没啥问题,因为设置的都是极速模式,极速模式内置的是webkit内核,后来测试人员测试了兼容模式,发现会出各种问题,打开控制台一看,“我的天呐”,默认的竟然 ...
- node.js+socket.io安装
最近做安卓遇到一个网络包的bug,服务端使用node做的,通讯用socket.io,但是服务端没法调试,没办法,还是自己搭建一个服务器端吧,索性买了阿里云的ecs测试,之前也配置过node+socke ...
- AppFog免费云空间申请及安装wordpress(图文教程)
AppFog是一家提供运算平台的服务,用户可以在上面搭建自己的Web App.原本它的名字为PHPFog,但在采用了Cloud Foundry的代码作为核心,支持多个编程语言后,选择了更名.AppFo ...
- Flapper Bird的学习笔记(一)
因为我有一个超屌的梦想,所以就绝不做孬种的追梦人! 本文主要目的是为了实现Flapper Bird的功能. 另外一个目的是为了加强对Unity引擎的理解和掌握. 新人一枚,如若看到是我幸运.若是发现错 ...