先看最终效果:
沙盒 (需要官网沙盒,链接打不开建议科学上网)
最近搞路径漫游,需要绘制平滑曲线,刚开始想到的是绘制贝塞尔曲线,但是贝塞尔曲线初不过控制点,最后才知道需要的是样条线这个东西。
通过样条线获取平滑曲线的插值点,用点绘制线就可以了,如下:
const viewer = new Cesium.Viewer("cesiumContainer");
// 定义控制点
var controlPoints = [
new Cesium.Cartesian3(-1000000.0, 0.0, 1000000.0),
new Cesium.Cartesian3(-500000.0, 0.0, 1000000.0),
new Cesium.Cartesian3(0.0, 0.0, 1000000.0),
new Cesium.Cartesian3(1000000.0, 0.0, -500000.0),
new Cesium.Cartesian3(1000000.0, 0.0, -1500000.0),
new Cesium.Cartesian3(2000000.0, 0.0, -1500000.0),
new Cesium.Cartesian3(1000000.0, 0.0, -2000000.0)
];
let count = controlPoints.length;
let times = [];
let step = 1/(count-1);
for(let i =0;i<count;i++){
let time = step*i;
times.push(time);
}
// 样条线
var spline = new Cesium.CatmullRomSpline({
times,
points: controlPoints
});
// 获取平滑曲线(样条线)的插值点
var numSamples = 100;
var samples = [];
for (var i = 0; i <= numSamples; i++) {
var time = i / numSamples;
var sample = spline.evaluate(time);
samples.push(sample);
}
viewer.scene.primitives.add(new Cesium.PolylineCollection());
var polyline = new Cesium.PolylineGeometry({
positions: samples,
width: 5.0
});
var polylineInstance = new Cesium.GeometryInstance({
geometry: polyline,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW)
}
});
// 绘制曲线
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: [polylineInstance],
appearance: new Cesium.PolylineMaterialAppearance({
material: Cesium.Material.fromType('Color', {
color: Cesium.Color.YELLOW
})
})
}));
// 绘制控制点
controlPoints.forEach(p => {
viewer.entities.add({
position:p,
point:{
pixelSize:15,
color:Cesium.Color.RED
}
})
})
viewer.scene.globe.show = false;
贝塞尔曲线也顺便贴上来吧。。。
var viewer = new Cesium.Viewer('cesiumContainer');
var controlPoints = [
new Cesium.Cartesian3(-1000000.0, 0.0, 1000000.0),
new Cesium.Cartesian3(-500000.0, 0.0, 1000000.0),
new Cesium.Cartesian3(0.0, 0.0, 1000000.0),
new Cesium.Cartesian3(500000.0, 0.0, 1000000.0),
new Cesium.Cartesian3(1000000.0, 0.0, 1000000.0),
new Cesium.Cartesian3(1000000.0, 0.0, 500000.0),
new Cesium.Cartesian3(1000000.0, 0.0, 0.0),
new Cesium.Cartesian3(1000000.0, 0.0, -500000.0),
new Cesium.Cartesian3(1000000.0, 0.0, -1000000.0),
new Cesium.Cartesian3(500000.0, 0.0, -1000000.0)
];
var numSamples = 100;
var samples = [];
for (var i = 0; i <= numSamples; i++) {
var t = i / numSamples;
var point = controlPoints[0];
for (var j = 1; j < controlPoints.length; j++) {
var prevPoint = point;
point = Cesium.Cartesian3.lerp(prevPoint, controlPoints[j], t, new Cesium.Cartesian3());
}
samples.push(point);
}
viewer.entities.add({
polyline: {
positions: samples,
width: 5.0,
material: Cesium.Color.YELLOW
}
});
viewer.scene.globe.show = false;