用Cesium.js围绕顶点旋转锥体

时间:2017-03-22 02:53:21

标签: javascript 3d cesium

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

我在以下链接中找到了以下示例: https://groups.google.com/forum/#!topic/cesium-dev/f9ZiSWPMgus

但它只显示了如何将圆锥体旋转90度,如果选择不同的滚动值,如45度或30度,它会变形,顶点会在错误的位置结束。

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

我还希望在旋转锥体时延长锥体的长度,以便当它旋转30度时,锥体的底部仍然会在那个方向上到达地面,而顶点仍然保持不变在原来的地方,我不知道那是多么可行。

这是以下代码示例的故障: 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);

2 个答案:

答案 0 :(得分:1)

当您想将圆柱体指向由方位角和仰角指定的特定方向时,我想到了旋转和平移圆柱体。

/**
 * 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];
}

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

这并不能让您获得想要的行为,只要旋转圆柱体就可以延长圆柱体,但希望能对您有所帮助。

答案 1 :(得分:0)

我和你有同样的问题。这是我的参考代码。这是计算任意角度的圆锥矩阵的功能。

Enum