四元数x向量,相关用法

Posted 就当笔记吧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四元数x向量,相关用法相关的知识,希望对你有一定的参考价值。

Vector3 operator *(Quaterion rotation, Vector3 point)

点绕着原点旋转指定的角度。不管如何旋转这个点都是在一个圆球的表面上(圆球半径为point到原点的距离)。

 

几个例子

测试代码

public class QuatTest : MonoBehaviour

    public Vector3 m_QuatEuler;
    private Vector3 m_Point;

    void Update()
    
        if (Input.GetKeyDown(KeyCode.Alpha1))
        
            var point = new Vector3(0, 0, -1);
            m_Point = Quaternion.Euler(m_QuatEuler) * point;
        
    

    private void OnDrawGizmosSelected()
    
        Gizmos.color = Color.cyan;
        Gizmos.DrawLine(Vector3.zero, m_Point);
    

1) x轴旋转45度

 

2) x, y轴都旋转45度

 

3) x, y, z都旋转45度,貌似和2)没有区别,主要是point本身就在z轴上,绕z轴旋转没任何效果的

 

一些疑问

有时候,我们会看到this.transform.rotation * point直接这样用,如果用this.transform.localRotation * point有区别吗?

1) 有区别,比如localRotation是x轴30度,rotation却是无任何旋转(parent反方向旋转了),这种情况就不一样了。所以最终是看rotation和localRotation的实际值来决定。

 

 一些用法

1) 使用四元数计算相机的forward向量

var myForward = this.transform.rotation * Vector3.forward;
myForward.Normalize();
Debug.Log($"myForward.x, myForward.y, myForward.z");

var f = this.transform.forward; //上面的结果和这边得到的是一样的
Debug.Log($"f.x, f.y, f.z");

 

2) 相机绕着player旋转

 

using UnityEngine;

[RequireComponent(typeof(Camera))]
public class RotateAround : MonoBehaviour


    private Transform m_Camera;

    public Transform m_Player;

    public Vector3 m_OffsetPoint = new Vector3(0.0f, 0.0f, -5.0f);

    private float m_HorizontalAngle = 0.0f;

    void Awake()
    
        m_Camera = GetComponent<Camera>().transform;
    

    void Update()
    
        if (m_Player == null) return;

        if (Input.GetMouseButton(0))
        
            m_HorizontalAngle += 0.1f;
        
        else if (Input.GetMouseButton(1))
        
            m_HorizontalAngle -= 0.1f;
        

        Quaternion cameraRot = Quaternion.Euler(0, m_HorizontalAngle, 0);
        m_Camera.rotation = cameraRot;

        m_Camera.position = m_Player.position + cameraRot * m_OffsetPoint;
    

 

GLM四元数反向偏航

【中文标题】GLM四元数反向偏航【英文标题】:GLM quaternion reversed yaw 【发布时间】:2019-03-03 20:18:25 【问题描述】:

我正在使用 OpenGL 和 GLM 构建一个玩具 3D 引擎。我的轴系是右手系,X 向右,Y 向上,Z 向后。

实体的变换由 3D 向量和 GLM 的四元数之一组成。物理模拟是二维的,所以实体的速度是一个二维向量(Y 上没有速度,只有 XZ,地平面)。类似地,角速度只围绕 Y 轴(偏航)。

// Properly integrate the change in velocities
auto deltaPos = (physics->velocity + physics->lastVelocity) * 0.5f * deltaTime;
auto deltaYaw = (physics->yawVelocity + physics->lastYawVelocity) * 0.5f * deltaTime;
// Apply the velocities
transform->position += glm::vec3 deltaPos.x, 0, deltaPos.y * transform->orientation
transform->orientation = glm::quat(glm::vec3 0, deltaYaw, 0) * transform->orientation;

我正在使用自上而下的相机渲染世界,将方向转换为 4x4 矩阵,将其(以正确的顺序)乘以比例和平移矩阵:

glm::mat4x4 transformMat =
        glm::translate(transform->position) *
        glm::mat4x4(transform->orientation) *
        glm::scale(glm::vec3 size.x, 1.0f, size.y);

.. 并将其发送到着色器,在那里它与点坐标以及投影和视图矩阵相乘:

// projView is projection * view
gl_Position = projView * transform * vec4(vertPosition.xyz, 1.0);

然而,虽然这段代码看起来很简单,但对象的偏航似乎有时会翻转。当一个对象向左转时,它开始在世界中向左移动(position += deltaPosition * orientation 行正常工作),但它被渲染为向右旋转,但向左移动。这是一个示例图像:

似乎四元数的表示,或者至少是它的四元数 - 矩阵转换,否定了旋转的偏航“分量”,就像 Y 向下而不是向上一样。然而,当一个向量被那个四元数旋转时,它似乎表现得很好,就像 Y 向上一样。有趣的是,代码的另一部分(处理车辆的转弯)似乎只有在四元数通过 -yaw 而不是 yaw 旋转时才能正常工作。 (渲染问题仍然存在)。

有什么解释或方法可以解决这个问题吗?

【问题讨论】:

你为什么要通过方向来旋转速度?它是否存储在对象的本地坐标系中?此外,代码vector * quaternion 是 glm 中的有效四元数转换吗?通常,您使用quaternion * vector * quaternion^-1,其中vector 是四元化向量。 谢谢,vector * quaternion 行实际上是在执行旋转(它似乎是某种 GLM 符号),但它是按四元数^-1 旋转的,这导致了所有问题旋转。 【参考方案1】:

原来我错误地应用了四元数: 在这一行:

transform->position += glm::vec3 deltaPos.x, 0, deltaPos.y * transform->orientation

GLM 中的乘法定义实际上是将向量旋转四元数的倒数。正确的行是:

transform->position += transform->orientation * glm::vec3 deltaPos.x, 0, deltaPos.y;

感谢 Nico Schertler 将我的注意力引向正确的方向。

【讨论】:

以上是关于四元数x向量,相关用法的主要内容,如果未能解决你的问题,请参考以下文章

什么是四元数旋转?

四元数运动学笔记旋转的雅克比矩阵

matlab练习程序(求向量间的旋转矩阵与四元数)

eigen 中四元数欧拉角旋转矩阵旋转向量

四元数绕轴旋转的分量

matlab练习程序(对应点集配准的四元数法)