Entity rotation based on directional vector

I know Cesium has a lot of very helpful translation/rotation methods that can be used to move things about.

I’ve been given a point and a directional vector to draw a cylinder on and the cylinder needs to be rotated along the vector length wise.

I know the math to get a quaternion to do the rotation but didn’t know if Cesium had a method that would take the pointing vector and accomplish the same thing without me having to write one myself.

I’m going to sift through the documentation but figured I would ask here as well in hopes of getting a quick answer.

Thanks!

Hello,

We have Quaternion.fromAxisAngle and Quaternion.fromHeadingPitchRoll, but I’m not sure if those would be helpful for your exact case.

I think this function might help? https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Core/Transforms.js#L785

It takes in a position and a vector and returns a rotation matrix.

Best,

Hannah

I do

Cesium.Matrix3.pointAt= function(point){
  point= point.clone();
  var vec3= Cesium.Cartesian3;
  vec3.negate(point,point);//handedness or something?
  vec3.normalize(point, point);

  var fwd = point.clone();
  var up = new vec3();
  var right= new vec3();

  var zdotY= fwd.y;
  var fwd_mul_zdoty= new vec3();
  vec3.multiplyByScalar(fwd, zdotY, fwd_mul_zdoty);
  up.y= 1.;
  vec3.negate(up,up);
  vec3.add(up,fwd_mul_zdoty,up);
  vec3.negate(up,up);
  vec3.normalize(up,up);

  vec3.cross(up, fwd, right);

  var ret= new Cesium.Matrix3();
  Cesium.Matrix3.setColumn(ret, 0,right, ret);
  Cesium.Matrix3.setColumn(ret, 1,up, ret);
  Cesium.Matrix3.setColumn(ret, 2,fwd, ret);

  return ret;
}

Someone contribute this for me as I am too lazy :d
Might need tweaked for orthonormality or something, I've not tested it on a perfect square

Thank you guys so far!

I’m a bit confused on Quaternion.fromAxisAngle though.

Below is some code that can be pasted into the sandcastle.

If I am trying to rotate the cone from the the default vector (red) to the directional vector between the start/end points (green/yellow). The center point of the cone is placed half way between the start/end points. Would the Quaternion axis not be the cross of the two vectors (orange) and the angle be the angle between the two vectors (Cartesian3.angleBetween) ???

The rotation looks way off.

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var scene = viewer.scene;

var ellipsoid = scene.globe.ellipsoid;

//START, END, and CENTER POINTS DRAWN

var currentPos = {x:-8035730.572402987,y:-39529022.92437431,z:-12287146.028328177};

var targetPos = {x:1553245.4815050373,y:-4293756.086433321,z:4670055.649305257};

var vector = {x: targetPos.x - currentPos.x, y: targetPos.y - currentPos.y, z: targetPos.z - currentPos.z};

var centerPoint = {};

centerPoint.x = currentPos.x + (0.5 * vector.x);

centerPoint.y = currentPos.y + (0.5 * vector.y);

centerPoint.z = currentPos.z + (0.5 * vector.z);

var alignment = viewer.entities.add({

polyline : {

    positions : [currentPos, centerPoint],

    followSurface: false,

    width : 2,

    material : Cesium.Color.LIME

}

});

var vector1 = viewer.entities.add({

polyline : {

    positions : [centerPoint, targetPos],

    followSurface: false,

    width : 2,

    material : Cesium.Color.YELLOW

}

});

var vector2 = viewer.entities.add({

polyline : {

    positions : [{x:0, y:0, z:1}, centerPoint],

    followSurface: false,

    width : 2,

    material : Cesium.Color.RED

}

});

var dist = Math.sqrt(Math.pow((targetPos.x - currentPos.x), 2) + Math.pow((targetPos.y - currentPos.y), 2) + Math.pow((targetPos.z - currentPos.z), 2));

//THIS IS THE IMPORTANT BIT

var v1 = Cesium.Cartesian3.normalize(vector, {});

var v2 = Cesium.Cartesian3.normalize(centerPoint, {});

var a = Cesium.Cartesian3.cross(v2, v1, {});

var an = Cesium.Cartesian3.normalize(a, {});

var r = Cesium.Cartesian3.angleBetween(v2, v1);

var orientation = new Cesium.Quaternion.fromAxisAngle(an, r, {});

//THE CONE BEING ROTATED

var goldCone = viewer.entities.add({

position: centerPoint,

orientation: orientation,

cylinder : {

    length :  dist,

    topRadius : 0.0,

    bottomRadius : 4041689.062608033,

    material : Cesium.Color.GOLD.withAlpha(0.2)

}

});

//VISUALIZE VECTORS

var len = 5000000;

var ax = {x: centerPoint.x + (a.x * len), y: centerPoint.y + (a.y * len), z: centerPoint.z + (a.z * len)};

var axis = viewer.entities.add({

polyline : {

    positions : [centerPoint, ax],

    followSurface: false,

    width : 5,

    material : Cesium.Color.ORANGE

}

});

var ax1 = {x: centerPoint.x + (v1.x * len), y: centerPoint.y + (v1.y * len), z: centerPoint.z + (v1.z * len)};

var vector1 = viewer.entities.add({

polyline : {

    positions : [centerPoint, ax1],

    followSurface: false,

    width : 5,

    material : Cesium.Color.YELLOW

}

});

var ax2 = {x: centerPoint.x + (v2.x * len), y: centerPoint.y + (v2.y * len), z: centerPoint.z + (v2.z * len)};

var vector2 = viewer.entities.add({

polyline : {

    positions : [centerPoint, ax2],

    followSurface: false,

    width : 5,

    material : Cesium.Color.RED

}

});

viewer.zoomTo(viewer.entities);

``