一、封装创建视锥体的类(用全局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:垂直边和水平边的比值。