Point to Cursor using Angles - Bug?

Blitz3D Forums/Blitz3D Beginners Area/Point to Cursor using Angles - Bug?

(tu) ENAY(Posted 2012) [#1]
Hi,

I have some code where I have a dial in the middle and I need it to point towards the cursor and also calculate which direction is fastest, clockwise or anti/counter clockwise.

I have it working but as soon as I put the cursor exactly on 0degrees or 180 degrees it goes to the exact opposite angle.

I had this working in C++ but porting it to Blitz seems to have broken somewhere, any see what is wrong?

Here is the code:-


AppTitle "angle test"

Graphics 640,480,0,2

Function GetTurnDir%(x1#, y1#, x2#, y2#, current_angle#)
	Local angle#	= (ATan( (y1 - y2) / (x1 - x2) ) - 90);
	
	Text 0,100,x1
	Text 0,110,y1
	Text 0,120,x2
	Text 0,130,y2
	Text 0,140,current_angle
	
	If (x1 > x2) Then angle = angle + 180
	
	angle = angle - current_angle
	
	While ( angle < 0 )
		angle = angle + 360
	Wend
	
	
	If (angle > 180 )
		Return -1
	Else
		Return 1
	EndIf
End Function

Function GetAngle#(x1#, y1#, x2#, y2#)
	Local angle# = ATan2(y2 - y1, x2 - x1) - 90; ) * 180 / bPi)*RAD2DEG
	
	;If ( x1 > x2 ) Then angle = angle + 180
	;
	While ( angle < 0 )
		angle = angle + 360
	Wend
	;
	Return (angle);
End Function

Global posx1 = MouseX()
Global posy1 = MouseY()

Global posx2 = 320
Global posy2 = 240

Global the_angle#

Global DEG2RAD# = 57.27272727
Global RAD2DEG# = 0.01746031
Global bPi = 3.142

Repeat
	Cls
	
	posx1 = MouseX()
	posy1 = MouseY()
	
	Oval posx1-20,posy1-20,40,40,0
	
	Text 10,10,posx1
	Text 10,20,posy1
	
	
	Text MouseX()-10,MouseY()-40,GetAngle(posx1, posy1, posx2, posy2)
	Color 255,0,255
	Line posx1, posy1, posx2, posy2
	Color 255,255,255
	
	
	the_angle = the_angle + GetTurnDir(posx1, posy1, posx2, posy2, the_angle)
	Line posx2,posy2, posx2 + (Cos((the_angle-90)))*64, posy2 + (Sin((the_angle-90)))*64


	If (the_angle > 360) Then the_angle = the_angle - 360
	If (the_angle < 0) Then the_angle = the_angle + 360
	
	Text 310,180,the_angle
	
	Oval posx2-20,posy2-20,40,40,0
		
	Flip
Until KeyHit(1)


Last edited 2012


Ross C(Posted 2012) [#2]
One of the problems is the angle is being turned in increments of 1.0, so your getting a juddering as the angle the line is at, is a floating point number. The two will never match up.

To solve your current problem though:

Function GetTurnDir%(x1#, y1#, x2#, y2#, current_angle#)
	Local angle#	= (ATan( (y1 - y2) / (x1 - x2) ) - 90);
	
	Text 0,100,x1
	Text 0,110,y1
	Text 0,120,x2
	Text 0,130,y2
	Text 0,140,current_angle
	
	If (x1 > x2) Then angle = angle + 180
	
	angle = angle - current_angle
	
	While ( angle < 0 )
		angle = angle + 360
	Wend
	
	
	If (angle > 180 )
		Return -1
	Else
		Return 1
	EndIf
End Function


This line:
If (x1 > x2) Then angle = angle + 180


Should be:

If (x1 => x2) Then angle = angle + 180


This fixes the problem. But, i'm assuming your wanting the line to travel at a linear speed?


Ross C(Posted 2012) [#3]
Ok man, after some thought:

Function GetTurnDir#(x1#, y1#, x2#, y2#, current_angle#)
	
	Local angle#	= (ATan( (y1 - y2) / (x1 - x2) ) - 90);
	
	Text 0,100,x1
	Text 0,110,y1
	Text 0,120,x2
	Text 0,130,y2
	Text 0,140,current_angle
	
	If (x1 => x2) Then angle = angle + 180
	

	If Abs(angle - current_angle) Mod 360 < 1 Then
		Return 0
	End If

	angle = angle - current_angle

	While ( angle < 0 )
		angle = angle + 360
	Wend

	
	
	If (angle > 180 )
		Return -1
	Else
		Return 1
	EndIf
End Function


I have added:

	If Abs(angle - current_angle) Mod 360 < 1 Then
		Return 0
	End If


It will basically detect if the angle is less than one, don't return a turning value. This will stop it gittering.


(tu) ENAY(Posted 2012) [#4]
Many thanks for the help guys :)

All I wanted basically is the fastest route to where the mouse is. Nothing special. This is basically my "gradually turn to face player" AI code.

As it was, sometimes the AI would do a full spin to align with the player even if the player was about 3 degrees away.