View Full Version : Vector & angle puzzle....
noontz 01032008, 01:43 PM I swear I have used the insideout of whatīs left inside my brains to solve this one, but iīm giving up and hope the great math potential on this forum can help me out..
Thing is i need the angle between (p1p2) (p5p4) both projected on the plane perpendicular to (p2p4) ( p2p3 whatever ).. It is not enough for me to just get the angle between the two cross products (p1p2p3) (p3p4p5), as I need the full angle (0360) of (p5projectedp3) relative to (p1projectetp3).. Iīll spare you for all my code attempts :hmm: (http://forums.cgsociety.org/misc.php?do=getsmilies&wysiwyg=1&forumid=0#) as the solution might be obvious for those who know their M&Ms.. (Maths&Matrixes) :thumbsup:
http://www.noontz.net/picsinspace/vektor.jpg


This is from top of my head, I am doctoring a PC right now and cannot go and test it, but:
1. You need the plane perpendicular to the p4p2 first. Use matrixFromNormal to get a matrix where the Z axis is parallel to p4p2.
2. Now you need the projection of the two vectors in the XY plane of this new coordinte system. Since both p2 and p4 lie on the Z axis, all we need are the XY coordinates of the points p1 and p5. To get these vectors, simply multiply each vector (p1p2) and (p5p4) by the matrix from step 1, then replace the Z component with 0 because you are interested in the projection of the vectors in the XY where the X and Y are as calculated but the Z is zero. Let's call these projection vectors a and b.
3. Now that you have two vectors in a common coordinate system, calculate the acos( dot (normalize a) (normalize b) ) to get the angle. The result will be in the range from 0 to 180. To get the range 0 to 360, you will have to find out when the cross product of the same two vectors flips its Z axis  in the range from 0 to 180 the cross product's Z axis will be parallel to the positive Z axis of the current coordinate system (the Z component of the cross product will be positive), when the angle exceeds 180 degrees, the calculation will give you an angle going down from 180 to 0, but the Z component of the (cross a b) will flip sign and you can check for that and use 360theAngle to get the desired full angle.
Once again, this from top of my M&M head, I might have missed something...
EverZen
01032008, 03:14 PM
Noontz.
Definitley an interesting one.
The cross product of 2 vectors will yield a 3rd vector that is perpendicular to the first two. This could be used to effectively generate your projected vectors....
So maybe something like (and im afraid I really dont have time at the moment to test this, but I will try and find some ;) )
First Normalize all the vectors
VerticalVec = normalize(p4p2)  This is our reference vector
p5Vec = normalize(p5p4)
p1Vec = normalize(p1 p2)
Now we can create our projected vectors onto the plane  they should be normalised since both in the input vectors are normalized
p5ProjectedVec = cross VerticalVec p5Vec
p1ProjectedVec = cross VerticalVec p1Vec
/*
Note that both these vectors would be on the required plane, but they would both be 90 degrees out from the drawn vectors (since we are using the cross product) so
p5ProjectedVec is perpendicular (in marked grid) to the vector (p5Projectedp3)  as marked on your drawing
p1ProjectedVec is perpendicular (in marked grid) to the vector (p1Projectedp3)  as marked on your drawing
Now having the vectors out by 90 degrees could be tought of as a problem, but since BOTH vectors are out by 90 degrees then the relative angle between them should remain the same so there wont be a problem... please test this theory!
*/
From there we have the two needed normalized vectors so we can calculate the angle using the function in help...
fn GetVectorsAngle v1 v2 =
(
theAngle = acos(dot (normalize v1) (normalize v2))
)
ProjectedAngle = GetVectorsAngle p5ProjectedVec p1ProjectedVec
Now this might need some polishing, but I think it is on the right lines, but I am afraid that I cannot test it. Please give it a whirl, I recommend placing objects in the positions yielded from some of these calculations to make sure that things are roughly in the right place....
If I am completely wrong then just shout, and ill have another look at it....
Hope it helps though mate....
Rich
P.S Check all the commands are right, I dont have max infront of me so my syntax might be out.....
EverZen
01032008, 03:16 PM
In my experience do what Bobo says ;)
But if you have time, then see if my solution is any where near right.... I would be most interested...
Cheers ;)
Rich
noontz
01032008, 03:49 PM
Hi Rich & Bobo
Thx so much for both replies!!!
The solution from you Rich was my initial go, but it only yields an "absolute" angle between 0180 degrees. I tried all kinds of tricks to get the correct "flip" + , but no cigar. I will try Boboīs angle and give feedback as soon as Iīve been through some tests :thumbsup:
EverZen
01032008, 04:03 PM
Noontz,
Cheers for the feedback :) Sorry to have told you what you have all ready tried...
Bobos method yields the same 0180 solution mid way through the calculation, since it uses the same acos( dot (normalize a) (normalize b) ) command.
It is Bobos later section of part 3 which is a sublime method for solving the flip issue, which is the missing piece to my approach and perhaps your initial method. Explore Bobos method too (and probably use it!), since the matrixFromNormal command is so so useful in a number of situations.
Thanks Bobo, I have now pocketed that little trick with the cross products to detect a flip. Very neat, and something I have managed to completely over look!
Good luck Noontx, let us know if you get it solved :)
Rich
noontz
01032008, 09:32 PM
Hi again Rich & Bobo
Thx again for the great feedback, but there seems to be more to the picture than meets the eye, so I hope I can catch your interest on the subject :)
Underneath is the code trying both methods for the initial angle and Bobos for the "flip". All the print stuff is just to analyze in the listener so comment it out if itīs a bore..
Anyway.. Both methods brings the correct 225 degrees at start, but try moving vertice 5 around and trouble begins, and even more if you rotate all the vertices to check different angles of the fixed structure. The c d version seems to be stable with the initial angle, but itīs still the correct time to "flip" thatīs missing as 135 will show up eventually..
Hereīs the maxscene I used for testing: 5knots.zip (http://www.noontz.net/picsinspace/5knots.zip)
Hope you guys can help me out
utility anglemeasure "anglemeasure"
(
pickbutton get "Get it"
label test ""
fn angle p =
(
zAxis = normalize ( p[4]  p[2] )
v1 = normalize ( p[1]  p[2] )
v2 = normalize ( p[5]  p[4] )
plane = matrixFromNormal zAxis
a = v1 * plane
b = v2 * plane
c = cross zAxis v1
d = cross zAxis v2
print p[1]
print p[2]
print p[3]
print p[4]
print p[5]
print zAxis
print v1
print v2
print plane
print a
print b
a.z = 0
b.z = 0
print a
print b
theAngle = acos( dot (normalize a)(normalize b))
theAngle = acos( dot (normalize c)(normalize d))
if (cross a b).z < 0 then theAngle = 360  theAngle
print theAngle
test.caption = "the angle is " + theAngle as string
)
on get picked spline do  pick the 5 vertice spline
(
p = #()  reset p
for i = 1 to numKnots spline do  gather vertice positions
(
a = in coordsys world getKnotPoint spline 1 i
append p a
)
angle p  calculate the angle with the points
)
My bad, you should multiply A and B by the INVERSE of the matrix, because we want to convert the whole system back so that the p4p2 vector is aligned to the world coordinate system, then setting the Z to 0 makes sense as we project onto the XY of the world regardless of the Z vector's original orientation.
I played with it and even compared the results with the Protractor and they are identical.
noontz
01042008, 07:42 AM
Hi Bobo & Rich ( & any other vectoraddicts )
First of all : A friend of mine, Jan Fjordside, recommended this forum & I gotta say it fully lives up to itīs reputation.. Amazing to get an answer so quick on a rather complicated issue! Thanks again for the help!!
That word "inverse" did all the difference. Man!! Iīve been through so much stuff on matrixes before posting on this forum, but never really caught the essens! Only one thing to do now: Get Bobos DVD :thumbsup:
Here is the final code for anyone stumbling on this thread:
zAxis = normalize ( p[4]  p[2] )  vector perpendicular to the plane
v1 = normalize ( p[1]  p[2] )  vector p1p2
v2 = normalize ( p[5]  p[4] )  vector p5p4
plane = inverse ( matrixFromNormal zAxis )  check Bobos Matrix DVD ;)=)
a = v1 * plane  move vector to world space
b = v2 * plane
a.z = 0  project to xy ( removing the z component )
b.z = 0
theAngle = acos( dot (normalize a)(normalize b))  initial 0180 angle
if (cross a b).z < 0 then theAngle = 360  theAngle  check the direction of cross a b
EverZen
01042008, 08:59 AM
noontz,
This forum is great for these kinds of problems. People really take the time out to solve other peoples problems. I have posted so many of my difficulties up here, and people have come up with a solution practically every time, which is amazing. Since everyone seems to have the same sharing attitude then you find yourself helping (or trying!) people, and then when it comes round to your turn everyone helps you. At times you get some of the greatest minds consulting your problem (and some less great minds too ;) )!
Overall this forum must have saved me hours, and I have learned so much.
Cheers also for posting the final code, it is great to get a finished solution that can be referred to when similar scenarios occur in your own work!
Good luck with it all :)
Rich
Overall this forum must have saved me hours, and I have learned so much.
While it might not be obvious, even the people who help solving the problems DO learn something every time. We are not just sharing knowledge here, we are all exercising our brains on unusual cases. If I ever have to find the full angle of two crossing noncoplanar vectors, I will have one thing less to think about :)
EverZen
01042008, 09:38 AM
First of all, use Bobos method, its slick.
But, I think you can use Bobos flip method for the final section of your initial idea, it just doesnt make sense to test the z component of the cross product at the end, since we have not aligned our coordinate system to the new Z Axis.
However, it does make sense to test the cross product vector against the (p4  p2) vector. We can Compare our vector produced (using the cross product) to the normalized (p4 p2) vector using a dot product! If they are parallel the dot product would be 1, since they are both normalized, but as the cross product flips, the result dot product should flip to 1, and you can test for this sign change
So your the Code may change to something like (using the intial method) ....
First Normalize all the vectors
VerticalVec = normalize(p4p2)  This is our reference vector
p5Vec = normalize(p5p4)
p1Vec = normalize(p1 p2)
Now we can create our projected vectors onto the plane  they should be normalised since both in the input vectors are normalized
p5ProjectedVec = cross VerticalVec p5Vec
p1ProjectedVec = cross VerticalVec p1Vec
From there we have the two needed normalized vectors so we can calculate the angle using the function in help...
fn GetVectorsAngle v1 v2 =
(
theAngle = acos(dot (normalize v1) (normalize v2))
)
theAngle = GetVectorsAngle p5ProjectedVec p1ProjectedVec
Now introduce the Check against VerticalVec, by producing a flip vector for the test
FlipTestVec = (cross p1ProjectedVec p5ProjectedVec) this should be normalized
Now we can compare this vector to our axis vector VerticalVec using the dot product and check for the sign change!
if dot (VerticalVec FlipTestVec) < 0 then theAngle = 360  theAngle
There may be a sign error here.... check it if you have time!
In principle I think this successfully builds in Bobos flip method to your initial way of solving the problem. I have not had time or max to test it, and I really should before pasting it around everywhere, but it really is here just for completeness, although again I would be interested to see if it actually works! If anyone else sees a flaw in the logic please point it out.
Proceed with Bobos method though, and in principle I would try and solve these types of problems with his matrixnormal approach....
Good luck :)
Rich
CGTalk Moderation
01042008, 09:38 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©20002015, Jelsoft Enterprises Ltd.