需要标注线面的角度heading
2022年6月23日
heading计算方式:
https://turfjs.fenxianglu.cn/
计算两点之间的角度
直接F12在控制台可以计算
eg:
function c(a,b){
console.log( [(b[0]+a[0])/2,(a[1]+b[1])/2,(b[2]+a[2])/2])
var point1 = turf.point([a[0],a[1]]);
var point2 = turf.point([b[0],b[1]]);
var bearing = turf.bearing(point1, point2);
console.log(bearing)
}
加载gltf模型,模型是透明的,需要改为不透明
2022年6月23日
用文本编辑器打开.gltf,把里面的"alphaMode":"BLEND"改成"alphaMode":"OPAQUE"
模型旋转之后,标注的点也旋转的计算方式
2022年6月24日
Q:项目需要将模型沿Z 轴旋转(模型之前设置的z:1 后来改为0.65,相当于旋转了-0.35度),之前标注的点因此错位。需要将之前标注的线段、点等也旋转-0.35度。
A:利用turf.js中的【旋转】transformRotate
// 原来标注的线段
var poly = turf.lineString([[75.87926657839982, 39.20165857293024], [75.8792225335169, 39.2016347276248]]);
// pivot:旋转的质点(模型的中心点)
var options = {pivot: [75.879766,39.201592]};
// -0.35为旋转角度,应与模型旋转角度相同
var line = turf.transformRotate(poly, -0.35, options);
console.log(line.geometry.coordinates)
计算两点间的中点
2022年6月24日
function min_point(b,c){
console.log( [(b[0]+c[0])/2,(c[1]+b[1])/2,(b[2]+c[2])/2])
}
计算对称点(已知左侧跟中点,右侧对称点)
2022年6月24日
function other_point(b,c){
console.log( [(2*b[0]-c[0]),(2*b[1]-c[1]),(2*b[2]-c[2])])
}
视线离得越远设置Graphic越小
scaleByDistance: new schinta3d.Cesium.NearFarScalar(100, 1,500, 0),100距离的时候是正常展示,距离超过500就隐藏了
const graphic = new schinta3d.graphic.DivGraphic({
position: opt.position,
style: DefaultOptions.getLabelStyleOptions({
html: HtmlBuilder[`get${opt.type}LabelHtml`](opt),
scaleByDistance: new schinta3d.Cesium.NearFarScalar(100, 1,500, 0),
distanceDisplayCondition: new schinta3d.Cesium.DistanceDisplayCondition(0, far)
}),
attr: opt.attr || {}
})
模拟水闸放水时的粒子效果(项目中引入ParticleSystem.js)
2022年8月5日17:22:44
/**
* 添加水柱(粒子效果)(与闸门无关的粒子)
* @param {number[]} waterGate 出水点对象
* @param {number} gravity 重力因子
* @param {number[]} speed 发射的速度(越大越远)
* @param {number} heading 方向
* @param {number} pitch 俯仰角
* @returns {*[]}
*/
addWaterParticle(waterParticle) {
if(!waterParticle){
return
}
let graphicLayer = this.mapInstance.getLayer('water_particle')
if (graphicLayer){
graphicLayer.clear(true)
}else{
graphicLayer = new schinta3d.layer.GraphicLayer({name: 'water_particle'})
this.addLayer(graphicLayer)
}
for (let i = 0, len = waterParticle.length; i < len; i++) {
const {name,position,gravity=-11,speed=19,heading=140,pitch=50,minSpeed,maxSpeed,maxDistance=160,emissionRate=500}=waterParticle[i];
const particleSystem = new ParticleSystem({
id:'WaterParticle_'+name,
position, // 位置
style: {
image:require("../assets/img/smoke.png"),
particleSize: 20,
startColor: schinta3d.Cesium.Color.LIGHTCYAN.withAlpha(0.3), // 粒子出生时的颜色
endColor: schinta3d.Cesium.Color.WHITE.withAlpha(0.0), // 当粒子死亡时的颜色
startScale:2.0, // 粒子出生时的比例,相对于原始大小
endScale: 6.0, // 粒子在死亡时的比例
minimumParticleLife: 6.0, // 最小寿命时间(秒)
maximumParticleLife: 7.0, // 最大寿命时间(秒)
minimumSpeed: minSpeed, // 最小速度(米/秒)
maximumSpeed: maxSpeed, // 最大速度(米/秒)
emissionRate, // 每秒要发射的粒子数。
lifetime: 1.0, // 粒子的生命周期为(以秒为单位)。
heading, // 方向角
pitch, // 俯仰角
},
gravity:gravity || -11,
//target:target || new schinta3d.Cesium.Cartesian3(-0.25, -0.12, 0.1), // 粒子的方向
maxDistance: maxDistance, //超出后不显示粒子效果
maxHeight: 1500 // 超出该高度后不显示粒子效果
})
调用:
/**
* 粒子效果对象
* @param {number[]} position 出水点
* @param {number} gravity 重力因子
* @param {number[]} speed 发射的速度(越大越远)
* @param {number} heading 方向 (喷的左右方向)
* @param {number} pitch 俯仰角 (喷的高低方向)
* @returns {*[]}
*/
const obj={
name: 'xxxxx闸口1#',
position: [71.70923741915449, 39.1242423560064, 1418.562869989279],
gravity: -1,
minSpeed: 1,
maxSpeed: 4,
heading: 213,
pitch: 95
},
// 添加放水粒子效果
this.mapViewer.addWaterGate({oPosition,gravity:-11,tPosition,pointHight:5});
根据线段生成等宽的面
2022年7月21日20:36:07
//lineArr:线段数组; width:生成的线宽度
function calc(lineArr,width=5){
// 平移到左边的点集合
var left_point=[]
// 平移到右边的点集合
var right_point=[]
for(var i=0;i<lineArr.length-1;i++){
// 每两个点算一次
var b=lineArr[i];
var c=lineArr[i+1];
var point1 = turf.point(b);
var point2 = turf.point(c);
// 两点间恒向角度
var bearing = turf.rhumbBearing(point1, point2);
// 与这个角度垂直的话就 加减90度
var leftbearing = bearing +90;
var rightbearing =bearing - 90;
// 平移
var translatedPolyleft = turf.transformTranslate(point1, width/2000, leftbearing);
var translatedPolyright = turf.transformTranslate(point1, width/2000, rightbearing);
left_point.push(translatedPolyleft.geometry.coordinates);
right_point.unshift(translatedPolyright.geometry.coordinates);
}
// 合并 成面
var newpolygn=[...left_point,...right_point]
console.log(JSON.stringify(newpolygn))
return newpolygn
}
// 调用
// 线段(沿着渠道底部中点)
var a=[[75.735847,39.138099,1378.8],[75.735871,39.138122,1378.8],[75.735898,39.138145,1378.8],[75.735918,39.138163,1379.3]]
calc(a,5)
支持高亮显示Entity、Primitive和3DTiles等 点击时的描边效果
2022年8月5日17:19:37
公司版本比较老,没有mars3d.effect.OutlineEffect。项目组有一个createEdgeStage.js文件用来处理模型描边。
1、调用 然后初始化effect
#initEffects() {
// 抗锯齿
this.mapInstance.viewer.scene.postProcessStages.fxaa.enabled = true
// 阴影透明度
this.mapInstance.viewer.shadowMap.darkness = 0.55
// 环境遮罩
// 与模型描边效果冲突,不能同时开启
// this.postStage.ambientOcclusion =
// this.mapInstance.viewer.scene.postProcessStages.ambientOcclusion;
// this.postStage.ambientOcclusion.enabled = true;
// 模型描边效果处理器初始化
this.postStage.edgeStage = createEdgeStage()
this.postStage.edgeStage.visibleEdgeColor = schinta3d.Cesium.Color.fromCssColorString('#7ca6b1')
this.postStage.edgeStage.hiddenEdgeColor = schinta3d.Cesium.Color.fromCssColorString('#1d3c4d')
this.postStage.edgeStage.selected = []
this.postStage.edgeStage.enabled = false
this.mapInstance.viewer.postProcessStages.add(this.postStage.edgeStage)
this.postStage.blackFog = new schinta3d.effect.FogEffect({
enabled: false,
color: schinta3d.Cesium.Color.BLACK,
fogByDistance: new schinta3d.Cesium.Cartesian4(10, 0.0, 3000, 1)
})
this.mapInstance.addThing(this.postStage.blackFog)
this.postStage.groundTransparent = new schinta3d.thing.Underground({
alpha: 0.2
})
}
2、高亮的方法highlightPicked
highlightPicked(pickedObjectArray, options) {
let opt = options || {}
this.postStage.edgeStage.thresholdAngle = (opt.thresholdAngle * Math.PI) / 180 || (12 * Math.PI) / 180
this.postStage.edgeStage.visibleEdgeColor = schinta3d.Cesium.Color.fromCssColorString(
// opt.visibleEdgeColor || "#7ca6b1"
opt.visibleEdgeColor || '#F8F846'
)
this.postStage.edgeStage.hiddenEdgeColor = schinta3d.Cesium.Color.fromCssColorString(
// opt.hiddenEdgeColor || "#1d3c4d"
opt.hiddenEdgeColor || ''
)
this.postStage.edgeStage.showGlow = true
if (pickedObjectArray && pickedObjectArray.length > 0) {
this.postStage.edgeStage.selected = pickedObjectArray
// this.postStage.ambientOcclusion.enabled = false;
this.postStage.edgeStage.enabled = true
} else {
this.postStage.edgeStage.selected = []
this.postStage.edgeStage.enabled = false
// this.postStage.ambientOcclusion.enabled = true;
}
}
3、Entity、Primitive被click时调用highlightPicked参考:https://zhuanlan.zhihu.com/p/407871786
// 添加点击事件
this.mapViewer.additionalLayers.gltf_models.on(schinta3d.EventType.click, (event) => {
const { id, options } = event.graphic
console.log(options.name)
// 模型描边-start 参考:https://zhuanlan.zhihu.com/p/407871786
let picked=event.pickedObject
if (picked && picked.primitive) {
let primitive = picked.primitive
let pickIds = primitive._pickIds;//Entity、Primitive
//已经单体化的3D Tiles或者其他pickObject本身带有pickId属性的情况
let pickId = picked.pickId;
//未单体化的3D Tiles
if (!pickId && !pickIds && picked.content) {
pickIds = picked.content._model._pickIds;
}
if (!pickId) {
if (picked.id) {
//Entity
pickId = pickIds.find(pickId => {
return pickId.object == picked;
})
} else if (pickIds) {
pickId = pickIds[0]
}
}
this.mapViewer.highlightPicked([{
pickId: pickId
}]);
// 模型描边-end
}
4、3DTiles点击对象为模型时 文章来源:https://uudwc.com/A/Ykn8
const tilesetLayer = new schinta3d.layer.TilesetLayer({...opts, preloadWhenHidden: true, preloadFlightDestinations: true, preferLeaves: true })
// 左键单击 鼠标事件
tilesetLayer.on(schinta3d.EventType.click, (event) => {
this.tilesetClicked.next(event);
// console.log(event.pickedObject)
this.highlightPicked([event.pickedObject]);
});
文章来源地址https://uudwc.com/A/Ykn8