粒子发射器是用来限定粒子活动范围的,并给定随机产生的粒子一个初始位移和速度。cesium默认提供了4种粒子发射器。分别是
BoxEmitter 盒子粒子发射器,CircleEmitter 圆形粒子发射器,ConeEmitter 圆锥粒子发射器,SphereEmitter 球形粒子发射器
1,BoxEmitter 盒子粒子发射器
(1)生成算法
用a,b,c分别为长,宽,高建立一个盒子。盒子中心点为原点,建立x-y-z直角坐标系。其中x的取值范围(-a/2,a/2),y的取值范围(-b/2,b/2),z的取值范围(-c/2,c/2)
代码
function createBoxPoints(a,b,c){
let x=Cesium.Math.randomBetween(-a/2, a/2)
let y=Cesium.Math.randomBetween(-b/2, b/2)
let z=Cesium.Math.randomBetween(-c/2, c/2)
return {x,y,z}
}
效果
评价:这也是cesium采用的算法,能均匀在盒子内产生随机点
2,CircleEmitter 圆形粒子发射器
(1)生成算法1
根据圆的公式 xx + yy = rr;
取x在(-r,r)则 y等于r的平方减去x的平方得到结果之后再开方。这样y的取值范围就为(-Math.sqrt(rr-xx),Math.sqrt(rr-x*x))
代码
function createCirclePoints(radius){
let x=Cesium.Math.randomBetween(-radius, radius)
let yMax=Math.sqrt(radius*radius-x*x)
let y=Cesium.Math.randomBetween(-yMax, yMax)
return {x,y,z:0}
}
效果
评价:从图中看出靠近圆边线的点比较密集。中间部分的点比较稀疏
(2)生成算法2
x的取值范围在(-r,r),y的取值范围在(-r,r),然后根据圆的公式xx + yy = rr,只要(xx + yy)<rr
则随机点就落在圆内
代码
function createCirclePoints2(radius){
let x=Cesium.Math.randomBetween(-radius, radius)
let y=Cesium.Math.randomBetween(-radius, radius)
let isInner=(x*x+y*y)<radius*radius;
if(isInner){
return {x,y,z:0}
}
}
效果
评价:使用这个算法会多产生一些在圆外的点,但能满足在圆内均匀产生点的需求
(3)生成算法3
使用极坐标的方式表示在园内的点,圆内点(r,θ)可以任意表示为(r,θ ± 2kπ)或(−r,θ ± (2k+ 1)π)
代码
function createCirclePoints3(radius){
let rad=Cesium.Math.randomBetween(0, radius)
let theta=Cesium.Math.randomBetween(0, 2*Math.PI)
var x = rad * Math.cos(theta);
var y = rad * Math.sin(theta);
return {x,y,z:0}
}
效果
评价
圆心产生的点比较密集,离圆心越远产生的点越稀疏。
3,ConeEmitter 圆锥粒子发射器
算法,暂时还不太明白
代码
unction createConePoints(angle);{
let radius = Math.tan(angle);
let theta=Cesium.Math.randomBetween(0, 2*Math.PI)
let rad=Cesium.Math.randomBetween(0, radius)
let x = rad * Math.cos(theta);
let y = rad * Math.sin(theta);
let z = 1.0;
return {x,y,z}
}
4,SphereEmitter 球形粒子发射器
(1)生成算法1
和园内生成随机点算法一样,球内生成随机点也有好几种算法。当然效果各不一样,cesium采用的极坐标算法,先求θ的范围(0,2Π),然后再确定φ的范围(0,Π),
最后确定r的取值范围(0,R)
代码
function createSpherePoints(radius){
let rad=Cesium.Math.randomBetween(0, radius)
let theta=Cesium.Math.randomBetween(0, 2*Math.PI)
let phi=Cesium.Math.randomBetween(0,Math.PI)
let x = rad * Math.cos(theta)*Math.sin(phi);
let y = rad * Math.sin(theta)*Math.sin(phi);
let z=rad*Math.cos(phi);
return {x,y,z}
}
效果
评价,和园内极坐标生成随机点的算法一样,靠近球心的点会比较密集,远离球心随机点会越来越稀疏
5,其它拓展实现,例如三角形内随机点,矩形内随机点,圆柱内随机点,五角星内随机点等