Javascript Cesiumjs根据矢量计算俯仰、偏航和航向
我有一个Cesium的模型加载到场景中,我有两个点,我想用它们来计算模型的方向,这就是我创建的函数Javascript Cesiumjs根据矢量计算俯仰、偏航和航向,javascript,rotation,linear-algebra,quaternions,cesium,Javascript,Rotation,Linear Algebra,Quaternions,Cesium,我有一个Cesium的模型加载到场景中,我有两个点,我想用它们来计算模型的方向,这就是我创建的函数 // calculate the direction which the model is facing calculateOrientation({ position, nextPosition }) { let dir = new Cesium.Cartesian3(); let normalizedDir = new Cesium.Cartesian3(); Ce
// calculate the direction which the model is facing
calculateOrientation({ position, nextPosition }) {
let dir = new Cesium.Cartesian3();
let normalizedDir = new Cesium.Cartesian3();
Cesium.Cartesian3.subtract(nextPosition, position, dir);
Cesium.Cartesian3.normalize(dir, normalizedDir);
var heading = Math.acos(normalizedDir.x);
var pitch = Math.acos(normalizedDir.y);
var roll = 0;
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
return orientation;
}
但是我得到的旋转没有任何意义。我的数学错了吗
更新
在@Keshet给出第一个答案后,我查阅了如何找到平面和向量之间的角度。我想如果我找到每个平面的法线和-90之间的角度,我应该得到正确的角度,但我不确定这是否正确
我也不知道铯轴是如何工作的,我也找不到任何描述它的文件。例如XY平面等
let dir = new Cesium.Cartesian3();
let xyNormal = new Cesium.Cartesian3(0,0,1);
let xzNormal = new Cesium.Cartesian3(0,1,0);
let yzNormal = new Cesium.Cartesian3(1,0,0);
Cesium.Cartesian3.subtract(nextPosition, position, dir);
let xyAngle = Cesium.Math.PI_OVER_TWO - Cesium.Cartesian3.angleBetween(dir, xyNormal);
let xzAngle = Cesium.Math.PI_OVER_TWO - Cesium.Cartesian3.angleBetween(dir, xzNormal);
let yzAngle = Cesium.Math.PI_OVER_TWO - Cesium.Cartesian3.angleBetween(dir, yzNormal);
更新2
以下是使用atan2的@IIan建议代码:
Cesium.Cartesian3.subtract(position, nextPosition, dir);
// create the mapped to plane vectors, and get the
// normalized versions
let xyMappedVectorNormalized = new Cesium.Cartesian3(0, 0, 0);
let xyMappedVector = new Cesium.Cartesian3(dir.x, dir.y, 0);
let xzMappedVectorNormalized = new Cesium.Cartesian3(0, 0, 0);
let xzMappedVector = new Cesium.Cartesian3(dir.x, 0, dir.z);
let yzMappedVectorNormalized = new Cesium.Cartesian3(0, 0, 0);
let yzMappedVector = new Cesium.Cartesian3(0, dir.y, dir.z);
Cesium.Cartesian3.normalize(xyMappedVector, xyMappedVectorNormalized);
Cesium.Cartesian3.normalize(xzMappedVector, xzMappedVectorNormalized);
Cesium.Cartesian3.normalize(yzMappedVector, yzMappedVectorNormalized);
// calculate the angles
let xyAngle = Math.atan2(xyMappedVectorNormalized.y, xyMappedVectorNormalized.x);
let xzAngle = Math.atan2(xzMappedVectorNormalized.z, xzMappedVectorNormalized.x);
let yzAngle = Math.atan2(yzMappedVectorNormalized.z, yzMappedVectorNormalized.y);
首先,我们需要解释航向、俯仰和横滚角代表什么
var heading = Math.acos(normalizedDir.x);
var pitch = Math.acos(normalizedDir.y);
你需要得到每个平面上的总角度
在XY平面上,将使用规格化的|(X,Y)|
在XZ平面上,将使用规格化的|(X,Z)|
在YZ平面上,您将使用规格化的|(Y,Z)|
更新 |(X,Y)|表示单位圆上的一点 式中(sin(θ),cos(θ))=|(X,Y)| 即当θ=0时,|(X,Y)|=(1,0) 当θ=PI/2时,|(X,Y)|=(0,1) 这个θ就是你用来做航向的角度
然后,可以调用arctan2函数来计算相对于平面的角度 atan2(y,x)=θ,其中[x,y]是使用相应的归一化2D向量从上面计算得出的 注意:atan2给出了以(-PI,PI]为界的角度 示例 如果三维向量为(1,2,3)--在XY平面上X=1,Y=2 然后,如果规范化(1,2)=>(1/sqrt(5),2/sqrt(5))
然后你可以使用atan2(2/sqrt(5),1/sqrt(5)来计算航向的弧度角度反对票不会给出如何改进这个问题的反馈。@iAnkeshet |(X,Y)|表示什么量级?我的线性代数生锈了什么是(X,Y)?我在问题中给出了一个例子。再看看答案。所以,我定义了X,Y代表的是什么。基本上,
atan2(normalizedDir.X,normalizedDir.Y)
?是的,但不是规范化的3D向量,规范化的2D向量。相反。atan2(Y,X)——函数就是这样工作的