我尝试使用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
他们已经过测试(他们正常工作)。
答案 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)