-2

I have tried to implement the rotation of a 3D vector around an arbitrary axis for an arbitrary angle, using Rodrigues' rotation formula (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;
}

but it doesn't seem to be working correctly. I don't know what I am missing here, any help would be appreciated.

Edit:

These are the operators I used:

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

and they have been tested (they work correctly).

Eutherpy
  • 4,471
  • 7
  • 40
  • 64
  • `axis^*this` you seem to have overloaded operators for which we dont have the definition... I'm afraid we cant help you much (unless ofc the error is in that one line which we cant be sure of) – Borgleader Feb 23 '17 at 16:48
  • @Borgleader Sorry, I edited my question. – Eutherpy Feb 23 '17 at 16:53
  • 1
    @Eutherpy Would you mind posting a [MCVE] and tell us exactly what goes wrong (input, output, expected output). – πάντα ῥεῖ Feb 23 '17 at 17:01
  • Is axis a unit vector as it should be? – Daniel Jour Feb 23 '17 at 17:10
  • Potentially stupid question: is `theta` in degrees or radians? Also it may make it easier in the future to have dedicated `dot` and `cross` functions so others (or future you) do not have to look at what `*` and `^` might be doing. – ssell Feb 23 '17 at 17:37

1 Answers1

4

This might be helpful: How do axis-angle rotation vectors work and how do they compare to rotation matrices?

Also, you probably don't want to hear this, but GLM might make your life easier. Your operator overloading looks pretty tricky to get right.

Here is my attempt at an implementation...

#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;
}

Returns...

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)
Community
  • 1
  • 1
vincent
  • 1,370
  • 2
  • 13
  • 29