<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8">
<!-- Tell IE to use the latest, best version. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>Hello World!</title>
<script src="../Build/Cesium/Cesium.js"></script>
<style>
@import url(../Build/Cesium/Widgets/widgets.css);
html, body, #cesiumContainer {
100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
var viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider : Cesium.createTileMapServiceImageryProvider({
url : Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')
}),
shouldAnimate: true,//是否开始动画
geocoder : false
});
// 画一个用于粒子显示的canves图像
var particleCanvas;
function getImage() {
if (!Cesium.defined(particleCanvas)) {
particleCanvas = document.createElement('canvas');
particleCanvas.width = 20;
particleCanvas.height = 20;
var context2D = particleCanvas.getContext('2d');
context2D.beginPath();
context2D.arc(8, 8, 8, 0, Cesium.Math.TWO_PI, true);
context2D.closePath();
context2D.fillStyle = 'rgb(255, 255, 255)';
context2D.fill();
}
return particleCanvas;
}
//关于粒子的一些属性项
//光学粒子属性
var Optics_options = {
numberOfSystems : 1,
iterationOffset : 0.1,
cartographicStep : 0.00000001
};
//雷达粒子属性
var Radar_options = {
numberOfSystems : 50,//用很多粒子组成一个形状,这里让其组成一个圆形
iterationOffset : 0.1,
cartographicStep : 0.00000001,
baseRadius : 300//初始圆形的半径
};
// 创建粒子位置矩阵
var planePosition = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 800.0);
var particlesOffset = new Cesium.Cartesian3(-8.950115473940969, 34.852766731753945, -30.235411095432937);
var translationOffset = Cesium.Matrix4.fromTranslation(particlesOffset, new Cesium.Matrix4());
var translationOfPlane = Cesium.Matrix4.fromTranslation(planePosition, new Cesium.Matrix4());
var particlesModelMatrix = Cesium.Matrix4.multiplyTransformation(translationOfPlane, translationOffset, new Cesium.Matrix4());
//创建光学粒子系统,该系统只有一个粒子发射器不断发射粒子
var matrix4Scratch = new Cesium.Matrix4();
var scratchOffset = new Cesium.Cartesian3();
var imageSize = new Cesium.Cartesian2(5.0, 5.0);
var emitterModelMatrix = Cesium.Matrix4.fromTranslation(scratchOffset, matrix4Scratch);
var color = Cesium.Color.YELLOW;//设置粒子的颜色
//光学传感器粒子位置更新函数
var positionC= new Cesium.Cartesian3();
var positionD= new Cesium.Cartesian3();
var force = function(particle,dt) {
dt = Cesium.Math.clamp(dt, 0.0, 1);//每次更新时间间隔
//下面是向量计算
var positionA=particle.position;
var positionB=Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706,0);
positionC=Cesium.Cartesian3.multiplyByScalar(positionA, 0.9, positionC);
positionD=Cesium.Cartesian3.multiplyByScalar(positionB, 0.1, positionD);
particle.position=Cesium.Cartesian3.add(positionC,positionD,particle.position);
};
//
var itemOptics = viewer.scene.primitives.add(new Cesium.ParticleSystem({
image : getImage(),//粒子图像
startColor : color,//开始颜色
endColor : color.withAlpha(0.5),//结束时的颜色
particleLife : 100,//每个粒子的生存时间
speed : 50,//粒子飞行速度
imageSize : imageSize,//粒子大小
emissionRate : 1.0,//每秒发射粒子的个数
emitter : new Cesium.CircleEmitter(0.01),//粒子发射器的形式,确定了在什么样的区间里随机产生粒子
lifetime : 100,//粒子发射器的生命周期,即发射粒子的时间
updateCallback : force,//粒子位置更新回调函数
modelMatrix : particlesModelMatrix,//决定粒子在空间坐标系的位置矩阵
emitterModelMatrix : emitterModelMatrix//决定粒子相对于模型位置的位置矩阵
}));
var itemRadar=[];
//创建雷达粒子系统,该系统具有许多粒子发射器不断发射粒子
function createParticleSystems(options, systemsArray) {//创建很多个粒子系统
var length = options.numberOfSystems;//创建的长度
for (var i = 0; i < length; ++i) {
scratchAngleForOffset = Math.PI * 2.0 * i / options.numberOfSystems;//一圈粒子的不同大小
scratchOffset.x += options.baseRadius * Math.cos(scratchAngleForOffset);
scratchOffset.y += options.baseRadius * Math.sin(scratchAngleForOffset);
scratchOffset.z += options.baseRadius * Math.cos(scratchAngleForOffset/2);
var emitterModelMatrix = Cesium.Matrix4.fromTranslation(scratchOffset, matrix4Scratch);
var color = Cesium.Color.RED;//取一个随机颜色
// var color = Cesium.Color.AQUAMARINE//取天蓝色
var force = forceFunction(options, i);
itemRadar = viewer.scene.primitives.add(new Cesium.ParticleSystem({
image : getImage(),
startColor : color,
endColor : color,
particleLife : 50,
speed : 1,
imageSize : new Cesium.Cartesian2(2.0, 2.0),
emissionRate : 3.0,
emitter : new Cesium.CircleEmitter(0.1),
lifetime : 100,
updateCallback : force,
modelMatrix : particlesModelMatrix,
emitterModelMatrix : emitterModelMatrix
}));
systemsArray.push(itemRadar);
}
};
//雷达传感器粒子位置更新函数
var RadarpositionC = new Cesium.Cartesian3();
var RadarpositionD = new Cesium.Cartesian3();
var forceFunction = function(options, iteration) {
return function(particle, dt) {
dt = Cesium.Math.clamp(dt, 0.0, 1);//每次更新时间间隔
//下面是向量计算
var positionA=particle.position;
var positionB=Cesium.Cartesian3.fromDegrees(-122.0744619, 44.0503706,0);
positionC=Cesium.Cartesian3.multiplyByScalar(positionA, 0.9, positionC);
positionD=Cesium.Cartesian3.multiplyByScalar(positionB, 0.1, positionD);
particle.position=Cesium.Cartesian3.add(positionC,positionD,particle.position);
};
};
var RadarSystems = [];
createParticleSystems(Radar_options, RadarSystems);
////////////////////////////////**************************************////////////////////////////////
var scene = viewer.scene;
//飞行轨迹
var pathPosition = new Cesium.SampledPositionProperty();
var entityPath = viewer.entities.add({
position : pathPosition,
name : 'path',
path : {
show : true,
leadTime : 0,
trailTime : 60,
width : 10,
resolution : 1,
material : new Cesium.PolylineGlowMaterialProperty({
glowPower : 0.3,
color : Cesium.Color.PALEGOLDENROD
})
}
});
var camera = viewer.camera;
var r = 0;
var center = new Cesium.Cartesian3();
var hpRoll = new Cesium.HeadingPitchRoll();
var hpRange = new Cesium.HeadingPitchRange();
var speed = 500;//飞行速度
var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 50000.0);//飞机初始位置
var speedVector = new Cesium.Cartesian3();//速度向量
var fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west');//坐标系
//添加飞机模型
var planePrimitive = scene.primitives.add(Cesium.Model.fromGltf({
url : './SampleData/models/CesiumAir/Cesium_Air.glb',
modelMatrix : Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransform),
minimumPixelSize : 128
}));
//添加一个地面站
var entity1 = viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706),
billboard : {
image : './Sandcastle/images/facility.gif',
}
});
//添加第二个地面站
var entity1 = viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-122.0744619, 44.0503706),
billboard : {
image : './Sandcastle/images/facility.gif',
}
});
planePrimitive.readyPromise.then(function(model) {
// Play and loop all animations at half-speed
model.activeAnimations.addAll({
speedup : 0.5,
loop : Cesium.ModelAnimationLoop.REPEAT
});
});
viewer.scene.preUpdate.addEventListener(function(scene, time) {
speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X, speed / 10, speedVector);
position = Cesium.Matrix4.multiplyByPoint(planePrimitive.modelMatrix, speedVector, position);
pathPosition.addSample(Cesium.JulianDate.now(), position);
Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransform, planePrimitive.modelMatrix);
translationOfPlane = Cesium.Matrix4.fromTranslation(position, new Cesium.Matrix4());
particlesModelMatrix = Cesium.Matrix4.multiplyTransformation(translationOfPlane, translationOffset, new Cesium.Matrix4());
itemOptics.modelMatrix=particlesModelMatrix;
for(var i=0;i<50;i++){
RadarSystems[i].modelMatrix=particlesModelMatrix;
}
});
viewer.zoomTo(viewer.entities);
</script>
</body>
</html>
Cesium中粒子系统被用来模拟飞机爆炸、雨雪天气等场景。
根据官网对其定义 ,粒子系统是由小图像组成的集合,当他们在一起形成一个更复杂的对象时,就会形成火、烟等景象。对于该系统详细的说明可以参照官网介绍:
https://cesiumjs.org/tutorials/Particle-Systems-Tutorial/
下面还有国内公司的翻译版:
http://cesium.marsgis.cn/go.html?id=12
看完上述教程还是一头雾水,那就做个简单的粒子来分析下吧。粒子系统其实实由一个发射器不断发射出粒子对象实现的。如果是一个单个的粒子,可以将粒子发射器想象成一把枪,子弹就是该发射器发射出的粒子。不同之处在于,粒子发射器发射出粒子之后可以控制粒子的轨迹、颜色等属性。
先来看一个最简单的生成粒子系统的代码例子:
var item = viewer.scene.primitives.add(new Cesium.ParticleSystem({
image : getImage(),//粒子图像
startColor : color,//开始颜色
endColor : color.withAlpha(0.5),//结束时的颜色
particleLife : 100,//每个粒子的生存时间,即子弹被打出来后能飞多久
speed : 50,//粒子飞行速度
imageSize : imageSize,//粒子大小
emissionRate : 1.0,//每秒发射粒子的个数
emitter : new Cesium.CircleEmitter(1),//粒子发射器的形式,确定了在什么样的区间里随机产生粒子,该行表示粒子将在一个半径为1米的圆形区域不断产生
lifetime : 100,//粒子发射器的生命周期,即发射粒子的时间,该值可理解为一把枪的弹夹可以用多长时间,loop默认属性为true理解为到时间后换上另一个弹夹继续发射。
updateCallback : force,//粒子位置更新回调函数
modelMatrix : particlesModelMatrix,//决定粒子在空间坐标系的位置矩阵,可以理解为用枪的人的空间位置
emitterModelMatrix : emitterModelMatrix//决定粒子相对于模型位置的位置矩阵,可以理解为人把发射枪拿在哪里,用左手还是右手还是用脚,即发射器相对本体的位置矩阵。
}));
上述代码构成了一个粒子系统,该系统中只有一个发射器。
image : getImage()是每个粒子的样式,我们可以理解成从枪里发射出来子弹的类型,子弹的样子可以是图片,也可以用canves函数来绘制,如果使用图片的话,可以直接写作image : '../../SampleData/fire.png',
在火箭发射粒子效果里,给出了一个简单的圆形图像的绘制函数:
function getImage() {
if (!Cesium.defined(particleCanvas)) {
particleCanvas = document.createElement('canvas');
particleCanvas.width = 20;
particleCanvas.height = 20;
var context2D = particleCanvas.getContext('2d');
context2D.beginPath();
context2D.arc(8, 8, 8, 0, Cesium.Math.TWO_PI, true);
context2D.closePath();
context2D.fillStyle = 'rgb(255, 255, 255)';
context2D.fill();
}
return particleCanvas;
}
上述函数属于html中canves内容,这里不在赘述。
imageSize : imageSize是一个由二维向量定义的尺寸函数,可以由代码new Cesium.Cartesian2(1, 1)进行设置。
应该重点介绍的是updateCallback : force。该属性是一个函数形式,该函数可写作:
function force(particle, dt) {//particle是当前粒子对象,可以由很多属性,dt是时间步长。之前有一个属性是particleLife表示每个粒子被发射出来后的生存时间。dt就是将这段时间均分的步长。下面我们对粒子的位置进行改变。
var position = particle.position;
var positionA = Cesium.Cartesian3.normalize(position, new Cesium.Cartesian3());//将粒子的位置向量正则化为单位值。
Cesium.Cartesian3.multiplyByScalar(positionA , 5, positionA );//将单位向量按比例进行缩放
particle.position= Cesium.Cartesian3.add(particle.position, positionA , particle.position);//在粒子发射方向加上成比例缩放的向量,更新粒子位置
}
上述函数只是对粒子位置按粒子的生命周期进行了修改,还可以对其速度、颜色等属性按时间进行修改。
下述就是用粒子系统做的信号动态传输效果图,黄色用了一个粒子发射器。红色的圈圈用了一组发射器,沿着圆圈的方向不断发射粒子。当然该效果可以直接用entity来实现,但是粒子系统的自由度高,可以做出各种不同的波形效果。
*回忆总像个漏风的房子,起风了,都是不请自来*
本文转自 https://blog.csdn.net/dk_wyp/article/details/82024647,如有侵权,请联系删除。