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

查看:89
本文介绍了使用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/cesium-dev/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天全站免登陆