POV-Ray : Newsgroups : povray.tools.general : vector direction turned into rotation angles Server Time: 14 Dec 2018 00:18:30 GMT
 vector direction turned into rotation angles (Message 1 to 10 of 10)
 From: Kenneth Subject: vector direction turned into rotation angles Date: 5 Oct 2018 03:15:01 Message:
```Hey, I figured it out!  :-)

If you have a vector direction, or spatial point position, or a traced(...)
normal, this code will find the angles that it makes with the <0,0,0> origin.
In other words, it finds the actual rotation angles for a given <x,y,z> vector,
to use for whatever purpose-- like rotating an object to align to that vector.
Or for placing into a #debug statement.

There are already tools in POV-Ray that align objects FOR you-- like
Point_At_Trans and Reorient_Trans-- but they don't give you the actual rotation
angles that are used. That's why I wrote this.

I went back to basic trigonometry to figure it out... then had to do some
reading-up on the  asin  function  (arc-sin.) There are only a few 'special
rules' in the code, to take care of certain asin behavior.
And... no matrix math ;-)

For grins, I've included the visual trig diagrams-- the triangles. They helped
me to work out the code.

You might notice that the code produces rotations for only TWO axes, around x
and y; but that's enough for determining the proper orientation of an object.
The third rotation axis is 'synthesized' by the other two, in a manner of
speaking... and it has its own weird but understandable logic: Imagine that you
(as an 'object') are standing vertically, with your arms in front of you,
holding onto a vertical pole. As you tilt backwards, you will always still face
the pole, no matter how far you spin around it in y. Same logic here. (Of
course, you could pre-spin the object in y to face some other direction,
*before* applying the found rotations.)  I might work up some code to counteract
this-- so that an object always faces a set direction when it's rotated; but
that's icing on the cake for now.

In the code, there are two meaningful objects-- a BLACK rod, which is simply the
physical embodiment of the vector; and a WHITE rod as a 'real' object, made
later and rotated with the code's results. But you'll see only a *single* rod,
with speckles-- that's  both rods occupying the same space, to prove that the
code works. I used POV-ray's coincident-surface phenomenon as proof! ;-)  If you
mess with the code in some bad way, you'll probably see BOTH rods.

If you see a way to make the code simpler or more elegant, speak up. I
eventually want to turn it into a macro(?)

[You may have guessed that I plan to use this in my on-going 'position finder'
work, to solve a problem *there*.]

------------------
// October 3-4 2018

#version 3.7; // or 3.71 or 3.8
global_settings {assumed_gamma 1.0}
#default{finish{ambient .1 diffuse .9}}

#declare VECTOR = <-.9,.8,.6>; // or whatever values

//------------------------------
camera {
perspective
location  <.5, 1.5, -2.5>
look_at   <0, .3, 0>
right     x*image_width/image_height
angle 35
}

light_source {
0*x
color rgb .8
translate <200, 400, -200>
}

light_source {
0*x
color rgb .5
translate <-200, 100, -200>
}

background{rgb .1}

// origin indicators
union{
cylinder{<-.15,0,0>,<.15,0,0> .010}  // X
cylinder{<0,-.15,0>,<0,.15,0> .010}  // Y
cylinder{<0,0,-.15>,<0,0,.15> .010 } // Z
pigment{rgb <1,.6,0>}
}

plane{y,0
pigment{
cells color_map{[0 rgb .1][1 rgb .6]} translate 3
}
}

//-------------- THE CODE -----------
// Important 'fudge factors' due to POV-Ray's inner workings, to prevent
// fatal "uncategorized error" (because of vnormalize below?)--
#if(VECTOR.x = 0)
#declare VECTOR = <0.0001,VECTOR.y,VECTOR.z>;
#else
#end

#if(VECTOR.y = 0)
#declare VECTOR = <VECTOR.x,0.0001,VECTOR.z>;
#else
#end

#if(VECTOR.z = 0)
#declare VECTOR = <VECTOR.x,VECTOR.y,0.0001>;
#else
#end

#declare VECTOR = vnormalize(VECTOR);

// The visual stand-in for the VECTOR

// The trig construction lines...
// RED
union{
cylinder{VECTOR,<VECTOR.x,0,VECTOR.z> .007}
cylinder{0,<VECTOR.x,0,VECTOR.z> .007}
pigment{rgbt <1,0,0,.5>}
}

// GREEN
union{
cylinder{0,<VECTOR.x,0,0> .007}
cylinder{<VECTOR.x,0,0>, <VECTOR.x,0,VECTOR.z> .007}
pigment{rgbt <0,.2,0,.5>}
}

#declare X_Y_PLANE_ANGLE = 90 - degrees(asin(VECTOR.y/1));
// to get the degree of rotation, referenced to an imaginary
// 'rotated' X/Y plane-- think of it as the final 'elevation'.
// It's the arc-sin of y/R in that plane--
// R (the hypoteneuse length) is 1.0-- the VECTOR length

#declare NEW_HYPOT = sqrt(pow(VECTOR.x,2) + pow(VECTOR.z,2));
// The PROJECTION of the 'VECTOR' length onto the horizontal X/Z plane--
// its length *there* compared to its real length of 1.0. This is for use
// in the X_Z_PLANE_ANGLE equation below, as the 'R' for its trig function.
// sqrt(x^2 + y^2 = R^2) to find the length of this 'new'
// hypoteneuse-- with the Z value substituted for Y.

// NOTE: At this point, the NEW_HYPOT value is always positive-- which may or
// may not be a good thing(?). But it causes no problem.

// This #if is the KEY to getting things right...
#if(VECTOR.x < 0)
#declare X_Z_PLANE_ANGLE = degrees(asin(VECTOR.z/NEW_HYPOT));
// to get the degree of rotation, AS SEEN ON the horizontal X/Z plane--
// it will actually be the rotation around the y-axis, to be applied AFTER
// the previous x-axis 'elevation'. Arc-sin of y/R, as seen looking DOWN
// on X/Z plane. NEW_HYPOT is NOT 1.0 in this plane.
#else
#declare X_Z_PLANE_ANGLE = degrees(-asin(VECTOR.z/NEW_HYPOT)); // ditto
#end

// The special rules...
#if(VECTOR.x < 0)
#declare X_Z_PLANE_ANGLE = X_Z_PLANE_ANGLE - 90;
#else
#end

#if(VECTOR.x >= 0)
#declare X_Z_PLANE_ANGLE = X_Z_PLANE_ANGLE + 90;
#else
#end

#declare FINAL_ROT =
<X_Y_PLANE_ANGLE,X_Z_PLANE_ANGLE,0>; // the final rotations!

// --------- END OF CODE ------------

// NEW rod, using the found rotation values
union{
cylinder{0,1.0*y .015}
text{ttf "cyrvetic.ttf" "POV-Ray" 1, 0
pigment{
color_map{
[.5 rgb .6*x]
[.5 rgb .2*z]
}
scale 1.1
translate -.05*z
}
scale .5*<.2,.2,.04>
translate <-.2,1,-.02>
}

// rotate ... *y // optional, to add any desired pre-spin to the object

#if(VECTOR.y < 0) rotate 180*y #else #end // optional, and only if
// VECTOR.y goes negative--  to keep the visual orientation of the
// object consistent with positive VECTOR.y appearance.
rotate FINAL_ROT
pigment{rgb 2}
}
```
 From: Thomas de Groot Subject: Re: vector direction turned into rotation angles Date: 5 Oct 2018 07:48:37 Message: <5bb71755\$1@news.povray.org>
```On 5-10-2018 5:12, Kenneth wrote:
> Hey, I figured it out!  :-)
>

Smart and well done, sir! I shall not pretend that I already understand
everything, but with some messing around that may well be in my future.

[I have some nagging feeling in my brain that I did something similar in
the past but it totally escapes me. Most probably a false positive] :-)

--
Thomas
```
 From: Kenneth Subject: Re: vector direction turned into rotation angles Date: 5 Oct 2018 16:10:01 Message:
```"Kenneth" <kdw### [at] gmailcom> wrote:

>
> You might notice that the code produces rotations for only TWO axes, around x
> and y; but that's enough for determining the proper orientation of an object.
> The third rotation axis is 'synthesized' by the other two, in a manner of
> speaking...

Now that I've had a chance to stand back and look at the results, I see that the
'3rd-axis' of rotation isn't really there. It would be the additional 'spin' or
facing-direction of the POV-Ray logo. Currently, the logo direction is just a
natural and automatic consequence of the code rotations in x and y.

I've already worked out one conceptual way of adding that spin-- to keep the
logo always facing -z, for example:

rotate (1 - (VECTOR.z))*90*y
THEN, the main rotations...
rotate <X_Y_PLANE_ANGLE,X_Z_PLANE_ANGLE,0>

The ordering of these is important. Note that there's a rotation in y first,
then a rotation in x, then *another* rotation in y. Simply adding the first
y-rotation within the 2nd rotate command does not produce the same results.

But I want the final rotation vector to be a *single* entity-- all the rotations
being combined-- in order to GET the final rotation angles themselves. The only
way to do that is to combine these two rotation statements into a transform, for
use. But I want to avoid using a transform-- because it becomes a pure matrix
behind-the-scenes, with no (easy!)way to then reconstruct the individual
rotations.

Although-- I'm still studying some matrix-to-angle code suggestions made by
others here  ;-)

While it's true that this 3rd-axis 'spin' can EASILY be added *manually* to an
object-- see the end of my scene file-- it would be far more elegant to do so
within the code (especially for animation purposes, where the 'spin' rotation
might need to constantly change.)

The code as-is is perfectly usable, though; it's just not as elegant or
self-contained as I'd like.
```
 From: Bald Eagle Subject: Re: vector direction turned into rotation angles Date: 5 Oct 2018 19:20:01 Message:
```If all you're doing is applying a series of rotations to an object, then start
with the default transformation matrix, and sequentially multiply it by the
rotation matrices of the individual rotations.

If I understand the power of a transformation matrix, then all of the rotations
you perform will be condensed into a single operation so that you can then
perform a rotate <x, y, z> operation with those values.

Easiest way I can think of to work this out is to take a highly asymmetric
object - the Stanford Dragon or just 3 arrowed axes - and instantiate it with
each progressive rotation.

Then in the same scene have the object as transformed by the matrix.

Then you can visually work out the matrix step by step if you have to until it
matches the rotate, rotate, rotate version.
```
 From: Bald Eagle Subject: Re: vector direction turned into rotation angles Date: 5 Oct 2018 19:25:00 Message:
```"Kenneth" <kdw### [at] gmailcom> wrote:
> Hey, I figured it out!  :-)

As I knew you would.   Excellent work!   :)

> // The PROJECTION of the 'VECTOR' length onto the horizontal X/Z plane--

Although I LOVE that you worked it out a priori:

You know that there are macros and functions for this, right?

http://www.povray.org/documentation/view/3.6.2/459/
```
 From: Thomas de Groot Subject: Re: vector direction turned into rotation angles Date: 6 Oct 2018 06:55:19 Message: <5bb85c57\$1@news.povray.org>
```On 5-10-2018 21:20, Bald Eagle wrote:
>
> You know that there are macros and functions for this, right?
>
> http://www.povray.org/documentation/view/3.6.2/459/
>
>

Ha! Got it! That is where my earlier hunch came from of course! I used
/those/ in some scene macros in the past!

I have to do something about my memory I guess ;-)

--
Thomas
```
 From: Kenneth Subject: Re: vector direction turned into rotation angles Date: 6 Oct 2018 07:15:01 Message:
```"Bald Eagle" <cre### [at] netscapenet> wrote:

>
> Although I LOVE that you worked it out a priori:
>
> You know that there are macros and functions for this, right?
>
> http://www.povray.org/documentation/view/3.6.2/459/

Honestly, I would say that I understand maybe half of those things, from a
conceptual/3-D spatial viewpoint (my preferred or ONLY way of thinking about
math concepts.) Others like dot-products I have a really hard time visualizing.
And of the ones that I *do* understand, I'm just not sure how or when to use
some of them. THAT's quite frustrating-- to know that they are useful, but to
not know when to apply them.

That's really why I wanted to work out this angle-finder code from scratch (so
to speak); I could follow my own step-by-step construction, while using just
basic tools. Of course 'basic tools' is a relative concept-- I can tell that
you're WAY ahead of me in the maths department ;-) But I'm learning some

From that docs page, I DO see some tools that I could have used...

VAngle(V1, V2), VAngleD(V1, V2)-- Compute the angle between two vectors.

VCos_Angle(V1, V2)-- Compute the cosine of the angle between two vectors.

[hey, where's VSin_Angle(V1 V2) ??]

VProject_Plane(V1, Axis)-- Project vector V1 onto the plane defined by Axis.
[Uh, then what? Does it return a length? A vector?]

.... but their actual operations still appear a bit mysterious to me. Maybe it's
the rather terse 'textbook' descriptions that give me a hard time, I dunno.
```
 From: clipka Subject: Re: vector direction turned into rotation angles Date: 8 Oct 2018 17:34:38 Message: <5bbb952e@news.povray.org>
```Am 06.10.2018 um 09:12 schrieb Kenneth:

> Honestly, I would say that I understand maybe half of those things, from a
> conceptual/3-D spatial viewpoint (my preferred or ONLY way of thinking about
> math concepts.) Others like dot-products I have a really hard time visualizing.
> And of the ones that I *do* understand, I'm just not sure how or when to use
> some of them. THAT's quite frustrating-- to know that they are useful, but to
> not know when to apply them.

Speaking of dot product...

> VAngle(V1, V2), VAngleD(V1, V2)-- Compute the angle between two vectors.
>
> VCos_Angle(V1, V2)-- Compute the cosine of the angle between two vectors.
>
> [hey, where's VSin_Angle(V1 V2) ??]

Because `VCos_Angle` is more fundamental (see below) - even more
fundamental than `VAngle`.

> VProject_Plane(V1, Axis)-- Project vector V1 onto the plane defined by Axis.
> [Uh, then what? Does it return a length? A vector?]

A vector.

In essence, the "portion" of `V1` that is perpendicular to `Axis`.
Or what is left of `V1` if you take away the component in the direction
of `Axis`.

For example, if `Axis` would happen to be +z or -z, the result would be
equal to `<V1.x,V1.y,0>`; or if `Axis` would happen to be +x or -x, the
result wold be equal to `<0,V1.y,V1.z>`; and so on.

> ..... but their actual operations still appear a bit mysterious to me. Maybe it's
> the rather terse 'textbook' descriptions that give me a hard time, I dunno.

The core building block of these all happens to be the dot product.

For me, the key property of the dot product is as follows:

Suppose you have a /unit-length/ vector A specifying a direction, and an
arbitrary vector B:

______ ..........__
|    /:\ |       /\
|  Ba :__|90    / B
|     :        /
|    /|\      /
|   A |      /
L|     |     /
|     |    /
|     |   /
|     |  /
|     | /
|     |/
------ *

(The orientation of A may be aribtrary; it's only axis-aligned here
because it makes ASCII art easier ;))

Then picture a right-angled triangle as drawn above, with B as the
longest leg (hypotenuse for the initiated), and one of the other legs
(one of the catheti) in the /direction/ of A.

Then the dot product of A and B gives you the length L of the A-aligned
leg - in other words, the distance between the common corner and the
right-angled corner.

(Remember, this only works if A is of unit length; otherwise, the dot
product grows or shrinks proportional to the length of A; not sure where
one would explout that - to me it is just a nuisance.)

This property can be put to good use in the following ways:

- Dividing L (the dot product) by the length of B gives the cosine of
the angle between the two vectors. (Or, if B is also of unit length, the
dot product /is/ the cosine.)

This is what `VCos_Angle` and `VAngle` use.[*]

- Multiplying A by L (the dot product) gives us the vector from the
common corner to the right-angled corner of the triangle (Ba in the
above diagramoid) - the component of B that is co-linear with A, if you
will. Or the projection of B onto A.

This is what `VProject_Plane` uses[*], by subtracting this vector Ba
from B, thus getting the component of B that is perpendicular to A.
```
 From: Kenneth Subject: Re: vector direction turned into rotation angles Date: 8 Oct 2018 20:10:01 Message:
```clipka <ano### [at] anonymousorg> wrote:

>
> Speaking of dot product...
>
>
>   ______ ..........__
>    |    /:\ |       /\
>    |  Ba :__|90    / B
>    |     :        /
>    |    /|\      /
>    |   A |      /
>   L|     |     /
>    |     |    /
>    |     |   /
>    |     |  /
>    |     | /
>    |     |/
>   ------ *
>

Hey, that's great :-)  Nice and graphical. Thanks for taking the time and effort
to explain it so well. Now, I can go back to the pertinent Wikipedia article
with some new-found knowledge, to try and understand *that* description.

(If I was ever taught anything about do-products while in college those MANY
years ago, I've certainly forgotten it.)

Funny thing: Of the many maths classes I had to take (even prior to college),
CALCULUS was actually the most interesting and easily-grasped, for me-- the
direct result of having an excellent teacher. On the other hand, GEOMETRY (well,
its proofs) was exactly the opposite-- and for the same (opposite) reason.

But the ironic thing is, I don't *think* that I've ever had to actually USE
calculus during my lifetime(!) So my 'mental machinery' has become quite rusty.
Yet, trig concepts-- the basic ones-- have always stuck with me. And I do find
uses for those from time to time.
```
 From: Thomas de Groot Subject: Re: vector direction turned into rotation angles Date: 9 Oct 2018 06:46:06 Message: <5bbc4eae\$1@news.povray.org>
```On 8-10-2018 22:07, Kenneth wrote:
> But the ironic thing is, I don't *think* that I've ever had to actually USE
> calculus during my lifetime(!) So my 'mental machinery' has become quite rusty.
> Yet, trig concepts-- the basic ones-- have always stuck with me. And I do find
> uses for those from time to time.
>

I join Kenneth with my own thanks too. I would add to that that I never
ever was taught vector calculus (like dot product) either. And as for
use in RL (professionally or otherwise): no, never. So, nice new
knowledge indeed!

--
Thomas
```