How to make the cylinder rotate around a point

Hello community!
I try to rotate the object in the following way, but it doesn’t seem normal. How can I normally rotate the object around a certain point.

const viewer = new Cesium.Viewer("cesiumContainer");
const center = new Cesium.Cartesian3.fromDegrees(117, 39, 30000);
const point = viewer.entities.add({
  position:center,
  point:{
    pixelSize:5,
    color:Cesium.Color.RED
  }
});
const cylinder = viewer.entities.add({
  position:new Cesium.Cartesian3.fromDegrees(117, 39, 22500),
  orientation:Cesium.Transforms.headingPitchRollQuaternion(center, new Cesium.HeadingPitchRoll(0, Cesium.Math.PI_OVER_TWO, 0)),
  cylinder:{
    length:15000,
    topRadius:0.0,
    bottomRadius:7500,
    material: Cesium.Color.RED.withAlpha(0.5)
  }
});
viewer.flyTo(cylinder);

demo

Hi @zhanglin ,

You can use CallbackProperty to keep changing heading. Check this modified example.

  • Regards

Thank you for your reply, ha ha! I may not express my idea. My idea is that the cone rotates around the top of the cone,By default, a cone rotates around its center
like this
image

In that case you need to change the center point position to cone’s top ( that should be half of the length of the cone).

In this way, the top of the cone can be placed at this point, but the top of the cone will not be at this point after rotation. My idea is that no matter how the cone rotates and the top does not change its position, how should this be realized?

You can check this similar post. I hope it will help you.

1 Like

This is really a great link. If you rotate pitch and roll at the same time, how to calculate their offset.

const Heading = 0;
const Pitch = 60;
const Roll = 60;

const orientation = Cesium.Transforms.headingPitchRollQuaternion(center, new Cesium.HeadingPitchRoll(0, Pitch , Roll))

any idea about this, dear partner?

Here is a method to offset the center of the cone to the top.

  computeoffset() {

    //中心距离顶部的高度
    const oldLength = this.length / 2

    const oldX = 0
    const oldY = 0
    const oldZ = -oldLength
    let newX = 0
    let newY = 0
    let newZ = 0

    const pitchRadians = Cesium.Math.toRadians(this.pitch)
    const rollRadians = Cesium.Math.toRadians(this.roll)

    //旋转roll
    newY = oldY + oldLength * Math.sin(rollRadians)
    newZ = oldZ + oldLength - oldLength * Math.cos(rollRadians)
    const pitchTouying = oldLength * Math.cos(rollRadians) //进行pitch变化时在Y轴和Z轴组成的平面的投影

    //旋转pitch
    newX = oldX + pitchTouying * Math.sin(pitchRadians)
    newZ = newZ + (pitchTouying - pitchTouying * Math.cos(pitchRadians))

    if (this.heading !== 0) {

      const headingTouying = Math.sqrt(Math.pow(Math.abs(newX), 2) + Math.pow(Math.abs(newY), 2)) //进行heading变化时在Y轴和X轴组成的平面的投影

      //旋转heading
      const Xdeg = Cesium.Math.toDegrees(Math.acos(Math.abs(newX) / Math.abs(headingTouying))) //现有投影线与X轴的夹角
      let newXdeg = 0 //旋转heading后与X轴的夹角
      let newXRadians = 0 //旋转heading后与X轴的夹角弧度

      if (newX >= 0 && newY >= 0) {
        newXdeg = this.heading - Xdeg;
      } else if (newX > 0 && newY < 0) {
        newXdeg = this.heading + Xdeg;
      } else if (newX < 0 && newY > 0) {
        newXdeg = this.heading + (180 + Xdeg)
      } else {
        newXdeg = this.heading + (180 - Xdeg)
      }

      if (newXdeg >= 360) {
        newXdeg = 360 - newXdeg
      }

      if (newXdeg >= 0 && newXdeg <= 90) {

        newXRadians = Cesium.Math.toRadians(newXdeg)
        newY = -headingTouying * Math.sin(newXRadians)
        newX = headingTouying * Math.cos(newXRadians)

      } else if (newXdeg > 90 && newXdeg <= 180) {

        newXRadians = Cesium.Math.toRadians(180 - newXdeg)
        newY = -headingTouying * Math.sin(newXRadians)
        newX = -headingTouying * Math.cos(newXRadians)

      } else if (newXdeg > 180 && newXdeg <= 270) {

        newXRadians = Cesium.Math.toRadians(newXdeg - 180)
        newY = headingTouying * Math.sin(newXRadians)
        newX = -(headingTouying * Math.cos(newXRadians))

      } else {

        newXRadians = Cesium.Math.toRadians(360 - newXdeg)
        newY = headingTouying * Math.sin(newXRadians)
        newX = headingTouying * Math.cos(newXRadians)

      }
    }

    const offset = new Cesium.Cartesian3(newX, newY, newZ)

    return offset
  }

      const offset = this.computeoffset()
      const enuTransform = Cesium.Transforms.eastNorthUpToFixedFrame(this.center)
      Cesium.Matrix4.multiplyByPointAsVector(enuTransform, offset, offset)
      const cylindercenter = Cesium.Cartesian3.add(this.center, offset, new Cesium.Cartesian3())

Thanks. That’s quite complicated~ liangleliangle

Do you happen to have a sandcastle example demonstrating this solution?

Thank you