'Rotating an end point while having the direction
I have a point and a direction and I would like to know what that point would be if it was rotated by 45 degrees. For example, if I have
Point A being (0, 0, 0) with a direction of (0, 0, 1) and a distance of 5, then my point B would be (0, 0, 5). However, if I wanted to get what point B would be while also incorporating an angle of 45 degrees, how would I do so?
I had thought of using the Rodrigues formula, however, given the formula of Rodrigues being rotation = (v, k, angle), or in this case, rotation = (point b, direction, 45) I would have a resulting vector of (0, 0, 5). This leads me to believe that I should be applying the angle to the direction some how
Solution 1:[1]
You appear to work in 3D, so you need to define a plane in which you want to rotate (i.e. move) some point. For example, given a point (0,0,1) and you choose the x-z-plane as plane in which you want to rotate the point, and you want to rotate it by 90°, you end up with (1,0,0). But if you choose to rotate the point (0,0,1) by 90° in the y-z-plane instead, you end up with (0,-1,0).
Rather than defining a plane, you can also use the normal vector of the plane in which you want to rotate the point. This normal is the rotation axis (called k below) around which the point gets rotated according to the right-hand rule. So, if you choose the x-z-plane, the rotation axis would be k=(0,1,0), i.e. the y-axis. If you choose the y-z-plane as plane, the rotation axis would be k=(1,0,0), i.e. the x-axis.
Note that in 2D you do not have the freedom of choosing the rotation axis: It is always pointing straight "out of your screen". Meaning, you only have x- and y-coordinates, but for the purpose of rotating you imagine a third axis (the z-axis) which is orthogonal to both the x- and y-axes, i.e. k=(0,0,1).
Now, to rotate some general 3D vector v by an angle angle around a rotation axis k, you can use Rodrigues' rotation formula. In pure C++ (since you added it as tag) without any additional libraries, it could be implemented like this:
#include <array>
#include <cmath>
using Vec3 = std::array<double, 3>;
// v = vector to rotate
// k = rotation axis. Must be a **unit** vector! (Length must be 1!)
// angle = rotation angle in radiant
Vec3 Rotate(Vec3 const & v, Vec3 const & k, double angle) {
double const cosAngle = std::cos(angle);
double const sinAngle = std::sin(angle);
Vec3 const cross{
k[1]*v[2] - k[2]*v[1],
k[2]*v[0] - k[0]*v[2],
k[0]*v[1] - k[1]*v[0]};
double const scalar = k[0]*v[0] + k[1]*v[1] + k[2]*v[2];
double const scalarWithAngle = scalar * (1.0 - cosAngle);
Vec3 result;
for (size_t i = 0; i < 3; ++i){
// Rodrigues' rotation formula
result[i] = v[i] * cosAngle + cross[i]*sinAngle + k[i]*scalarWithAngle;
}
return result;
}
Here I implement e.g. cross and scalar products manually. Using an appropriate library such as Eigen can make things easier and faster.
Given your explanation, I assume you want to start at a point A=(0,0,0), move a distance=5 into some direction. The direction is (0,0,1) but rotated by 45°. What you did not specify was the rotation axis. Considering your image, I guess to want to rotate around the y-axis (0,1,0), i.e. in the x-z-plane. Thus, in C++:
int main() {
Vec3 const A{0, 0, 0};
double const distance = 5.0;
Vec3 const rotationAxis{0, 1.0, 0.0}; // = y-axis, i.e. rotation in x-z-plane
double const angle = M_PI / 4.0; // 45° in radiant
Vec3 const direction{0, 0, 1.0};
Vec3 const rotatedDirection = Rotate(direction, rotationAxis, angle);
Vec3 const C{
A[0] + rotatedDirection[0]*distance,
A[1] + rotatedDirection[1]*distance,
A[2] + rotatedDirection[2]*distance};
// Prints C = {3.53553, 0, 3.53553}
std::cout << "C = {" << C[0] << ", " << C[1] << ", " << C[2] << "}" << std::endl;
}
This code first rotates the direction (0,0,1) by 45° in the x-z-plane, and then moves adistance=5 starting at A along the rotated direction to get to point C.
If you already know the point B that you want to rotate, it can be done similarly:
int main() {
Vec3 const B{0, 0, 5.0};
Vec3 const rotationAxis{0, 1.0, 0.0}; // = y-axis, i.e. rotation in x-z-plane
double const angle = M_PI / 4.0; // 45° in radiant
Vec3 const C = Rotate(B, rotationAxis, angle);
// Prints C = {3.53553, 0, 3.53553}
std::cout << "RotatePointDirectly C = {" << C[0] << ", " << C[1] << ", " << C[2] << "}" << std::endl;
}
Full example on godbolt.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

