C ++中的3D矢量旋转

时间:2017-02-23 16:45:53

标签: c++ vector 3d rotation

我尝试使用Rodrigues'以任意角度围绕任意轴旋转3D矢量。轮换公式(Rodrigues' rotation formula)

vector3 vector3::rotate(const vector3 &axis, double theta) const
{
    double cos_theta = cos(theta);
    double sin_theta = sin(theta);
    vector3 rotated = *this*cos_theta + (axis^*this)*sin_theta + axis*(axis*(*this))*(1 - cos_theta);
    return rotated;
}

但它似乎没有正常工作。我不知道我在这里缺少什么,我们将不胜感激。

编辑

这些是我使用的运算符:

vector3 operator*(double) const; //multiplication by scalar
friend vector3 operator*(double, const vector3&); //multiplication by scalar
double operator*(const vector3&) const; //dot product
vector3 operator^(const vector3&) const; //cross product

他们已经过测试(他们正常工作)。

1 个答案:

答案 0 :(得分:3)

这可能会有所帮助:How do axis-angle rotation vectors work and how do they compare to rotation matrices?

此外,您可能不想听到此消息,但GLM可能会让您的生活更轻松。你的运算符重载看起来很难实现。

以下是我对实施的尝试......

#include <iostream>
#include <cmath>

#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>

// v: a vector in 3D space
// k: a unit vector describing the axis of rotation
// theta: the angle (in radians) that v rotates around k
glm::dvec3 rotate(const glm::dvec3& v, const glm::dvec3& k, double theta)
{
    std::cout << "Rotating " << glm::to_string(v) << " "
              << theta << " radians around "
              << glm::to_string(k) << "..." << std::endl;

    double cos_theta = cos(theta);
    double sin_theta = sin(theta);

    glm::dvec3 rotated = (v * cos_theta) + (glm::cross(k, v) * sin_theta) + (k * glm::dot(k, v)) * (1 - cos_theta);

    std::cout << "Rotated: " << glm::to_string(rotated) << std::endl;

    return rotated;
}

int main()
{
    glm::dvec3 v(1.0, 0.0, 0.0);
    glm::dvec3 k(0.0, 0.0, 1.0);
    double theta = M_PI; // 180.0 degrees

    // Rotate 'v', a unit vector on the x-axis 180 degrees
    // around 'k', a unit vector pointing up on the z-axis.
    glm::dvec3 rotated = rotate(v, k, theta);

    return 0;
}

...返回

Rotating dvec3(1.000000, 0.000000, 0.000000) 3.14159 radians around dvec3(0.000000, 0.000000, 1.000000)...
Rotated: dvec3(-1.000000, 0.000000, 0.000000)