PacktPublishing / Python-Scripting-in-Blender

Python Scripting in Blender, published by Packt
MIT License
38 stars 16 forks source link

Chapter 7 - Vert Runner #8

Closed emkademy closed 9 months ago

emkademy commented 9 months ago

Hi,

I am a bit confused with the explanations on how the aim_to_point method is created. The explanations use a unit circle with x and y coordinates to describe what needs to be done to rotate an object, but under Finding the shortest arc we suddenly switch to z coordinate. I don't understand why we did that. Also, I don't understand this statement:

To find the shortest arc away from the current rotation, 
we must store three possibilities in a tuple – the target orient, 
the same value after a complete clockwise rotation, and the same value rotated counterclockwise:

why do we need these 3 values to find the shortest arc?

pKrime commented 9 months ago

Hi, thanks a lot for raising this issue: rotations are a tricky topic and I wish I could have introduced it better. I would boil the confusing bits to two main issues:

Let's start with stating our goal: we want to orient an object so that it faces the direction of its motion. In our case, that means rotating only the z axis, as that's how you change the yaw from a rest position in blender.

So, in this specific case, we are only interested in the value to use for the z rotation channel: we will leave the rotations on x and y at 0.0 and never bother with them.

In chapter 4 it is mentioned how, unless we use Gimbal transform, rotating on one axis can affect the other rotation values if the object was already rotated on all three, but that's not the case here: rotating on the Z axis alone has no effect on euler values for X and Y. It is different when it comes to the individual coordinates of each vertex: rotations change the absolute position of every object point away from the pivot.

That also happens in our unitary circle representation: each direction (i.e. Z rotation if looked from above in blender) points to a vertex with a different x and y.

The method aim_to_point does the inverse: finds the angle used for pointing towards a given point with x and y coordinates .

Using the result as rotation_euler.z would be the end of the story if we weren't animating through a sequence: the value we get from aim_to_point is correct, but we don't want our object to revolve on itself when it heads toward the next destination.

There must be a smarter way to do that, but I propose a cheat: I compare the result of aim_to_point with the equivalent rotations after a clockwise and counterclockwise full circle. So the expression

arcs = (arc, arc + 2*pi, arc - 2*pi)

doesn't contain three coordinates, but three ways to write down the same angle. Say the results of aim_to_point is 10 degrees. Since rotations are cyclic, 370 degrees and -350 degrees express an equivalent orientation.

If the current value of rotation_euler.z is 0, setting it to 10 is fine. But if, because of a previous operation, rotation_euler.z is 340, we may want to use 370, which is only 30 degrees ahead rather than 330 degrees away in a counterclockwise rotation.

I hope that this example helped clear the confusion, please let me know if more explanation is required

Congratulations on your progress, Paolo

emkademy commented 9 months ago

Hi, thank you for your explanations. Some things are clearer now, but I still don't get the whole picture. I will experiment a little more for now, and then come back to you if I still don't get it. For now, we can close this issue.