使用 Cesium.js 围绕顶点旋转锥体 [英] Cone rotation around apex with Cesium.js

查看:104
本文介绍了使用 Cesium.js 围绕顶点旋转锥体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从圆锥的顶点而不是中心旋转圆锥,以便顶点保持在相同的位置.

I am trying to rotate a cone from its apex, rather than its centre, so that the apex remains in the same position.

我从以下链接中找到了以下示例:https://groups.google.com/forum/#!topic/铯开发/f9ZiSWPMgus

I've found the example below from the following link: https://groups.google.com/forum/#!topic/cesium-dev/f9ZiSWPMgus

但它只显示了如何将圆锥旋转 90 度,如果您为滚动选择不同的值,例如 45 或 30 度,它会倾斜,并且顶点最终会出现在错误的位置.

But it only shows how to rotate the cone by 90 degrees, if you choose a different value for roll, like 45 or 30 degrees, it gets skewed, and the apex ends up in the wrong place.

我知道它与偏移量有关,但无法从那里取得任何进展.有没有办法计算任何滚动值的正确偏移量?

I know its something to do with the offset, but can't make any progress from there. Is there some way to calculate the correct offset for any value of roll?

我还想在旋转时延长锥体的长度,例如,当它旋转 30 度时,锥体的底部仍将在该方向上到达地面,而顶点仍保持在其原来的地方,我不知道那是否可行.

I'd also like to extend the length of the cone when its rotated, so that when its rotated 30 degrees for example, the bottom of the cone will still reach the ground in that direction, while the apex still remains in its original place, I don't know how feasible that is though.

这是下面代码示例的一个小故障:https://glitch.com/edit/#!/cesium-cone-rotation

Here's a glitch of the code sample below: https://glitch.com/edit/#!/cesium-cone-rotation

var viewer = new Cesium.Viewer('cesiumContainer');

var position = Cesium.Cartesian3.fromDegrees(-75, 40, 90); 

//Original, non-rotated cone for comparison.
viewer.entities.add(new Cesium.Entity({
    position: position,
    point: {
        color: Cesium.Color.YELLOW,
        show: true,
        pixelSize: 20
    },
    cylinder: {
        topRadius: 0,
        bottomRadius: 45,
        length: 180,
        material: Cesium.Color.YELLOW.withAlpha(0.5)
    }
}));

var heading = Cesium.Math.toRadians(0.0);
var pitch = Cesium.Math.toRadians(0.0);
var roll = Cesium.Math.toRadians(90.0);
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);

//Create a rotation
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

// offset the rotation so it's rotating from the apex of the cone, instead of the centre
var offset = new Cesium.Cartesian3(0, 90, 90);

//Create a transform for the offset.
var enuTransform = Cesium.Transforms.eastNorthUpToFixedFrame(position);

//Transform the offset
Cesium.Matrix4.multiplyByPointAsVector(enuTransform, offset, offset);

//Add the offset to the original position to get the final value.
Cesium.Cartesian3.add(position,  offset,  position);

viewer.entities.add(new Cesium.Entity({
    position: position,
    orientation: orientation,
    point: {
        color: Cesium.Color.YELLOW,
        show: true,
        pixelSize: 20
    },
    cylinder: {
        topRadius: 0,
        bottomRadius: 45,
        length: 180,
        material: Cesium.Color.YELLOW.withAlpha(0.5)
    }
}));

viewer.zoomTo(viewer.entities);

推荐答案

当您想将圆柱体指向由方位角和仰角指定的特定方向时,我想出了以下方法来旋转和平移圆柱体.

Here's what I came up with to rotate and translate a cylinder when you want to point it in a specific orientation specified by an azimuth and elevation.

/**
 * Calculate the position and orientation needed for the beam entity.
 * @param {Cesium.Cartesian3} position - The position of the desired origin.
 * @param {Number} az - The azimuth of the beam center in radians.
 * @param {Number} el - The elevation of the beam center in radians.
 * @param {Number} range - The range of the beam in meters.
 * 
 * @returns {[Cesium.Cartesian3, Cesium.Quaternion]} Array of the position and
 * orientation to use for the beam.
 */
calculateBeam(position, az, el, range) {
    // The origin of Cesium Cylinder entities is the center of the cylinder.
    // They are also pointed straight down towards the local East-North plane. The
    // math below rotates and translates the cylinder so that its origin is the tip
    // of the cylinder and its orientation is pointed in the direction specified by
    // the az/el.
    let heading = az - Cesium.Math.toRadians(90);
    let pitch = Cesium.Math.toRadians(90) + el;
    let hpr = new Cesium.HeadingPitchRoll(heading, pitch, 0.0);
    let x = range/2.0 * Math.sin(pitch) * Math.cos(heading);
    let y = -range/2.0 * Math.sin(heading) * Math.sin(pitch);
    let z = -range/2.0 * Math.cos(pitch);
    var offset = new Cesium.Cartesian3(x, y, z);
    let enuTransform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
    Cesium.Matrix4.multiplyByPointAsVector(enuTransform, offset, offset);
    let newPosition = Cesium.Cartesian3.add(position, offset, new Cesium.Cartesian3());
    let orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
    return [newPosition, orientation];
}

这将为您提供创建圆柱实体时要使用的位置/方向.它将放置圆柱体,使圆柱体的尖端位于位置",并指向方位角和仰角指定的方向.方位角是相对于北向东的正角.高程相对于东北平面,正角向上.范围是圆柱体的长度.

This will give you the position/orientation to use when you create the cylinder entity. It will place the cylinder such that the tip of the cylinder is located at 'position' and it is pointed in the direction specified by the azimuth and elevation. Azimuth is relative to North with positive angles towards East. Elevation is relative to the North-East plane, with positive angles up. Range is the length of the cylinder.

就在旋转圆柱体时延长圆柱体而言,这并不能满足您想要的行为,但希望它有所帮助.

This doesn't get you the behavior you wanted as far as lengthening the cylinder as you rotate it, but hopefully it helps.

这篇关于使用 Cesium.js 围绕顶点旋转锥体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆