在cesium中,提供了三种样条插值方法,LinearSpline,CatmullRomSpline,HermiteSpline。
在具体实例中,可以使用样条插值法利用已知的控制点,插值出一系列的点,用于平滑曲线,特别是在路径的追溯重演。
插值概念
在数学的数值分析领域中,内插或称插值(interpolation)是一种通过已知的,离散的数据点,在范围内推求出新数据点的过程或方法。
求解科学和工程的问题时,通常有许多数据点借由采样、实验等方法获得,这些数据可能代表了有限个数值函数,其中自变量的值。而根据这些数据,我们往往希望得到一个连续的函数(也就是曲线);或者更密集的离散方程与已知数据互相吻合,这个过程叫做拟合。
与插值密切相关的另一个问题是通过简单函数逼近复杂函数。假设给定函数的公式是已知的,但是太复杂以至于不能有效地进行评估。来自原始函数的一些已知数据点,或许会使用较简单的函数来产生插值。当然,若使用一个简单的函数来估计原始数据点时,通常会出现插值误差;然而,取决于该问题领域和所使用的插值方法,以简单函数推得的插值数据,可能会比所导致的精度损失更大。
在数值分析这个数学分支中,样条插值是使用一种名为样条的特殊分段多项式进行插值的形式。由于样条插值可以使用低阶多项式样条实现较小的插值误差,这样就避免了使用高阶多项式所出现的龙格现象,所以样条插值得到了流行。
插值代码详解
LinearSpline(线性样条)
线性样条从效果上看,是把所有的点-一一连成线,并在连线上做定点取值
1.设置几个控制点,并添加到场景中,聚焦视角
var controls = []
controls.push(Cesium.Cartesian3.fromDegrees(120.11551237582385, 35.97934910503657))
controls.push(Cesium.Cartesian3.fromDegrees(121.1367529, 35.9629172))
controls.push(Cesium.Cartesian3.fromDegrees(122.1367529, 36.9629172))
controls.push(Cesium.Cartesian3.fromDegrees(123.8632471, 36.9629172))
controls.push(Cesium.Cartesian3.fromDegrees(124.1367529, 35.9629172))
for (var i = 0; i < controls.length; i++) {
viewer.entities.add({
position: controls[i],
point: {
color: Cesium.Color.RED,
pixelSize: 10,
},
});
}
viewer.zoomTo(viewer.entities);
2.创建LinearSpline对象
var spline = new Cesium.LinearSpline({
times: [0.0, 0.25, 0.5, 0.75, 1],
points: controls,
});
3.插值50个点
var positions = [];
for (var i = 0; i <= 50; i++) {
var cartesian3 = spline.evaluate(i / 50);
positions.push(cartesian3);
viewer.entities.add({
position: cartesian3,
point: {
color: Cesium.Color.YELLOW,
pixelSize: 6,
},
});
}
4.将插值所有的点连接成线,方便观察效果
viewer.entities.add({
name: "LinearSpline",
polyline: {
positions: positions,
width: 3,
material: Cesium.Color.GREEN,
},
});
CatmullRomSpline(Catmull-ROM样条)
var spline = new Cesium.CatmullRomSpline({
points: controls,
times: [0.0, 0.25, 0.5, 0.75, 1],
});
var positions = [];
for (var i = 0; i <= 50; i++) {
var cartesian3 = spline.evaluate(i / 50);
positions.push(cartesian3);
viewer.entities.add({
position: cartesian3,
point: {
color: Cesium.Color.BLUE,
pixelSize: 6,
},
});
}
viewer.entities.add({
name: "CatmullRomSpline",
polyline: {
positions: positions,
width: 3,
material: Cesium.Color.WHITE,
},
});
HermiteSpline(埃尔米特样条)
// HermiteSpline
var spline = Cesium.HermiteSpline.createNaturalCubic({
times: [0.0, 0.25, 0.5, 0.75, 1],
points: controls,
});
var positions = [];
for (var i = 0; i <= 50; i++) {
var cartesian3 = spline.evaluate(i / 50);
positions.push(cartesian3);
viewer.entities.add({
position: cartesian3,
point: {
color: Cesium.Color.WHITE,
pixelSize: 6,
},
});
}
viewer.entities.add({
name: "HermiteSpline",
polyline: {
positions: positions,
width: 3,
material: Cesium.Color.RED,
},
});
效果图如下:
其中白色为线条为CatmullRomSpline,红色线条为HermiteSpline,绿色线条为LinearSpline。