SuperMap iClient3D for Cesium绘制河流(二)
2024-01-03 16:32:33
作者:kele
前言
之前分享过一篇《SuperMap iClient3D for WebGL绘制河流》(跳转)的文章,当时的思路是以 entity 中的 polyline 作为载体,给它添加流动材质来表达出河流效果,但是由于 polyline 对象是像素宽度,线宽始终是相对屏幕的固定大小,导致在场景放大缩小过程中,河流宽度与周围的山脉位置和大小不匹配,这个问题困扰了小编好久。最近想到了一个新的方案,并且能够支持实时更改河流宽度和高度,一起来看下如何实现吧~
一、解决思路
为了解决这个问题,先后考虑过以下几种方案:
- corridor 走廊对象:
大小正常,但水流方向为统一方向,不是沿线流动方向
- polygon 面对象:
大小正常,但水流方向为统一方向,不是沿线流动,适合用来表达湖泊效果
- wall 墙对象:
大小正常,水流方向沿墙体方向流动,但是墙体为向上拉伸只能竖着,河流表面应该是水平面,所以无法表达河流效果 - polylineVolume 多段线柱体对象:
多段线柱体对象类似于截面放样功能,通常是用来表达管道和墙体,我们先制作一个圆管看看效果
如上所示,河流大小正常,水流方向为沿线方向,这两方面都是符合预期的。接下来我们可以将管道截面改为一条横线,最终得到结果就是一个面片,感觉这个方式可行
二、实现代码
2.1 绘制河流
经过上面的分析,我们最终选择使用 polylineVolume 多段线柱体对象绘制河流,这个方案的关键所在就是需要一个合适的截面:
river = viewer.entities.add({
name : 'river',
polylineVolume : {
positions: new Cesium.Cartesian3.fromDegreesArrayHeights(positions), //节点坐标
shape: computeCircle(150.0), //截面形状
material : new Cesium.PolylineTrailLinkMaterialProperty(Cesium.Color.SKYBLUE,10000),
cornerType: Cesium.CornerType.MITERED,
}
})
function computeCircle(radius) { //设置截面长和宽的大小
var positions = [];
for(var i = 0; i < 180; i++) {
let x = radius * Math.cos(Math.PI * 2 * i / 360); //宽度参数radius可传入进行控制
let y = 0.1 * Math.sin(Math.PI * 2 * i / 360); //将高度尽可能设置小,达到面片效果
positions.push(new Cesium.Cartesian2(x, y));
}
return positions;
}
将截面设置为面片模拟河流
2.2 调整河流宽度
因为我们使用的是 polylineVolume 多段线柱体对象,他没有 width 属性,而是通过改变截面大小,来实现河流宽度的修改,配合着 CallbackProperty 属性,我们就可以实时改变河流宽度了。
shape: new Cesium.CallbackProperty(setWidth,false),
function setWidth() {
var positions = [];
for(var i = 0; i < 180; i++) {
let x = roverWidth * Math.cos(Math.PI * 2 * i / 360);
let y = 0.1 * Math.sin(Math.PI * 2 * i / 360);
positions.push(new Cesium.Cartesian2(x, y));
}
return positions;
}
$('#addwidth').click(function () {
roverWidth += 20
});
$('#reducewidth').click(function () {
roverWidth -= 20
});
2.3 调整河流高度
同样的,polylineVolume 多段线柱体对象没有高度属性,想要改变数据的高度,需要改变传入坐标的 z 值,同样需要使用 CallbackProperty 属性来实现
positions: new Cesium.CallbackProperty(setHeight,false),
function setHeight() {
return new Cesium.Cartesian3.fromDegreesArrayHeights(positions)
}
$('#addheight').click(function () {
for(let i=0;i<positions.length/3;i++){
positions[i*3+2] += 20;
}
});
$('#reduceheight').click(function () {
for(let i=0;i<positions.length/3;i++){
positions[i*3+2] -= 20;
}
});
三、最终效果
demo地址:
链接:https://pan.baidu.com/s/1e8zxMY31GUVFwmQAyx7BqA
提取码:6655
文章来源:https://blog.csdn.net/supermapsupport/article/details/135354563
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!