7 views (last 30 days)

Show older comments

Hi all,

EDIT#1: Added the .m script as an attachement

-------------------------- EDIT#2: Please read the comments --------------------------

Presentation (you can skip)

Thanks for your interest. Sorry for the title, it is a bit of a mouthful. Let me explain...

I have a large 3D printed D20 also named icosahedron. Basically, it has 20 faces. Please have a look at the attached picture :) .

I can attach a 3D angular sensor to any of the faces. The sensor would return me the 3D projection of the gravity like [0 0 -9.81] or [0 -4.905 -4.905].

What I would like to do

In Matlab, I would like to simulate this. To be more specific, given any of the 20 faces as a reference, I would like to get the 20 projections of the gravity (because of the 20 faces).

Let me explain this a bit more :)

Each time I "roll" the dice, I basically force one of the triangular faces to be "flat" (parallel to the XY plane). The reference face (to which my sensor is attached) is at a different angle. Therefore the gravity is not [0 0 -9.81] but a projection.

These projections are what I would like to calculate.

Therefore I think I expect to get a matrix like this:

projection#1 ---> [ [X Y Z];

projection#2 ---> [X Y Z];

...

projection#20 ---> [X Y Z] ]

What I can do

- I have managed to get a list of all the D20 vertices.
- With that, I can construct the 20 triangular faces of the icosahedron.
- And I can get the 3D normal vectors of each to each of the 20 faces.

Where I am stuck

But the part where I am stuck is calculating the 3D angles (can I name them roll/pitch/yaw?) given 2 normals to the planes:

- the one which is flat
- the one on which the sensor is attached

Do I need a quaternion? a rotation matrix? What would be the best way to calculate the 20 orientations?

I tried something like the following but it only retuns a single angle:

Angles_roll_pitch_yaw(cnt_face,:) = atan2(norm(...

cross(refrence_3D_vector,Normals_Vector(cnt_face,:))), ...

dot(refrence_3D_vector,Normals_Vector(cnt_face,:)));

Thank you very much for your time.

Sorry for the long post.

EDIT: I really can't understand if I need and what the function "vrrotvec" returns

James Tursa
on 20 May 2021

Edited: James Tursa
on 20 May 2021

If you have the 3D normal vectors, then all you need to do is take the dot product between them and the "flat" face normal vector. This will give you the cos(angle) between them which you can use to multiply by the normal vectors to get your gravity projection. E.g.,

flat_normal = the 3D normal vector of the flat face

other_normal = the 3D normal vector of another arbitrary face

g = gravity magnitude

flat_gravity = g * flat_normal

other_gravity = g * dot(flat_normal,other_normal) * other_normal

Is this what you are trying to do?

Side Note: You may need to use -g instead of g to get things to match your sensors output. Strictly speaking accelerometers measure reaction force, not gravity, and reaction force is (sort of) in the opposite direction from gravity. The caveat is because if you are on the ground you would strictly need to account for rotation of the Earth to get a more accurate reaction force.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!