# Thread: Rotation in 3 dimensions

1. ## Rotation in 3 dimensions

Hi all, i hope this is the right place.

I'am trying to do some rotation in a 3D space, basically i have 3 nodes (a,b,c) and two edges (a,b),(b,c). I'am trying to rotate along i believe the axis formed by the edge (b,c) with the aim of repositioning node 'a' along the circular plane.

What i was hoping someone maybe able to help me with is, i need to basically 'randomly' place node 'a' along various parts of the circular plane, but need to keep the angle and length constraints the same obviously.

If i have the X,Y,Z coordinates for all nodes (a,b,c) along with length of edges, is thre a way i can use them to place 'a' somewhere along the circular polane but remain within constraints?

Any help is appreciated, trust me

Regards Wolfe

*edit* solution

Well i found some way of doing what i wanted, simply performing a rotation along each axis seperately

q = angle of rotation.

first along Z axis
x' = x*cos q - y*sin q
y' = x*sin q + y*cos q
z' = z

Then along X axis
y' = y*cos q - z*sin q
z' = y*sin q + z*cos q
x' = x

and finally along Y axis
z' = z*cos q - x*sin q
x' = z*sin q + x*cos q
y' = y

2. Originally Posted by cdrwolfe
Hi all, i hope this is the right place.

I'am trying to do some rotation in a 3D space, basically i have 3 nodes (a,b,c) and two edges (a,b),(b,c). I'am trying to rotate along i believe the axis formed by the edge (b,c) with the aim of repositioning node 'a' along the circular plane.

What i was hoping someone maybe able to help me with is, i need to basically 'randomly' place node 'a' along various parts of the circular plane, but need to keep the angle and length constraints the same obviously.

If i have the X,Y,Z coordinates for all nodes (a,b,c) along with length of edges, is thre a way i can use them to place 'a' somewhere along the circular polane but remain within constraints?

Any help is appreciated, trust me

Regards Wolfe
Hi. You can use a Rotation matrix of the following form

.

If I understand your picture correctly, the unit vector

$\mathrm{\hat{v} = (c-b)/||c - b||}$

is the axis you want to rotate around (not along). $\theta$ is the angle of rotation, which you can choose randomly. Call the rotation matrix $\mathrm{M.}$ Then

$\mathrm{a' = M(a-b) + b}$

is the rotated point on the circle.

3. Thanks,. but its not to clear how to calculate the new set of x,y and z coordinates. If say for example the coordinates for node a are 2,3,4 and new angle say 45*, err then what?

cos0 + (1 - cos0)2*2 etc what or how do you compute the matrix? so you end up with the correct new x',y',z' coordinates?

Sorry for the questions, but since i've never seen a matrix before i haven't a clue what to do with it

Regards Wolfe

4. Originally Posted by cdrwolfe
Thanks,. but its not to clear how to calculate the new set of x,y and z coordinates. If say for example the coordinates for node a are 2,3,4 and new angle say 45*, err then what?

cos0 + (1 - cos0)2*2 etc what or how do you compute the matrix? so you end up with the correct new x',y',z' coordinates?

Sorry for the questions, but since i've never seen a matrix before i haven't a clue what to do with it

Regards Wolfe
Sorry, I think this is too complicated (for me at least!) if you've never seen a matrix. Someone else may want to step in here.

5. Er... It sounds so strange, especially since all rotations in space are just multiplications with specific matrices

6. Thanks for the help, i've managed to figure out a way of doing it using a similar matric, in this case just performng a rotation along each axis seperately.

However now i've got what i thought to be the simpler of the problems to figure out however my first method turned out to not be correct

In this case it is just a simple scaling between two points in a 3D space.

for example i have point A. with x,y,z corrdinates (54.44, -11.129, 4.884) and point B (53.823, -13.98, 9.326). These two points have a distance of 5.314156001 angstroms for example.

Now i pick a new set of coordinates for B say (48.623, -17.925, 23.662) which now has a disatnce of 20.79539935 angstroms from A.

Obviosuly now i want to reduce to the correct distance, however for the life of me i can't figure out how, i thought at first it was a simple scaling by the ratio of the two distances, i.e. a factor of 4.8088, for each coordinate however that doesn't work becuase i think it uses coord (0,0,0) as the origin and not point A.

I can't help but think it is something really simple to do, however i don't know

Any help is appreciated

Regards Wolfe

*edit*

NM lol i think i have it, take away point A's coordinates from point B's, then reduce by the ratio and then add on point A's coordinates again. i beleive thats it....

7. Originally Posted by cdrwolfe
Thanks for the help, i've managed to figure out a way of doing it using a similar matric, in this case just performng a rotation along each axis seperately.

However now i've got what i thought to be the simpler of the problems to figure out however my first method turned out to not be correct

In this case it is just a simple scaling between two points in a 3D space.

for example i have point A. with x,y,z corrdinates (54.44, -11.129, 4.884) and point B (53.823, -13.98, 9.326). These two points have a distance of 5.314156001 angstroms for example.

Now i pick a new set of coordinates for B say (48.623, -17.925, 23.662) which now has a disatnce of 20.79539935 angstroms from A.

Obviosuly now i want to reduce to the correct distance, however for the life of me i can't figure out how, i thought at first it was a simple scaling by the ratio of the two distances, i.e. a factor of 4.8088, for each coordinate however that doesn't work becuase i think it uses coord (0,0,0) as the origin and not point A.

I can't help but think it is something really simple to do, however i don't know

Any help is appreciated

Regards Wolfe

*edit*

NM lol i think i have it, take away point A's coordinates from point B's, then reduce by the ratio and then add on point A's coordinates again. i beleive thats it....
The problem statement is not clear to me. A is fixed. Is B being scaled, or is a completely new point being chosen? In your example, the revised B = (48.623, -17.925, 23.662) is not a scalar multiple of the the original B = (53.823, -13.98, 9.326).

If a completely new point is being chosen, the new point is any one on the sphere with center A and radius equal to the new distance.

If B is being scaled, the new point is on the intersection of that sphere and the line containing the origin and the original point B. There may be no such intersection if new distance is less than the old distance.

8. (48.623, -17.925, 23.662) , (54.44, -11.129, 4.884)

48.623 - 54.44 = -5.817
-17.925 - -11.129 = -6.796
23.662 - 4.884 = 18.778

scale these numbers, in this case we want a distance of 5.31416, but the distance of (48.623, -17.925, 23.662) , (54.44, -11.129, 4.884) is 20.7954

so 5.13416 / 20.7954 = 0.25554

scale (-5.817, -6.796, 18.778) by 0.25554 gives (-1.2777, -1.73668, 4.7986)

add orignal point A coordinates back on ie (54.44, -11.129, 4.884) to give
(53.1145, -12.8657, 9.6826)

now work out distance between point A and now new scaled point B hoping to get correct distance of 5.31416

to work out distance between two XYZ coordinates...
Sq Root ( (Ax - Bx)*2 + (Ay - By)*2 + (Az -Bz)*2 )

gives 5.3972027, which is slightly higher but thats because i've been extremely lazy with the number size, i.e 9.6826 instead of 9.682620104

Regards Wolfe

9. Originally Posted by cdrwolfe
(48.623, -17.925, 23.662) , (54.44, -11.129, 4.884)

48.623 - 54.44 = -5.817
-17.925 - -11.129 = -6.796
23.662 - 4.884 = 18.778

scale these numbers, in this case we want a distance of 5.31416, but the distance of (48.623, -17.925, 23.662) , (54.44, -11.129, 4.884) is 20.7954

so 5.13416 / 20.7954 = 0.25554

scale (-5.817, -6.796, 18.778) by 0.25554 gives (-1.2777, -1.73668, 4.7986)

add orignal point A coordinates back on ie (54.44, -11.129, 4.884) to give
(53.1145, -12.8657, 9.6826)

now work out distance between point A and now new scaled point B hoping to get correct distance of 5.31416

to work out distance between two XYZ coordinates...
Sq Root ( (Ax - Bx)*2 + (Ay - By)*2 + (Az -Bz)*2 )

gives 5.3972027, which is slightly higher but thats because i've been extremely lazy with the number size, i.e 9.6826 instead of 9.682620104

Regards Wolfe
Just to let you know, using the words "new scaled point B" is misleading.

What you are doing is this. Given vectors $\bold{a}$ and $\bold{b}$ and distance $d,$ find a vector $\bold{b'}$ along the line between $\bold{a}$ and $\bold{b}$ so the distance $|| \bold{a - b'} || = d$. That line is the set of vectors $\bold{b'} = \bold{a} + t(\bold{b-a})$ for $t \in [0,1]$. You are finding the appropriate value for $t = d/||\bold{a - b}||.$

Calling $\bold{b'}$ the "new scaled point" $\bold{b}$ is misleading. Scaling the vector $\bold{b}$ would be simply multiplying it by a scalar, which you haven't done. You have scaled $\bold{b-a}.$

It seems my simpler rotation hasn't hit fruition, right now i rotate about each axis in successio (Z,X,Y)

Z =

x' = x*cos q - y*sin q
y' = x*sin q + y*cos q
z' = z

X =

y' = y*cos q - z*sin q
z' = y*sin q + z*cos q
x' = x

Y =

z' = z*cos q - x*sin q
x' = z*sin q + x*cos q
y' = y

However though both the Z and X axis rotations keep the (x,y,z) coordinates in the correct distance i want, this doesn't heppen for the y axis rotation.

Which is a shame considering i thought it might be a simpler way

Regards Wolfe

11. Originally Posted by JakeD
Hi. You can use a Rotation matrix of the following form

.

If I understand your picture correctly, the unit vector

$\mathrm{\hat{v} = (c-b)/||c - b||}$

is the axis you want to rotate around (not along). $\theta$ is the angle of rotation, which you can choose randomly. Call the rotation matrix $\mathrm{M.}$ Then

$\mathrm{a' = M(a-b) + b}$

is the rotated point on the circle.
Originally Posted by cdrwolfe

It seems my simpler rotation hasn't hit fruition, right now i rotate about each axis in successio (Z,X,Y)

Z =

x' = x*cos q - y*sin q
y' = x*sin q + y*cos q
z' = z

X =

y' = y*cos q - z*sin q
z' = y*sin q + z*cos q
x' = x

Y =

z' = z*cos q - x*sin q
x' = z*sin q + x*cos q
y' = y

However though both the Z and X axis rotations keep the (x,y,z) coordinates in the correct distance i want, this doesn't heppen for the y axis rotation.

Which is a shame considering i thought it might be a simpler way

Regards Wolfe
Well, you are rotating around some axis, but it is not clear which one.

Rotating around a specified axis $\bold{\hat{v}} = [x,y,z]$ using an angle $\theta$ using your method requires using three different angles called Euler angles in the three matrices. To convert the axis-angle $(\bold{\hat{v}},\theta)$ to Euler angles, use these formulas I translated from here:

\begin{aligned}
q_0 &= \cos(\theta/2) \\
q_1 &= \sin(\theta/2) x \\
q_2 &= \sin(\theta/2) y \\
q_3 &= \sin(\theta/2) z \\
\phi & = \arctan(2(q_0q_1 + q_2q_3)/(1-2(q_1^2 + q_2^2))) \\
\beta & = \arcsin(2(q_0q_2 - q_1q_3)) \\
\psi & = \arctan(2(q_0q_3 + q_1q_2)/(1-2(q_2^2 + q_3^2))) .\\
\end{aligned}

The Euler angles $(\phi,\beta,\psi)$ correspond to clockwise rotations about the $(X,Y,Z)$ axes applied in the order $(Z,Y,X).$ You're using clockwise rotations in a different order.

12. Thanks, well now that i have my euler angles what do i do with them?

do i simply replace the angle q with the new euler angle for each set of equations i.e

Z =

x' = x*cos $\phi$ - y*sin $\phi$
y' = x*sin [tex] \phi [tex] + y*cos $\phi$
z' = z

Y =

z' = z*cos $\beta$ - x*sin $\beta$
x' = z*sin $\beta$ + x*cos $\beta$
y' = y
etc

I'am not sure what i should do with these new euler angles

Regards Wolfe

13. Originally Posted by JakeD
Well, you are rotating around some axis, but it is not clear which one.

Rotating around a specified axis $\bold{\hat{v}} = [x,y,z]$ using an angle $\theta$ using your method requires using three different angles called Euler angles in the three matrices. To convert the axis-angle $(\bold{\hat{v}},\theta)$ to Euler angles, use these formulas I translated from here:

\begin{aligned}
q_0 &= \cos(\theta/2) \\
q_1 &= \sin(\theta/2) x \\
q_2 &= \sin(\theta/2) y \\
q_3 &= \sin(\theta/2) z \\
\phi & = \arctan(2(q_0q_1 + q_2q_3)/(1-2(q_1^2 + q_2^2))) \\
\beta & = \arcsin(2(q_0q_2 - q_1q_3)) \\
\psi & = \arctan(2(q_0q_3 + q_1q_2)/(1-2(q_2^2 + q_3^2))) .\\
\end{aligned}

The Euler angles $(\phi,\beta,\psi)$ correspond to clockwise rotations about the $(X,Y,Z)$ axes applied in the order $(Z,Y,X).$ You're using clockwise rotations in a different order.
Originally Posted by cdrwolfe
Thanks, well now that i have my euler angles what do i do with them?

do i simply replace the angle q with the new euler angle for each set of equations i.e

Z =

x' = x*cos $\phi$ - y*sin $\phi$
y' = x*sin [tex] \phi [tex] + y*cos $\phi$
z' = z

Y =

z' = z*cos $\beta$ - x*sin $\beta$
x' = z*sin $\beta$ + x*cos $\beta$
y' = y
etc

I'am not sure what i should do with these new euler angles

Regards Wolfe
That's it. But be careful to match each angle with the right matrix and multiply the matrices in the correct order, or it won't work.

14. Well it doesn't seem to work,...

Here is the example code i'am using.

Pop[i][j][0] = x, with [1] = y and [2] = z;

// convert to euler angles
q0 = cos(angle/2);
q1 = sin(angle/2) * Pop[i][j][0];
q2 = sin(angle/2) * Pop[i][j][1];
q3 = sin(angle/2) * Pop[i][j][2];

eX = atan(2*((q0*q1) + (q2*q3)) / (1 - (2*( (q1 * q1) + (q2 * q2) ) ) ) );
eY = asin(2*((q0*q2) - (q1*q3)));
eZ = atan(2*((q0*q3) + (q1*q2)) / (1 - (2*( (q2 * q2) + (q3 * q3) ) ) ) );

nX[0] = Pop[i][j][0]; // store for later use in z axis rotaion
nY[0] = Pop[i][j][1];
nZ[0] = Pop[i][j][2];

// rotate around Z axis
cout << "Rotate Z axis" << endl;
Pop[i][j][0] = (nX[0] * (cos(eX))) - (nY[0] * (sin(eX)));
Pop[i][j][1] = (nX[0] * (sin(eX))) + (nY[0] * (cos(eX)));
Pop[i][j][2] = nZ[0];

oldnX[0] = Pop[i][j][0]; // store for later use in y axis rotaion
oldnY[0] = Pop[i][j][1];
oldnZ[0] = Pop[i][j][2];

// rotate around Y axis
Pop[i][j][0] = (oldnZ[0] * (cos(eY))) - (oldnX[0] * (sin(eY)));
Pop[i][j][1] = oldnY[0];
Pop[i][j][2] = (oldnZ[0] * (sin(eY))) + (oldnX[0] * (cos(eY)));

oldnX[0] = Pop[i][j][0]; // store for later use in y axis rotaion
oldnY[0] = Pop[i][j][1];
oldnZ[0] = Pop[i][j][2];

// rotate around X axis
Pop[i][j][0] = oldnX[0];
Pop[i][j][1] = (oldnY[0] * (cos(eZ))) - (oldnZ[0] * (sin(eZ)));
Pop[i][j][2] = (oldnY[0] * (sin(eZ))) + (oldnZ[0] * (cos(eZ)));

oldnX[0] = Pop[i][j][0]; // store for later use in y axis rotaion
oldnY[0] = Pop[i][j][1];
oldnZ[0] = Pop[i][j][2];

It looks correct but, and the first part of rotatin around the z axis seems to work, but the others just through up number to infinity so are wrong.

hmmm.

15. Right, some feedback, it seem my original raotation along the three seperate angles did work, i just dispalyed the output for them wrong and decieved myself into thinking it didn't *sigh*

Also JakeD

Where you wrote q1 = sin(angle/2) * X

Looking over at the link shouldn't it be q1 = sin(angle/2) * cos(X)??

Changing to this doesn't seem to throw up negetive infinity numbers anymore.

Regards Wolfe

Page 1 of 2 12 Last