cesium创建视椎体(可动态旋转)

一、封装创建视锥体的类(用全局viewer)

export 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();
    }

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

    // 清除视锥体
    clearFrustum(){
        if(this.frustumPrimitive){
            viewer.scene.primitives.remove(this.frustumPrimitive);
            this.frustumPrimitive = 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 instanceGeo = new Cesium.GeometryInstance({
            geometry: new Cesium.FrustumGeometry({
	            frustum: frustum,
	            origin: this.position,
	            orientation: this.orientation,
	            vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
	        }),
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(1.0, 0.0, 0.0, 0.5)
                ),
            },
        });
        let instanceGeoLine = new Cesium.GeometryInstance({
            geometry: new Cesium.FrustumOutlineGeometry({
	            frustum: frustum,
	            origin: this.position,
	            orientation: this.orientation,
	        }),
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(1.0, 0.0, 0.0, 0.5)
                ),
            },
        });
        let primitive = new Cesium.Primitive({
            geometryInstances: [instanceGeo,instanceGeoLine],
            appearance: new Cesium.PerInstanceColorAppearance({
                closed: true,
                flat: true,
            }),
            asynchronous: false,
        });
        this.frustumPrimitive = viewer.scene.primitives.add(primitive);
    }
    }
}

注:ts写法与上诉文件仅开头部分不同

export class CreateFrustum{
   position: any;
   orientation:any;
   fov:any;
   near:any;
   far:any;
   aspectRatio:any;
   frustumPrimitive:any;
   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();
   }
}

视椎体与视椎线分开封装

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;

调用

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

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

let head = 0;
let pitch = 0;
let roll = 0;
let hpr = new Cesium.HeadingPitchRoll(heading,pitch,roll)
let orientation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);

// 创建视锥体
let createFrustum = new CreateFrustum({
    position: origin,
    orientation: orientation,
    fov: 90,
    near: 10,
    far: 100,
    aspectRatio: 600 / 1080,
});

// 动态修改视锥体的姿态
setInterval(()=>{
    // 绕Z轴旋转-航向
    // head += 0.01;

    // 绕X轴旋转-俯仰
    // pitch += 0.01;

    // 绕Y轴旋转-翻滚
    roll += 0.01;
    hpr = new Cesium.HeadingPitchRoll(heading,pitch,roll)
    orientation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
    createFrustum.update(origin, orientation);
}, 200)
},

二、传入viewer

/**
 * 绘制视锥
 */
export default class {
    constructor(viewer, options) {
        this.viewer = viewer;
        this._position = options.position;
        this._orientation = options.orientation;
        this._fov = options.fov || 35.0;
        this._near = options.near||0.1;
        this._far = options.far||20;
        this._fill = options.fill || false;
        this._closed = options.closed || false;
        this._color = options.color || new Cesium.Color(1.0, 0.0, 0.0, 0.2);
        this._outlineColor=options.outlineColor||new Cesium.Color(0.0, 0.0, 0.0, 0.5);
        this._flat = options.flat || true;
        this.update(this._position,this._orientation);
    }

    update(position, orientation) {
        this._position = position;
        this._orientation = orientation;
        this._add();
    }

    _add() {
        this._clear();
        this._addFrustum();
        this._addOutline();
    }

    _clear() {
        this._clearFrustum();
        this._clearOutline();
    }

    _addFrustum() {
        if (!Cesium.defined(this._position)) {
            return;
        }
        if (!Cesium.defined(this.viewer)) {
            return;
        }
        var scene = this.viewer.scene;
        var frustum = new Cesium.PerspectiveFrustum({
            fov: Cesium.Math.toRadians(this._fov),
            aspectRatio: scene.canvas.clientWidth / scene.canvas.clientHeight,
            near: this._near,
            far: this._far,
        });
        this._frustum=frustum;

        var frustumGeometry = new Cesium.FrustumGeometry({
            frustum: frustum,
            origin: this._position,
            orientation: this._orientation,
            vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
        });

        var frustumGeometryInstance = new Cesium.GeometryInstance({
            geometry: frustumGeometry,
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    this._color
                ),
            },
            id: "frustum",
        });

        this._frustumPrimitive = scene.primitives.add(
            new Cesium.Primitive({
                geometryInstances: frustumGeometryInstance,
                appearance: new Cesium.PerInstanceColorAppearance({
                    closed: this._closed,
                    flat: this._flat,
                }),
                asynchronous:false
            })
        );
    }

调用

//视锥绘制开始
var mCameraHeightThanBottom = modelm.boundingSphere.radius / 1.7;
let mCameraLoc = matrixUtil.localToWorldCartesian3(
  worldCoorOrigin,
  x - localconfig.x,
  y - localconfig.y,
  z + mCameraHeightThanBottom - localconfig.z
);
let m2 = Cesium.Transforms.eastNorthUpToFixedFrame(mLoc);
var rotation222 = Cesium.Matrix4.getMatrix3(m2, new Cesium.Matrix3());
Cesium.Matrix3.multiply(
  rotation222,
  Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(angle + 90)),
  rotation222
);
Cesium.Matrix3.multiply(
  rotation222,
  Cesium.Matrix3.fromRotationX(Cesium.Math.PI_OVER_TWO * 0.91),
  rotation222
);
var orientation222 = Cesium.Quaternion.fromRotationMatrix(rotation222);
this.drawViewFrustum(mCameraLoc, orientation222);//画
//视锥绘制结束
this.angleHistory = angle; //保存当前角度
modelm.modelMatrix = m;//新模型矩阵,更新模型位置和角度

三、补充说明

视锥的形态和初始姿态(heading>0,pitch>0,roll>0)
在这里插入图片描述
视锥构造参数:
在这里插入图片描述
frustum:视锥本体,

origin:轴心,就是顶点的位置,

orientation:决定相机看的方向,

vertexFormat:该参数和视锥绘制没有关系,保持默认即可。

frustum参数

在这里插入图片描述
near和far参数:
在这里插入图片描述
fov:查看的视场角,绕z轴旋转,以弧度方式输入。

aspectRatio:垂直边和水平边的比值。
在这里插入图片描述

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值