Cesium开源

Cesium 视锥体 Frustum

2022-02-24  本文已影响0人  WebGiser

CreateFrustum.js 封装创建视锥体的类

class CreateFrustum{
    constructor(options){
        this.position = options.position;
        this.orientation = options.orientation;
        this.fov = options.fov || 30;
        this.near = options.near || 10;
        this.far = options.far || 100;
        this.aspectRatio = options.aspectRatio;
        this.add();
    }

    // 更新视锥体的姿态
    update(position, orientation){
        this.position = position;
        this.orientation = orientation;
        this.add();
    }

    // 创建视锥体和轮廓线
    add(){
        this.clear();
        this.addFrustum();
        this.addOutline();
    }

    // 清除视锥体和轮廓线
    clear(){
        this.clearFrustum();
        this.clearOutline();
    }

    // 清除视锥体
    clearFrustum(){
        if(this.frustumPrimitive){
            viewer.scene.primitives.remove(this.frustumPrimitive);
            this.frustumPrimitive = null;
        }
    }

    // 清除轮廓线
    clearOutline(){
        if(this.outlinePrimitive){
            viewer.scene.primitives.remove(this.outlinePrimitive);
            this.outlinePrimitive = null;
        }
    }

    // 创建视锥体
    addFrustum(){
        let frustum = new Cesium.PerspectiveFrustum({
            // 查看的视场角,绕Z轴旋转,以弧度方式输入
            // fov: Cesium.Math.PI_OVER_THREE,
            fov: Cesium.Math.toRadians(this.fov),
            // 视锥体的宽度/高度
            aspectRatio: this.aspectRatio,
            // 近面距视点的距离
            near: this.near,
            // 远面距视点的距离
            far: this.far,
        });
        let geometry = new Cesium.FrustumGeometry({
            frustum: frustum,
            origin: this.position,
            orientation: this.orientation,
            vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
        });
        let instance = new Cesium.GeometryInstance({
            geometry: geometry,
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(1.0, 0.0, 0.0, 0.5)
                ),
            },
        });
        let primitive = new Cesium.Primitive({
            geometryInstances: instance,
            appearance: new Cesium.PerInstanceColorAppearance({
                closed: true,
                flat: true,
            }),
            asynchronous: false,
        });
        this.frustumPrimitive = viewer.scene.primitives.add(primitive);
    }

    // 创建轮廓线
    addOutline(){
        let frustum = new Cesium.PerspectiveFrustum({
            // 查看的视场角度,绕Z轴旋转,以弧度方式输入
            // The angle of the field of view (FOV), in radians. 
            // This angle will be used as the horizontal FOV if the width is greater than the height, otherwise it will be the vertical FOV.
            fov: Cesium.Math.toRadians(this.fov),
            // 视锥体的宽度/高度
            aspectRatio: this.aspectRatio,
            // 近面距视点的距离
            near: this.near,
            // 远面距视点的距离
            far: this.far,
        });
        let geometry = new Cesium.FrustumOutlineGeometry({
            frustum: frustum,
            origin: this.position,
            orientation: this.orientation,
            vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
        });
        let instance = new Cesium.GeometryInstance({
            geometry: geometry,
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(1.0, 1.0, 0.0, 1.0)
                ),
            },
        });
        let primitive = new Cesium.Primitive({
            geometryInstances: instance,
            appearance: new Cesium.PerInstanceColorAppearance({
                closed: true,
                flat: true,
            }),
            asynchronous: false,
        });
        this.outlinePrimitive = viewer.scene.primitives.add(primitive);
    }
}

export default CreateFrustum;

创建视锥体、视点、坐标轴

    test() {
            // 创建视点
            let origin = Cesium.Cartesian3.fromDegrees(120, 30);
            this.createPoint(origin);

            // 创建XYZ局部坐标轴
            this.createFrame(origin);

            // 视角定位
            viewer.camera.flyTo({
                destination: origin,
            });

            // 确定相对于视点的旋转矩阵
            let enu = Cesium.Transforms.eastNorthUpToFixedFrame(origin);
            let rotation = Cesium.Matrix3.getRotation(enu, new Cesium.Matrix3());
            let orientation = Cesium.Quaternion.fromRotationMatrix(rotation);
            
            // 创建视锥体
            let createFrustum = new CreateFrustum({
                position: origin,
                orientation: orientation,
                fov: 90,
                near: 10,
                far: 100,
                aspectRatio: 600 / 1080,
            });

            // 动态修改视锥体的姿态
            let head = 0;
            let pitch = 0;
            let roll = 0;
            let rot = orientation;
            setInterval(()=>{
                // 绕Z轴旋转-航向
                // head += 0.01;
                // rot = Cesium.Matrix3.multiply(
                //  rotation,
                //  Cesium.Matrix3.fromRotationZ(head),
                //  new Cesium.Matrix3()
                // );

                // 绕X轴旋转-俯仰
                // pitch += 0.01;
                // rot = Cesium.Matrix3.multiply(
                //  rotation,
                //  Cesium.Matrix3.fromRotationX(pitch),
                //  new Cesium.Matrix3()
                // );

                // 绕Y轴旋转-翻滚
                roll += 0.01;
                rot = Cesium.Matrix3.multiply(
                    rotation,
                    Cesium.Matrix3.fromRotationY(roll),
                    new Cesium.Matrix3()
                );
                
                orientation = Cesium.Quaternion.fromRotationMatrix(rot);
                createFrustum.update(origin, orientation);
            }, 200)
        },

        // 创建视点
        createPoint(p) {
            return viewer.entities.add({
                position: p,
                point: {
                    pixelSize: 10,
                    color: new Cesium.Color(1.0, 1.0, 0.0, 1.0),
                },
            });
        },

        // 创建坐标系
        createFrame(p) {
            // X轴:红色,Y轴:绿色,Z轴:蓝色
            let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(p);
            viewer.scene.primitives.add(
                new Cesium.DebugModelMatrixPrimitive({
                    modelMatrix: modelMatrix,
                    length: 30000.0,
                    width: 3.0,
                })
            );
        },

效果

1645771985(1).png
上一篇下一篇

猜你喜欢

热点阅读