Posted: 1st Dec 2002 18:36
Just posting a small function for anyone having trouble calculating there angles.

+ Code Snippet
function GetAngle(cx#,cy#,x#,y#)
  rem --- cx#, cy#  =  center point
  rem --- x#, y#    =  point around center

  a# = y# - cy#
  b# = x# - cx#

  if b# = 0.0
    if a# = 0.0 then inc ang#,90.0 else inc ang#,270.0
  endif
endfunction ang#



...and a little demo.


+ Code Snippet
sync on : sync rate 60

repeat
  cls
  line 310,240,330,240 : line 320,0,320,250

  mx = mousex() : my = mousey()
  line 320,240,mx,my

  ang# = GetAngle(320,240,mx,my)

  rem --- draw arc
  for a = 0 to int(ang#)
    x = 30 * sin(a) + 320
    y = 240 - (30 * cos(a))
    dot x,y
  next a#

  text mx,my+8,str$(ang#)
  sync
until spacekey()

end



Hope it's useful
Posted: 1st Dec 2002 18:40
Nuts! the function did'nt copy properly, lets try again....

function GetAngle(cx#,cy#,x#,y#)
rem --- cx#, cy# = center point
rem --- x#, y# = point around center

a# = (y# - cy#)
b# = (x# - cx#)

if b# = 0.0
if a# <= 0.0 then ang# = 0.0 else ang# = 180.0
else
ang# = atan(a#/b#)
if b# >= 0.0 then inc ang#,90.0 else inc ang#,270.0
endif

endfunction ang#
Posted: 1st Dec 2002 21:06
do they apply for 3d if i use z instead of y in the code?
Posted: 1st Dec 2002 21:19
Though I have'nt tried it in 3D, it should be OK to pass Z co-ords into the cy# and y# parameters.
Posted: 1st Dec 2002 21:49
good example
Posted: 1st Dec 2002 21:53
thanx man, i'm gonna be using this for another game!
Posted: 1st Dec 2002 22:28
Thankyou haggisman.

Hexgear I've just experimented in 3D, and discoverd the result appears to be inverted, so you may want to change a line in the function from:

a# = (y# - cy#)

to

a# = (cy# - y#)

...but that's up to you
Posted: 8th Dec 2002 20:27
Much much much thx! I couldnt understand, why the point object doesnt works, but now i can elminate it! thx again!
Posted: 2nd Feb 2003 4:20
sorry to dig this up but i found a totally new way of calculating line of sight (like the dark basic command), i got so frustrated using the DB command because my enemy a.i. kept on looking through trees and buildings like they wherent there, no matter the value of width and accuracy for the line of sight command.

However i used your formula above and made a kinda 3D version, it works way better than the DB line of sight command, the only catch is that it's afected by object personal collision boxes (and not static boxes). it requires one single object so i'll upload it in RGT and place a link here to the code snippet!

this could be very helpful in making your enemy A.I.
Posted: 2nd Feb 2003 4:55
It's somewhat embarrasing to admit this, but after re-reading this subject (and re-reading the manual) I have only just found another way it could be done.

Replace the old function with this new one in the above example, it will show the same result:

+ Code Snippet
function GetAngle(cx#,cy#,x#,y#)
  rem --- cx#, cy# = center point
  rem --- x#, y# = point around center

  ang# = 180.0 - atanfull(x#-cx#,y#-cy#)
endfunction ang#


This is much smaller, and I think fractionly faster. I had totaly overlooked the AtanFull() command.

(hangs head in shame and sits facing the corner)

However, for 3D use you still may have to swap y# and cy# around.
Posted: 2nd Feb 2003 5:19
wow, ain't your fault, never even knew that command existed! but hey, it's still good to know how to calculate the angle btw two points using raw code instead of an unknown function
Posted: 2nd Feb 2003 6:10
What's equaly embarrasing is it took me nearly two months to realise this

True, it is handy to know the raw code version, especaily if you're translating a program from one language to another and you didn't know how the AtanFull() worked. The old function will easily convert to C++ for example.

Thanks for pointing that out, makes me feel a bit better
Posted: 10th Feb 2003 12:09
You don't have to swap y# and cy#...
Just use the ABS() command to always make it positive.
e.g.
ang# = 180.0 - atanfull(x#-cx#,ABS(y#-cy#))

If you get the number -165 ABS will convert it to (+)165.
Posted: 11th Feb 2003 0:59
True, that will also work, but after thinking about it, perhaps it would be better to offer a choice of calculation modes, either using 2D screen co-ords or using 3D plain co-ords. Handy if your program requires both.

+ Code Snippet
function GetAngle(cx#, cy#, x#, y#, use3D)
  rem --- cx#, cy# = center point
  rem --- x#, y# = point around center
  rem --- use3D = (0 for 2D screen co-ords, 1 for 3D plain co-ords)

  if use3D = 1 then ny# = cy# - y# else ny# = y# - cy#
  ang# = 180.0 - atanfull(x# - cx#, ny#)
endfunction ang#


...that should finalise things, I hope