gpt4 book ai didi

java - 为什么我的四元数不能正确旋转?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:50:30 26 4
gpt4 key购买 nike

好的,这个问题我们不是在谈论 OpenGL,但这将与 OpenGL ES 2.0 一起使用。

问题:如何使用以下代码创建和旋转四元数?

我一直在阅读和研究这个,但仍然不能完全理解这些概念。我以为我明白了,但是当我开始计算旋转四元数时,我意识到我什至无法回到我开始的地方。

假设我们有一个立方体,它的中心位于 (0, 0, 0)。我们想将它在 x 轴上旋转 45 度。我会怎么做? (只有四元数)

假设成功,您将如何从“W”获得旋转量?我知道 '1' 表示没有旋转,但如果旋转 173 度呢?

尝试旋转到给定方向,45 度,然后从 W 获取该值。我觉得我需要将角度转换为 rads 或其他东西,但不太确定。在线教程因人而异。

这是我的代码:

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

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)

  • 生成绕 X 轴 45 度(PI/4 弧度)的新旋转我们需要一个临时四元数来修改 q1。我们称它为 q2。

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()))

除此之外我没有查看您的代码,但请尝试应用这些概念,看看是否能解决您的问题。

关于java - 为什么我的四元数不能正确旋转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19570957/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com