#98916 - Rajveer - Fri Aug 18, 2006 2:27 pm
hi, i can see that there is no inverse cos function in libnds (i need it for finding the angle between 2 dot-produced-normalized vectors). ive been reading some threads and people suggest look up tables: is this correct? how would i create a look up table? how would i create a function to find inv cos anyways (if i were to create an lut)?
also, im a bit confused about angles. i thought ds used 0-511 for angles, howver when i use glRotate to rotate objects, it uses angles from 1-360. why?
cheers
#98922 - Mighty Max - Fri Aug 18, 2006 3:12 pm
Rajveer wrote: |
hi, i can see that there is no inverse cos function in libnds (i need it for finding the angle between 2 dot-produced-normalized vectors). ive been reading some threads and people suggest look up tables: is this correct? how would i create a look up table? how would i create a function to find inv cos anyways (if i were to create an lut)?
|
Walk through the existing LUT and find the entry with the least difference to the searched. You can speed that up a bit with reducing the range you walk through. (+ values from 0 to 128, - values from 128 to 256)
Most times however it is sufficent to keep the cos value of the angel. if you need to get the sin of the same angel i.e. you can calculate it without going through inv cos: 1 = sin^2 + cos^2.
Quote: |
also, im a bit confused about angles. i thought ds used 0-511 for angles, howver when i use glRotate to rotate objects, it uses angles from 1-360. why?
|
It's gl-Standard to use the 360 degrees scale.
_________________
GBAMP Multiboot
#98928 - kevinc - Fri Aug 18, 2006 3:50 pm
Isn't the "acos" function in math.h implemented in devkitpro? You can use that to create the lookup tables.
Or, you can use a cosine lookup table from [0-180). Because cos is a monotonous decreasing function, the cos values will be ordered in decreasing order, so you can use a bsearch to get a close estimate in O(log(n))
_________________
http://akzeac.blogspot.com
#98937 - Rajveer - Fri Aug 18, 2006 4:48 pm
cool, cheers guys.
mighty max: so i create an array of data with the angle and the inverse cos? and then see which value mine is closest too and use that?
kevinc: hmm i tried acos first but it didnt give me any results :S it gave the inverse as 0 all the time. the cosine lookup table makes sense since the inverse just maps the range to the domain, so i could just look up the values the other way round right?
#98943 - kevinc - Fri Aug 18, 2006 5:02 pm
Yep. But, because the values aren't exact, you'll have to get the closest one.
It's funny that acos isn't implemented. If you still want to use it, you can use an approximation:
acos(z) = PI / 2 - z + (z ^ 3) / 6 + 3 * (z ^ 5) / 40, where z is a float between [-1, 1].
Then multiply the result by 180 / PI to get the value in degrees. However, are you sure you need the angle at all? You can calculate sin and tan directly from cos.
_________________
http://akzeac.blogspot.com
#98958 - Rajveer - Fri Aug 18, 2006 7:05 pm
yeah need the angle, i got an object with which i use a ray-triangle intersection for the triangles on the "ground", and then want to calculate the angle between the objects "y-axis" and the grounds normal which i can use to rotate the ship in the new axis (unless you know of a way where i dont need to calculate the angle :) )
cheers for all the help, ill try implementing it and see how it goes :)
#98963 - Rajveer - Fri Aug 18, 2006 7:33 pm
so atm my understanding is that there are already lookup tables for sin and cos, called SIN and COS. now to use it to find cos(angle) or sin(angle) you would use COS(angle) and SIN(angle) right? if so, how do u use these lut's for going the otherway round (inverse)?
p.s. these lut's are out of 0-511 right? because to use the angle in opengl, id have to divide the angle by the ratio which isnt what anybody would want :)
#98965 - kevinc - Fri Aug 18, 2006 7:50 pm
Rajveer wrote: |
yeah need the angle, i got an object with which i use a ray-triangle intersection for the triangles on the "ground", and then want to calculate the angle between the objects "y-axis" and the grounds normal which i can use to rotate the ship in the new axis (unless you know of a way where i dont need to calculate the angle :) ) |
Nope, you don't :), I thought you were trying to display the angle.
Suppose you know the angle. Then, for the rotation, you're surely going to multiply each point by a matrix (if you're going to use a rotation function, check the implementation). You'll see there that all you're going to use is cos(angle), and sin(angle), never the angle itself.
Just replace all instances of cos(angle) with the dot product, and sin(angle) with sqrt(1 - dotp * dotp). It's much better that way.
_________________
http://akzeac.blogspot.com
#98966 - Rajveer - Fri Aug 18, 2006 7:56 pm
ahhhh cool i understand what you mean (already know about matrices and opengl rotations/transformations but it didnt click lol).
the thing i wanted to avoid however was to have to do three rotation matrices and rather just use one axis-angle call (since all rotations can be represented as one rotation) with the correct axis which id calculate with a cross product of the polygon normal and the ships y-axis. this is because im not sure about the correct orders and how to do custom axis-angle rotations with matrices (all i know is how to do them in x,y and z axis). any ideas?
p.s. cheers for the help!
#98971 - kevinc - Fri Aug 18, 2006 8:56 pm
Rajveer wrote: |
this is because im not sure about the correct orders and how to do custom axis-angle rotations with matrices (all i know is how to do them in x,y and z axis). any ideas?
p.s. cheers for the help! |
Oh. That's a complicated theme.
Let's say the rotation vector is (bx, by, bz), normalized. If it's not in the origin but in the position a, first do a translation to -a, then the rotation, then a translation to a.
You'll have to use a quaternion. Let's say:
w = cos(θ/2)
x = bx * sin(θ/2)
y = by * sin(θ/2)
z = bz * sin(θ/2)
The matrix would then be:
Code: |
1 - 2y2- 2z2 2xy - 2wz 2zx + 2wy 0
2xy + 2wz 1 - 2x2 - 2z2 2yz - 2wx 0
2zx - 2wy 2yz + 2wx 1 - 2x2 - 2y2 0
0 0 0 1
|
You can use glLoadMatrix (or something like that) to enter the matrix directly.
_________________
http://akzeac.blogspot.com
#98978 - Rajveer - Fri Aug 18, 2006 9:15 pm
cool, cheers for the reply!
so for quaternions, if cos(θ) is (object's y-axis) dot (polygon normal), then cos(θ/2) would be (using double angle formulae):
cos(θ) = 2(cos(θ/2)^2) - 1
therefore cos(θ/2) = sqrt((cos(θ) + 1)/2)
therefore cos(θ/2) = sqrt((yaxis dot normal + 1)/2)
and id find sin(θ/2) with sin(θ/2) = 1 - cos(θ/2) right?
never used quaternions before, first time implementing them! :O
Last edited by Rajveer on Fri Aug 18, 2006 9:37 pm; edited 1 time in total
#98979 - kevinc - Fri Aug 18, 2006 9:30 pm
Yes :)
But notice that sin(z) = sqrt(1 - cos(z) ^ 2), not sin(z) = 1 - cos(z).
Simplifying a bit, you'll get:
cos(θ/2) = sqrt((yaxis dot normal + 1)/2)
sin(θ/2) = sqrt(1 - (yaxis dot normal + 1)/2), I think.
_________________
http://akzeac.blogspot.com
#98980 - Rajveer - Fri Aug 18, 2006 9:49 pm
cool, cheers for all your help :)
ill try implementing it a bit today and tomorrow and post back my results, thanks again for all your help :)