首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >四元数和vec3上的GLM‘*算子是如何定义的?

四元数和vec3上的GLM‘*算子是如何定义的?
EN

Game Development用户
提问于 2022-07-08 14:12:07
回答 1查看 404关注 0票数 1

使用这里给出的四元数旋转的定义

因此,上述公式的GLM中的等效代码如下:

代码语言:javascript
运行
复制
glm::quat q;
glm::vec3 v;
glm::vec3 rotated_vector = q * v;

上述rotated_vector是将Lq变换应用于矢量v的结果。

我说得对吗?

下面是我编写的测试代码(并非详尽无遗):

代码语言:javascript
运行
复制
for (size_t number_of_conducted_testing = 0; number_of_conducted_testing < 10000; number_of_conducted_testing++)
{
    //axis to rotate around
    glm::vec3 axis = glm::sphericalRand(1.0);
    //vector to be rotated
    glm::vec3 v    = glm::sphericalRand(1.0);
    //quaternion
    glm::quat q;

    for (auto degree = 0.f; degree < 370.f; degree += 0.0001f)
    {
        q = glm::angleAxis(glm::radians(degree), axis);
        glm::vec3 q_vector = glm::vec3(q.x, q.y, q.z);


        const glm::vec3 rotated_vector   = q * v;
        const glm::vec3 rotated_vector_0 = ((q.w) * (q.w) - glm::length2(q_vector)) * v + 2 * (glm::dot(q_vector, v)) * q_vector + 2 * q.w * (glm::cross(q_vector, v));

        float difference = 0.0f;
        if (!test_similarity(rotated_vector, rotated_vector_0, difference))
        {
            throw std::runtime_error("two vectors are different!");
        }
    }
}


bool App::test_similarity(glm::vec3 a, glm::vec3 b,float& difference)
{
    const auto difference = glm::length((a - b));
    return difference < 1e-5f;
}

而且它没有为这个案子抛出任何例外,difference < 0.00001

EN

回答 1

Game Development用户

发布于 2022-07-14 09:49:33

最后,我在Kavan,Ladislav等,几何蒙皮与近似双四元数混合中找到了GLM '*‘操作符的实现“图形上的ACM事务处理”27.4 (2008年):105

Lemma 4.\textbf{q} = a + \textbf{r}是具有标量部分a和向量部分\textbf{r}__的单位正则四元数。由正则四元数\textbf{v} = v_0i + v_1j + v_2k表示的向量D5的旋转可以计算为\textbf{v}' = \textbf{v} + 2\textbf{r} \times (\textbf{r} \times \textbf{v} + a\textbf{v})\tag{15},其中\textbf{v}′是由\textbf{q}旋转的向量\textbf{v}。证据。该证明包括重新排列众所周知的表达式\textbf{v}′ = \textbf{qvq}^∗。利用方程(14),我们可以展开\begin{align} \textbf{v}′ &= \textbf{qvq}^∗ = (a + \textbf{r})\textbf{v}(a − \textbf{r}) = (−\langle\textbf{r}, \textbf{v}\rangle + a\textbf{v} + \textbf{r} \times \textbf{v})(a − \textbf{r}) = \\ &= −a\langle\textbf{r}, \textbf{v}\rangle + a\langle\textbf{v}, \textbf{r}\rangle + \langle\textbf{r}, \textbf{v}\rangle\textbf{r} + a^2\textbf{v} + a(\textbf{r} \times \textbf{v}) − a(\textbf{v} \times \textbf{r}) − (\textbf{r} \times \textbf{v}) \times \textbf{r} = \\ &= \langle\textbf{r}, \textbf{v}\rangle\textbf{r} + a^2\textbf{v} + 2a(\textbf{r} \times \textbf{v}) + \textbf{r} \times (\textbf{r} \times \textbf{v}) \end{align} 回忆拉格朗日公式\textbf{r} \times (\textbf{r} \times \textbf{v}) = \textbf{r}\langle\textbf{r}, \textbf{v}\rangle − \textbf{v}\langle\textbf{r}, \textbf{r}\rangle ,该公式加到以前的方程中,得到了\begin{align} \textbf{v}′ &= \langle\textbf{r}, \textbf{v}\rangle\textbf{r} + a^2\textbf{v} + 2a(\textbf{r} \times \textbf{v}) + 2\textbf{r} \times (\textbf{r} \times \textbf{v}) − \textbf{r}\langle\textbf{r}, \textbf{v}\rangle + \textbf{v}\langle\textbf{r}, \textbf{r}\rangle = \\ &= \textbf{v}(a^2 + \Vert\textbf{r}\Vert^2 ) + 2a(\textbf{r} \times \textbf{v}) + 2\textbf{r} \times (\textbf{r} \times \textbf{v}) \end{align} 方程(15)。

这正是GLM在四元数和vec3上实现其“*”运算符的方式:

代码语言:javascript
运行
复制
template
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(qua const& q, vec<3, T, Q> const& v)
{
    vec<3, T, Q> const QuatVector(q.x, q.y, q.z);
    vec<3, T, Q> const uv(glm::cross(QuatVector, v));
    vec<3, T, Q> const uuv(glm::cross(QuatVector, uv));

    return v + ((uv * q.w) + uuv) * static_cast(2);
}
票数 1
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/201644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档