Cesium 航线检测是否碰撞点云

效果:

核心代码:

 1. 检测碰撞点云:
/**
 * 判断两点之间是否碰撞了点云
 * @param  {
 *    viewer
 *    curPosition: Cesium.Cartesian3  起点
 *    nextPosition: Cesium.Cartesian3  终点
 * } 
 */
export const hasCollision = (viewer, curPosition, nextPosition) => {
    let isCollision = false;
    let { pickArr } = pickFromRay(viewer, curPosition, nextPosition);
    if (pickArr && pickArr.length) {
        for (let idx = 0; idx < pickArr.length; idx++) {
            let primitive = pickArr[idx]?.object?.primitive;
            // 拾取到点云并且位于中间位置,即碰撞了点云
            if(Cesium.defined(primitive) && primitive instanceof Cesium.Cesium3DTileset && idx != pickArr.length - 1) {
                isCollision = true;
            }
        }
    }
    return isCollision;
}

/**
 * A点到B点的射线,并拾取物体
 * @param  {
 *    viewer
 *    originPoint: Cesium.Cartesian3  起点
 *    sourcePoint: Cesium.Cartesian3  终点
 * } 
 */
export const pickFromRay = (viewer, originPoint, sourcePoint, limit = 20) => { 
    let dir = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(sourcePoint, originPoint, new Cesium.Cartesian3()), new Cesium.Cartesian3());
    let error = !(dir.x && dir.y && dir.z);   //如果两个点坐标一样,则计算出来的会是NaN
    if(error) {
        return {
            ray: null,
            pickArr: []
        }
    }
    let ray = new Cesium.Ray(originPoint, dir);
    let pickArr = error ? [] : viewer.scene.drillPickFromRay(ray, limit);
    return {
      ray,
      pickArr
    }
}
2. 绘制航线:
// Vue:

// 画线
const drawPolyline = function(entityArr) {
	removeEntity(['line']);
	let normalColor = new Cesium.Color.fromCssColorString('#006EFF').withAlpha(.8);
	let warnColor = new Cesium.Color.fromCssColorString('#F25757').withAlpha(.8);
	for (let idx = 0; idx < entityArr.length; idx++) {
		if(idx == 0) continue;
		let curPosition = entityArr[idx].position._value;
		let prePosition = entityArr[idx - 1].position._value;
		/* 风险判断 */
		//判断是否碰撞
		let isCollision = hasCollision(viewer, curPosition, prePosition); 
		viewer.entities.add({
			name: "line",
			show: true,
			polyline: {
				positions: [curPosition, prePosition],
				width: 3,
				material: isCollision ? warnColor : normalColor,
			}
		})
		if(entityArr[idx].name == 'wayPoint') { // 航点名
			entityArr[idx].point.outlineColor = isCollision ? warnColor : normalColor;
		}
	}
}

//根据name移除实体
const removeEntity = (nameArr) => {
	for(let i = viewer.entities.values.length - 1; i >= 0; i-- ) {
		if(nameArr.includes(viewer.entities.values[i].name)) {
            viewer.entities.remove(viewer.entities.values[i]);
        }
	}
}

猜你喜欢

转载自blog.csdn.net/weiliangLAN/article/details/141672277