问题描述
所以我正在研究游戏引擎,但是我对线性代数的了解有限-仅是最近几天我自学的知识-尽管我成功地实现了四元数,但我不能完全理解它们。
根据收集的数据,如果我有单位四元数(格式为[w,x,y,z])[0.92387956、0.38268343、0.0、0.0](围绕+ x轴旋转45度),然后乘以通过另一个单位四元数[0.7071068,0.0,0.70710677,0.0](围绕+ y轴90度),它应该产生一个新的四元数,该四元数是原始的围绕x轴45度,然后围绕全局y轴旋转90度,而是绕局部y轴(“偏航”轴)旋转它。
如果我的理解不正确,是否有人可以帮助我找到预期的行为?以下是我使用的一些代码。附带说明一下,我写了所有这些内容,因此很有可能完全错误。
public class Quaternion
{
public Quaternion(float x,float y,float z,float w)
{
float mod = (float)Math.sin(w / Mathf.RAD2DEG/2);
this.x = x * mod;
this.y = y * mod;
this.z = z * mod;
//System.out.println(Math.cos(w / Mathf.RAD2DEG /2));
this.w = (float)Math.cos(w / Mathf.RAD2DEG /2);
}
public Quaternion multiplyBy(Quaternion q)
{
setRaw(
w * q.x + x * q.w + y * q.z - z * q.y,w * q.y + y*q.w + z * q.x - x * q.z,w * q.z + z * q.w + x * q.y - y * q.x,w * q.w - x * q.x - y * q.y - z *q.z);
normalize();
return this;
}
public Quaternion setRaw(float x,float w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
}
public float magnitude()
{
return Mathf.sqrt(w*w + x*x + y*y + z*z);
}
public Quaternion normalize()
{
float norm = magnitude();
w/= norm;
x /= norm;
y /= norm;
z /= norm;
return this;
}
//does not return a real Quaternion but merely uses it as a means to store 4 floating points
public Quaternion angleAxis()
{
if(w > 1)
normalize();
float newAngle =2* (float)Math.acos(w);
float s = Mathf.sqrt(1-w *w);
//.out.println(newAngle);
///System.out.println(newAngle * Mathf.RAD2DEG);
//System.out.println();
return new Quaternion().setRaw(x,y,z,newAngle * Mathf.RAD2DEG);
}
}
public class ExampleClass
{
public static void main(String[] args)
{
//formatted x,w
Quaternion xrot = new Quaternion(1,45);
//evaluates to [0.92387956,0.38268343,0.0,0.0] formatted w,x,z
Quaternion yrot = new Quaternion(0,1,90);
//evaluates to [0.7071068,0.70710677,z
xrot.multiplyBy(yrot);
//evals to [0.9999837,0.0015426596,0.0037243098,0.0]
//an online quat calculator states the result should be [0.65328,0.2706,0.65328,0.2706]
}
}
最后一点,我使用OpenGL在3d中渲染视图,并且OpenGL接受由angleAxis()方法提供的旋转的角轴表示。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)