









 
 




 
 


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 POVRay 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
readingup on the asin function (arcsin.) 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 prespin 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 POVray's coincidentsurface 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 ongoing 'position finder'
work, to solve a problem *there*.]

// October 34 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
no_shadow
pigment{rgb <1,.6,0>}
}
plane{y,0
no_shadow
pigment{
cells color_map{[0 rgb .1][1 rgb .6]} translate 3
}
}
// THE CODE 
// Important 'fudge factors' due to POVRay'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 standin for the VECTOR
cylinder{0, VECTOR .015 no_shadow}
// 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>}
no_shadow
}
// 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>}
no_shadow
}
#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 arcsin 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 yaxis, to be applied AFTER
// the previous xaxis 'elevation'. Arcsin 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" "POVRay" 1, 0
pigment{
gradient z
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 prespin 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}
no_shadow
}
Post a reply to this message


 
 


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 5102018 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
Post a reply to this 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
'3rdaxis' of rotation isn't really there. It would be the additional 'spin' or
facingdirection of the POVRay 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
yrotation 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
behindthescenes, with no (easy!)way to then reconstruct the individual
rotations.
Although I'm still studying some matrixtoangle code suggestions made by
others here ;)
While it's true that this 3rdaxis '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 asis is perfectly usable, though; it's just not as elegant or
selfcontained as I'd like.
Post a reply to this 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.
Post a reply to this 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/
Post a reply to this message


 
 


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 5102018 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
Post a reply to this 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/3D spatial viewpoint (my preferred or ONLY way of thinking about
math concepts.) Others like dotproducts 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 anglefinder code from scratch (so
to speak); I could follow my own stepbystep 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
important things from your discussions.
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.
Post a reply to this message


 
 


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/3D spatial viewpoint (my preferred or ONLY way of thinking about
> math concepts.) Others like dotproducts 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 /unitlength/ 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 axisaligned here
because it makes ASCII art easier ;))
Then picture a rightangled 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 Aaligned
leg  in other words, the distance between the common corner and the
rightangled 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 rightangled corner of the triangle (Ba in the
above diagramoid)  the component of B that is colinear 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.
Post a reply to this 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 newfound knowledge, to try and understand *that* description.
(If I was ever taught anything about doproducts 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 easilygrasped, 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.
Post a reply to this message


 
 


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 8102018 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
Post a reply to this message


 
 




 

