为什么我的四元数不能正确旋转?
好的,我们不是在讨论OpenGL,但是这个将会和OpenGL ES 2.0一起使用。
问题:如何使用以下代码创建和旋转四元数?
我一直在阅读和研究这个问题,但仍然不能完全理解这些概念。 我以为我明白了,但是一旦我开始做一些旋转四元数的计算,我意识到我甚至不能回到我开始的地方。
所以让我们说,我们有一个立方体,它的中心位于(0,0,0)。 我们想在x轴上旋转45度。 我会怎么做? (只有四元数)
假设成功,你将如何从'W'获得旋转量? 我知道'1'表示没有旋转,但如果它旋转了173度呢?
试着旋转到一个给定的方向,45度,然后从W得到这个值。我觉得我需要将角度转换为拉德什么,但不完全确定。 在线教程因人而异。
这是我的代码:
import java.util.Scanner;
import Quaternion;
public class Main {
public static void main(String[] args) {
Quaternion q1 = new Quaternion(0, 0, 0, 1);
Quaternion q2 = new Quaternion(0, 0, 0, (float) Math.cos(toRAD(45.0f) / 2));
q1 = q2.mul(q1);
System.out.println("q1: " + q1.getX() + ", " + q1.getY() + ", " + q1.getZ() + " with " + toANGLE(2.0f * Math.acos(q1.getW())));
}
private static double toRAD(float angle) {
return angle * (Math.PI / 180.0f);
}
private static float toANGLE(double rad) {
return (float) (rad * (180.0f / Math.PI));
}
}
这是一个四元数的代码:
public class Quaternion // Credit goes to 'thebennybox' (http://www.youtube.com/user/thebennybox)
{
private float x;
private float y;
private float z;
private float w;
public Quaternion(float x, float y, float z, float w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public float length()
{
return (float)Math.sqrt(x * x + y * y + z * z + w * w);
}
public Quaternion normalize()
{
float length = length();
return new Quaternion(x / length, y / length, z / length, w / length);
}
public Quaternion conjugate()
{
return new Quaternion(-x, -y, -z, w);
}
public Quaternion mul(Quaternion r)
{
float w_ = w * r.getW() - x * r.getX() - y * r.getY() - z * r.getZ();
float x_ = x * r.getW() + w * r.getX() + y * r.getZ() - z * r.getY();
float y_ = y * r.getW() + w * r.getY() + z * r.getX() - x * r.getZ();
float z_ = z * r.getW() + w * r.getZ() + x * r.getY() - y * r.getX();
return new Quaternion(x_, y_, z_, w_);
}
public Quaternion mul(Vector3f r)
{
float w_ = -x * r.getX() - y * r.getY() - z * r.getZ();
float x_ = w * r.getX() + y * r.getZ() - z * r.getY();
float y_ = w * r.getY() + z * r.getX() - x * r.getZ();
float z_ = w * r.getZ() + x * r.getY() - y * r.getX();
return new Quaternion(x_, y_, z_, w_);
}
public float getX()
{
return x;
}
public void setX(float x)
{
this.x = x;
}
public float getY()
{
return y;
}
public void setY(float y)
{
this.y = y;
}
public float getZ()
{
return z;
}
public void setZ(float z)
{
this.z = z;
}
public float getW()
{
return w;
}
public void setW(float w)
{
this.w = w;
}
}
我仍然不能100%确定你的问题在问什么,但我会试试看。
问题:
给定一个四元数表示围绕x,y,z的0度旋转,生成一个新的四元数,表示绕x轴旋转45度
q1 =(w1,x1,y1,z1)
q1.w1 = cos(0/2)= 1
q1.x1 = 0 * sin(0/2)= 0
q1.y1 = 0 * sin(0/2)= 0
q1.z1 = 0 * sin(0/2)= 0
所以q1 =(1,0,0,0)
q2 =(w2,x2,y2,z2)
q2.w2 = cos(PI / 4/2)= cos(PI / 8)
q2.x2 = 1.0 * sin(PI / 4/2)= 1.0 * sin(PI / 8)= sin(PI / 8)
q2.y2 = 0.0 * sin(PI / 4/2)= 0.0
q2.z2 = 0.0 * sin(PI / 4/2)= 0.0
所以q2 =(cos(PI / 8),sin(PI / 8),0,0)
我的意思是这样的:
q1 = q2 * q1
您的乘法函数写入正确,所以问题不在那里。 请记住, 四元数乘法不可交换 。 那就是q2 * q1与q1 * q2不一样!
此时q1被修改为表示围绕X轴的45度旋转。
要以度为单位打印角度,需要计算2.0 * acos(q1.w) / PI * 180
您的代码错误地计算q1.w/PI * 180
以获得以度为单位的角度。
更具体地说,改变
toANGLE(resQuat.getW())
至
toANGLE(2.0f * Math.acos(resQuat.getW()))
除此之外,我还没有看过你的代码,但尝试应用这些概念,看看是否能解决你的问题。
链接地址: http://www.djcxy.com/p/81861.html