Angle between two XY positions

BlitzMax Forums/BlitzMax Beginners Area/Angle between two XY positions

Will(Posted 2005) [#1]
I am having trouble getting the angle between two points. I have written this function (which has seemed to work for me in other languages, maybe not, i'm not sure now)

Function AngleBetween:Float(x1, y1, x2, y2)
       ax = x2-x1; ay = y2-y1
       ang# = 0
       If ax <> 0 Then
              ang = ATan((y1-y2) / (x1-x2))
       Else
              If ay > 0 Then
                     ang = 90
              Else
                     ang = 270
              End If
       End If
       If ax < 0 And ay < 0 Then
              ang = ang + 180
       End If
       If ax < 0 And ay >= 0 Then
              ang = ang + 180
       End If
       Return ang
End Function


So this function, basically, doesn't work, and I have no idea why. I know that its not working, because when I test it like this:

SetLineWidth(5)
SetColor(0,0,0)
ang# = anglebetween(512, 384, MouseX(), MouseY())
DrawLine(512, 384, 512 + 10000*Cos(ang), 384 + 10000*Sin(ang))


What I should see is a line, from the center of my screen (which is 1024x768) draw through the mouse, that follows it as I move my mouse around the screen. However what happens is strange, and hard to describe, i would recommend testing it yourself. It is as if some angles work, and others are snap-to fit on 45 degree increments. Please help me figure out how to do this, as I'm working on a school project, and its currently inhibited by this weird issue.


Yan(Posted 2005) [#2]
Use ATan2(y, x)...

Graphics 800, 600, 0

SetLineWidth 5

Repeat
	Cls
	ang# = ATan2(300 - MouseY(), 400 - MouseX())
	
	DrawLine 400, 300, 400 - (Cos(ang) * 100), 300 - (Sin(ang) * 100)
	
	DrawText ang, 0, 0
	
	FlushMem
	Flip
Until KeyHit(KEY_ESCAPE)

End



Will(Posted 2005) [#3]
Nice, thanks. Why does that work, btw, and why doesn't Atan() regular work for this purpose? I think I am forgetting my trig.


Will(Posted 2005) [#4]
Nice, thanks. Why does that work, btw, and why doesn't Atan() regular work for this purpose? I think I am forgetting my trig.


Najdorf(Posted 2005) [#5]
because atan() gives you only an angle between -90 and 90, (it considers the line as poining always to the right), while atan2 considers the line as pointing to the left if x2<x1.

So if x2-x1>0 ang=atan((y2-y1)/(x2-x1))
if x2-x1<0 ang=atan((y2-y1)/(x2-x1))+180

(i think...)


Yan(Posted 2005) [#6]
Sorry, I've only just noticed this.

Why does that work, btw, and why doesn't Atan() regular work for this purpose?
I haven't got a clue TBH. :o/

I've always just used ATan2(). :o)


FlameDuck(Posted 2005) [#7]
Why does that work, btw, and why doesn't Atan() regular work for this purpose?
It does. ATan(y/x) should give the same results as ATan2(y,x). But since BlitzMAX doesn't do function overloading... :o>

The "snapping" you're experiencing is because x1 , y1, x2, y2 and by extension ax and yx are integers, when they should be floats! This means that when you divide them inside the ATan call the result is in integer division and a high degree of accuracy loss occurs!

To "fix" it you can either:
a) Make sure your delta values ax and ay are floats, and make sure you use them for the division.
b) Make sure x1,x2,y1 and y2 are all floats and then use the code you have now.


Will(Posted 2005) [#8]
thanks very much, that explains alot.