Hermite曲线插值
原文 Hermite Curve Interpolation
Hermite Curve Interpolation
Hamburg (Germany), the 30th March 1998. Written by Nils Pipenbrinck aka Submissive/Cubic & $eeN
Introduction
Hermite curves are very easy to calculate but also very powerful. They are used to smoothly interpolate between key-points (like object movement in keyframe animation or camera control). Understanding the mathematical background of hermite curves will help you to understand the entire family of splines. Maybe you have some experience with 3D programming and have already used them without knowing that (the so called kb-splines, curves with control over tension, continuity and bias are just a special form of the hermite curves).
The Math
To keep it simple we first start with some simple stuff. We also only talk about 2-dimensional curves here. If you need a 3D curve just do with the z-coordinate what you do with y or x. Hermite curves work in in any number of dimensions.
To calculate a hermite curve you need the following vectors:
- P1: the startpoint of the curve
- T1: the tangent (e.g. direction and speed) to how the curve leaves the startpoint
- P2: he endpoint of the curve
- T2: the tangent (e.g. direction and speed) to how the curves meets the endpoint

These 4 vectors are simply multiplied with 4 hermite basis functions and added together.
h1(s) = 2s^3 - 3s^2 + 1
h2(s) = -2s^3 + 3s^2
h3(s) = s^3 - 2s^2 + s
h4(s) = s^3 - s^2
Below are the 4 graphs of the 4 functions (from left to right: h1, h2, h3, h4).

(all graphs except the 4th have been plotted from 0,0 to 1,1)
Take a closer look at functions h1 and h2:
- h1 starts at 1 and goes slowly to 0.
- h2 starts at 0 and goes slowly to 1.
Now multiply the startpoint with h1 and the endpoint with h2. Let s go from 0 to 1 to interpolate between start and endpoint. h3 and h4 are applied to the tangents in the same manner. They make sure that the curve bends in the desired direction at the start and endpoint.
The Math in Matrix Form
All this stuff can be expessed with some vector and matrix algebra. I think the matrix-form is much easier to understand.
Vector S: The interpolation-point and it's powers up to 3:
Vector C: The parameters of our hermite curve:
Matrix h: The matrix form of the 4 hermite polynomials: | s^3 | | P1 | | 2 -2 1 1 |
S = | s^2 | C = | P2 | h = | -3 3 -2 -1 |
| s^1 | | T1 | | 0 0 1 0 |
| 1 | | T2 | | 1 0 0 0 |
To calculate a point on the curve you build the Vector S, multiply it with the matrix h and then multiply with C.P = S * h * C
A little side-note: Bezier-Curves
This matrix-form is valid for all cubic polynomial curves. The only thing that changes is the polynomial matrix. For example, if you want to draw a Bezier curve instead of hermites you might use this matrix:
| -1 3 -3 1 |
b = | 3 -6 3 0 |
| -3 3 0 0 |
| 1 0 0 0 |
I wrote a separate page about bezier curves.
Some Pseudocode
Sure, this C-style pseudo-code won't compile. C doesn't come with a power function, and unless you wrote yourself a vector-class any compiler would generate hundreds of errors and make you feel like an idiot. I think it's better to present this code in a more abstract form.
moveto (P1); // move pen to startpoint
for (int t=0; t < steps; t++)
{
float s = (float)t / (float)steps; // scale s to go from 0 to 1
float h1 = 2s^3 - 3s^2 + 1; // calculate basis function 1
float h2 = -2s^3 + 3s^2; // calculate basis function 2
float h3 = s^3 - 2*s^2 + s; // calculate basis function 3
float h4 = s^3 - s^2; // calculate basis function 4
vector p = h1*P1 + // multiply and sum all funtions
h2*P2 + // together to build the interpolated
h3*T1 + // point along the curve.
h4*T2;
lineto (p) // draw to calculated point on the curve
}
Getting rid of the Tangents
I know... controlling the tangents is not easy. It's hard to guess what a curve will look like if you have to define it. Also, to make a sharply bending curve you have to drag the tangent-points far away from the curve. I'll now show you how you can turn the hermite curves into cardinal splines.
Cardinal splines
Cardinal splines are just a subset of the hermite curves. They don't need the tangent points because they will be calculated from the control points. We'll lose some of the flexibility of the hermite curves, but as a tradeoff the curves will be much easier to use. The formula for the tangents for cardinal splines is:
Ti = a * ( Pi+1 - Pi-1 )
a is a constant which affects the tightness of the curve. Write yourself a program and play around with it. ( a should be between 0 and 1, but this is not a must).
Catmull-Rom splines
The Catmull-Rom spline is again just a subset of the cardinal splines. You only have to define a as 0.5, and you can draw and interpolate Catmull-Rom splines.
Ti = 0.5 * ( P i+1 - Pi-1 )
Easy, isn't it? Take a math-book and look for Catmull-Rom splines. Try to understand how they work! It's damn difficult, but when they are derived from hermite curves the cardinal splines turn out to be very easy to understand. Catmull-Rom splines are great if you have some data-points and just want to interpolate smoothly between them.
The Kochanek-Bartels Splines (also called TCB-Splines)
Now we're going down to the guts of curve interpolation. The kb-splines (mostly known from Autodesk's 3d-Studio Max and Newtek's Lightwave) are nothing more than hermite curves and a handfull of formulas to calculate the tangents. These curves have been introduced by D. Kochanek and R. Bartels in 1984 to give animators more control over keyframe animation. They introduced three control-values for each keyframe point:
- Tension: How sharply does the curve bend?
- Continuity: How rapid is the change in speed and direction?
- Bias: What is the direction of the curve as it passes through the keypoint?
I won't try to derive the tangent-formulas here. I think just giving you something you can use is a better idea. (if you're interested you can ask me. I can write it down and send it to you via email.)
The "incoming" Tangent equation:
(1-t)*(1-c)*(1+b)
TS = ----------------- * ( P - P )
i 2 i i-1
(1-t)*(1+c)*(1-b)
+ ----------------- * ( P - P )
2 i+1 i
The "outgoing" Tangent equation:
(1-t)*(1+c)*(1+b)
TD = ----------------- * ( P - P )
i 2 i i-1
(1-t)*(1-c)*(1-b)
+ ----------------- * ( P - P )
2 i+1 i
When you want to interpolate the curve you should use this vector:
| P(i) |
C = | P(i+1) |
| TD(i) |
| TS(i+1) |
You might notice that you always need the previous and next point if you want to calculate the curve. This might be a problem when you try to calculate keyframe data from Lightwave or 3D-Studio. I don't know exactly how these programs handle the cases of the first and last point, but there are enough sources available on the internet. Just search around a little bit. (Newtek has a good developer section. You can download the origignal Lightwave motion code on their web-site).
Speed Control
If you write yourself keyframe-interpolation code and put it into a program you'll notice one problem. Unless you have your keyframes in fixed intervals you will have a sudden change of speed and direction whenever you pass a keyframe-point. This can be avoided if you take the number of key-positions (frames) between two keyframes into account:
N is the number of frames (seconds, whatever) between two keypoints.
2 * N
i-1
TD = TD * --------------- adjustment of outgoing tangent
i i N + N
i-1 i
2 * N
i
TS = TS * --------------- adjustment of incomming tangent
i i N + N
i-1 i
What about the "normal" Splines?
The other spline-types, beta-splines, uniform nonrational splines and all the others are a completely different thing and are not covered here. They share one thing with the hermite curves: They are still cubic polynomials, but the way they are calculated is different.
Final Words
Why does no-one care that it's almost impossible to do nicely formatted math-formulas in HTML? What's more important? Good design or good content? As always you might want to contact me.
Hermite曲线插值的更多相关文章
- 数值计算方法实验之Hermite 多项式插值 (Python 代码)
一.实验目的 在已知f(x),x∈[a,b]的表达式,但函数值不便计算,或不知f(x),x∈[a,b]而又需要给出其在[a,b]上的值时,按插值原则f(xi)= yi(i= 0,1…….,n)求出简单 ...
- Hermite (埃尔米特)曲线
Hermite 曲线 已知曲线的两个端点坐标P0.P1,和端点处的切线R0.R1,确定的一条曲线. 参数方程 1. 几何形式 2. 矩阵形式 3. 推导 例子分析 如上图有四个点,假如P0.P2是端点 ...
- 曲线参数化的Javascript实现(理论篇)
在关键帧动画的制作过程中,动画师在k物体运动的过程中,一般要确定2个参数: 1)运动轨迹(表示物体运动的路径): 2)速度曲线(表示物体随时间的速度变化). 对于运动轨迹通常选用一定的样条曲线,通过动 ...
- 【Unity3d游戏开发】游戏中的贝塞尔曲线以及其在Unity中的实现
RT,马三最近在参与一款足球游戏的开发,其中涉及到足球的各种运动轨迹和路径,比如射门的轨迹,高吊球,香蕉球的轨迹.最早的版本中马三是使用物理引擎加力的方式实现的足球各种运动,后来的版本中使用了根据物理 ...
- unity3D:游戏分解之曲线
一提到曲线,很多新手就头疼了,包括我.查了很多资料,终于有个大概的了解.想深入了解曲线原理的,推荐一个链接http://www.cnblogs.com/jay-dong/archive/2012/09 ...
- n阶贝塞尔曲线绘制(C/C#)
原文:n阶贝塞尔曲线绘制(C/C#) 贝塞尔是很经典的东西,轮子应该有很多的.求n阶贝塞尔曲线用到了 德卡斯特里奥算法(De Casteljau's Algorithm) 需要拷贝代码请直接使用本文最 ...
- 两点三次Hermiter插值C++代码
#include <math.h> #include <gl/glut.h> #include <iostream> using namespace std; st ...
- mapboxgl 中插值表达式的应用场景
目录 一.前言 二.语法 三.对地图颜色进行拉伸渲染 1. 热力图 2. 轨迹图 2. 模型网格渲染 四.随着地图缩放对图形属性进行插值 五.interpolate的高阶用法 六.总结 一.前言 in ...
- 贝塞尔曲线在Unity中的应用
前言:国庆放假后基本整个人的散掉了.加之种种原因,没时间没心情写博客.最近研究了一下3d的一些效果.其中有类似翻书撕纸的操作,可是一个panel怎么由平整的变成弯曲的呢? 两点可以确定一条直线,三点可 ...
随机推荐
- zTree异步加载(自定义图片)
原文链接:https://blog.csdn.net/qq_37936542/article/details/78429675 zTree官网:点击打开链接 一:文件下载 点击首页右下角的ztree ...
- mysql 序列号生成器 (自定义函数)
https://yq.aliyun.com/articles/42600 http://bbs.csdn.net/topics/360203885 http://www.tuicool.com/art ...
- 基于bootstrap的富文本框——wangEditor【欢迎增加开发】
先来一张效果图: 01. 引言 老早就開始研究富文本框的东西,在写完<深入理解javascript原型与闭包>之后,就想着要去做一个富文本框的插件的样例. 如今网络上开源的富文本框插件许多 ...
- 关于如何在Sublime下安装插件
安装插件的两种方式 通过Package Control安装 不能安装 手工安装 安装插件的两种方式 在sublime下安装插件有两种方式,一种是通过package control来进行安装,另一种呢就 ...
- js进阶 11-2 jquery属性如何操作
js进阶 11-2 jquery属性如何操作 一.总结 一句话总结:jquery中的属性用attr方法表示.jquery中都是方法. 1.jquery中的属性的增删改查操作? 只需要两个方法, at ...
- 【u021】广义斐波那契数列
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定数列的两系数p和q,以及数列的 ...
- Qt 连接MySQL数据库(很多相关文章)
今天想试试Qt如何连接数据库的. 谁知怎么写完了提示driver not loaded我就郁闷了. 我自己是 VS2010 + Qt4.8.4 + MySQL5.1 的环境 网上查到是 C:\Qt\4 ...
- Go 快速入门
入门 Go 语言需要多久?答案是 -- 读完这篇文章的时间!不妨找一个周末的下午,踏上 Go 之旅吧! 更新记录: 2016.12.12: 完成重制 2016.11.02: 增加重点理解和参考链接 2 ...
- PHPDocumentor 整理目光规范
你会写凝视么?从我写代码開始.这个问题就一直困扰着我.相信也相同困扰着其它同学.曾经的写凝视总是没有一套行之有效的标准,给维护和协同开发带了很多麻烦,直到近期读到了phpdocumentor的凝视标准 ...
- 详解Qt,并举例说明动态编译(shared)和静态编译(static)以及debug and release 编译版本区别(可产生静态版的Debug版本,需要把-release 改为 –debug-and-release)
作为初入Qt学习的新人,花了整整一两天时间,对Qt编译版本等问题进行了一步步探索,首先感谢网站博客中文章,开始也不是很明白一些几个问题: 1.Qt版本问题 作为初学者,可能下载时这么多版本,如何选择呢 ...