本文主要是介绍SuperMap iClient3D for Cesium绘制河流(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
作者: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
这篇关于SuperMap iClient3D for Cesium绘制河流(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!