POV-Ray : Newsgroups : povray.general : Convert 313 Cartesian Euler Angles to POV-Ray Coordinates : Re: Convert 313 Cartesian Euler Angles to POV-Ray Coordinates Server Time21 Apr 2024 03:38:41 EDT (-0400)
 Re: Convert 313 Cartesian Euler Angles to POV-Ray Coordinates
 From: Tor Olav Kristensen Date: 17 Sep 2022 10:50:00 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#web.6325ddf67d53bcda864c7c4689db30a9%40news.povray.org",
"headline": "Re: Convert 313 Cartesian Euler Angles to POV-Ray Coordinates",
"dateCreated": "2022-09-17T14:50:00+00:00",
"datePublished": "2022-09-17T14:50:00+00:00",
"author": {
"@type": "Person",
"name": "Tor Olav Kristensen"
}
}
"LAP" <nomail@nomail> wrote:
> I am attempting to use POV-Ray for rigid-body dynamics.
>
> I have software that produces rotation parameters as 313 Euler angles, psi,
> theta, and phi, and the associated 313 rotation matrix.  All this is done in 3D
> Euclidean (Cartesian) space.
>
> The problem I face is converting these Euclidean 313 parameters to work in
> POV-Ray coordinates.  In other words, I need to convert the Euclidean rotation
> matrix to a POV-Ray matrix so that I can propery rotate objects (and their
> textures).
>
> Since the basic coordinate transform is <x,y,z> Euclidean to <-z, x, y> I have
> tried to rearrange the components of the Euclidean 313 rotation matrix to
> duplicate this transform but the results are not correct.
>
> Given a rotation matrix in 3D Euclidean space:
>
> | 00 01 02 |
> | 10 11 12 |
> | 20 21 22 |
>
> What is the correct way of transforming this matrix so that it will rotate a
> POV-Ray object in the same way?

Hi

You may want to have a look at the code below.

The matrices.inc and vectors.inc files can be found in these libraries:

https://github.com/t-o-k/POV-Ray-matrices

https://github.com/t-o-k/Useful-POV-Ray-macros

I've had a look at how POV-Ray does things internally - and I have tried
to keep the matrices simlar to that, and to do the multiplcations in the
same order. But keep in mind that since POV-Ray uses a left handed
coordinate system, the signs of the rotation angles are opposite of the
rotation angles in a right handed coordinate system.

I based some of the code below on what I found in these articles:

https://en.wikipedia.org/wiki/Euler_angles#Conventions_by_extrinsic_rotations

https://en.wikiversity.org/wiki/PlanetPhysics/Euler_313_Sequence

--
Tor Olav
http://subcube.com
https://github.com/t-o-k

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.7;

#include "../vectors.inc"
#include "POV-Ray-matrices/matrices.inc"
// #include "matrices.inc"

global_settings { assumed_gamma 1.0 }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#macro PrintVector3D(v0)

#debug concat("<", vstr(3, v0, ", ", 0, -1), ">")

#end // macro PrintVector3D

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#debug "\n\n"

#declare v0 = <+3, -4, +2>;
#debug "v0 = \n"
PrintVector3D(v0)
#debug "\n\n"

#declare MM_0R = M_Row_FromDir3D(v0);
#debug "MM_0R = \n"
M_Print(MM_0R)
#debug "\n\n"

#declare Psi = +30;
#declare Theta = -45;
#declare Phi = +15;

#declare vR =
vrotate(
vrotate(
vrotate(
v0,
Psi*z
),
Theta*x
),
Phi*z
)
;
#debug "vR = \n"
PrintVector3D(vR)
#debug "\n\n"

#declare Transform_313 =
transform {
rotate Psi*z
rotate Theta*x
rotate Phi*z
}

#declare vT = VectorTransform(v0, Transform_313);
#debug "vT = \n"
PrintVector3D(vT)
#debug "\n\n"

#declare MM_Rot_313_a = M_FromTransform(Transform_313);
#debug "MM_Rot_313_a = \n"
M_Print(MM_Rot_313_a)
#debug "\n\n"

#declare MM_R_a = M_Mult(MM_0R, MM_Rot_313_a);
#debug "MM_R_a = \n"
M_Print(MM_R_a)
#debug "\n\n"

#declare MM_Rot_Psi = M_Rotate3D_AroundZ(radians(Psi));  // 3
#declare MM_Rot_Theta = M_Rotate3D_AroundX(radians(Theta));  // 1
#declare MM_Rot_Phi = M_Rotate3D_AroundZ(radians(Phi));  // 3
#declare MM_Rot_313_b =
M_Mult(
M_Mult(
MM_Rot_Psi,
MM_Rot_Theta
),
MM_Rot_Phi
)
;
#debug "MM_Rot_313_b = \n"
M_Print(MM_Rot_313_b)
#debug "\n\n"

#declare MM_R_b = M_Mult(MM_0R, MM_Rot_313_b);
#debug "MM_R_b = \n"
M_Print(MM_R_b)
#debug "\n\n"

#error "No error, just finished!"

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

The result from running the code above:

v0 =
<3.000000, -4.000000, 2.000000>

MM_0R =
array[1][4] {
{  3.000000, -4.000000,  2.000000,  0.000000 }
}

vR =
<4.434831, 1.214589, 2.803043>

vT =
<4.434831, 1.214589, 2.803043>

MM_Rot_313_a =
array[4][4] {
{  0.745010,  0.565650, -0.353553,  0.000000 },
{ -0.641457,  0.462097, -0.612372,  0.000000 },
{ -0.183013,  0.683013,  0.707107,  0.000000 },
{  0.000000,  0.000000,  0.000000,  1.000000 }
}

MM_R_a =
array[1][4] {
{  4.434831,  1.214589,  2.803043,  0.000000 }
}

MM_Rot_313_b =
array[4][4] {
{  0.745010,  0.565650, -0.353553,  0.000000 },
{ -0.641457,  0.462097, -0.612372,  0.000000 },
{ -0.183013,  0.683013,  0.707107,  0.000000 },
{  0.000000,  0.000000,  0.000000,  1.000000 }
}

MM_R_b =
array[1][4] {
{  4.434831,  1.214589,  2.803043,  0.000000 }
}
```