need a little mathy help.

BlitzMax Forums/BlitzMax Programming/need a little mathy help.

Paul "Taiphoz"(Posted 2011) [#1]
Did a quick google to get an image for you to use, its a gif so you will need to change the code a little, but its got the same orientation as the sprite I am using.

Ok the problem, as you know blitz angles/degree's have zero at the right, and 180 at the left, and the range is -180 to 180, this always gets me all confused when trying to use these values to control the direction of travel and rotation of an image.

In short I want the little sprite to go after the mouse, but I'm going wrong with the math some where and not being brilliant at math cant seem to work out where.



Strict	
Framework BRL.GLMax2D
Import BRL.PNGLoader


SetGraphicsDriver GLMax2DDriver()
Global GFX_Width		:Int 	= 	500
Global GFX_Height		:Int 	= 	500
Graphics GFX_Width , GFX_Height , 0


AutoMidHandle(True)
Global ImageShip:TImage	 = 	LoadImage("ship.png")


Type TShip
	Field x:float
	Field y:float
	Field vx:float
	Field vy:float
	Field fAngle:float
	Field tAngle:float
	Field turnrate:float
	Field speed:float
End type


Global Ship:TShip = New TShip
Ship.x = 100
Ship.y = 100
Ship.fAngle = 0
Ship.tAngle = 0
Ship.turnrate = 0
Ship.speed = 1


repeat
	cls

	turnship()
	moveship()
	
	SetRotation -Ship.fAngle
	DrawImage ImageShip,Ship.x,Ship.y
	SetRotation 0
	
	flip
Until KeyHit(KEY_ESCAPE)



Function turnship()

		Ship.vx:+ Cos(Ship.fAngle)*Ship.speed
		Ship.vy:+ Sin(Ship.fAngle)*Ship.speed
		
		Ship.x:+ Ship.vx 
		Ship.y:+ Ship.vy 
				
		'Set Rotation
		Ship.tAngle = (ATan2(Ship.y-MouseY(),Ship.x-MouseX())+180.0) Mod 360.0		
		Local difference:float = Abs(Ship.tAngle-Ship.fAngle)

		If Ship.tAngle < Ship.fAngle				
			If difference > 180.0 Ship.turnrate=2 Else Ship.turnrate=-2
		ElseIf Ship.tAngle > Ship.fAngle
			If difference > 180.0 Ship.turnrate=-2 Else Ship.turnrate=2
		EndIf
		
		Ship.fAngle = (Ship.fAngle - Ship.turnrate +360) Mod 360	
End function


Function moveship()	
	
	Ship.vx = - Cos(Ship.fAngle) * Ship.speed
	Ship.vy = - Sin(Ship.fAngle) * Ship.speed
	
	Ship.x:- Ship.vx
	Ship.y:+ Ship.vy
	
	DrawText Ship.fAngle , 1 , 1
	DrawText Ship.tAngle , 1 , 30
	
End function




Last edited 2011

Last edited 2011

Last edited 2011

Last edited 2011


Paul "Taiphoz"(Posted 2011) [#2]
Solved it, although I am sure the way I fudged this to get it working is not the best way, so if anyone spots a much easier way please let me know.

Strict	
Framework BRL.GLMax2D
Import BRL.PNGLoader


SetGraphicsDriver GLMax2DDriver()
Global GFX_Width		:Int 	= 	500
Global GFX_Height		:Int 	= 	500
Graphics GFX_Width , GFX_Height , 0


AutoMidHandle(True)
Global ImageShip:TImage	 = 	LoadImage("ship.png")


Type TShip
	Field x:Float
	Field y:Float
	Field vx:Float
	Field vy:Float
	Field fAngle:Float
	Field tAngle:Float
	Field turnrate:Float
	Field speed:Float
End Type


Global Ship:TShip = New TShip
Ship.x = 100
Ship.y = 100
Ship.fAngle = 0
Ship.tAngle = 0
Ship.turnrate = 0
Ship.speed = 1


Repeat
	Cls

	turnship()
	moveship()
	
	SetRotation Ship.fAngle-180
	DrawImage ImageShip,Ship.x,Ship.y
	SetRotation 0
	
	Flip
Until KeyHit(KEY_ESCAPE)



Function turnship()

		Ship.vx:+ Cos(Ship.fAngle)*Ship.speed
		Ship.vy:+ Sin(Ship.fAngle)*Ship.speed
		
		Ship.x:+ Ship.vx 
		Ship.y:+ Ship.vy 
				
		'Set Rotation
		Ship.tAngle = (ATan2(Ship.y-MouseY(),Ship.x-MouseX())+180.0) Mod 360.0		
		Local difference:Float = Abs(Ship.tAngle-Ship.fAngle)

		If Ship.tAngle < Ship.fAngle				
			If difference > 180.0 Ship.turnrate=2 Else Ship.turnrate=-2
		ElseIf Ship.tAngle > Ship.fAngle
			If difference > 180.0 Ship.turnrate=-2 Else Ship.turnrate=2
		EndIf
		
		Ship.fAngle = (Ship.fAngle - Ship.turnrate +360) Mod 360	
End Function


Function moveship()	
	
	Ship.vx = - Cos(Ship.fAngle) * Ship.speed
	Ship.vy = - Sin(Ship.fAngle) * Ship.speed
	
	Ship.x:+ Ship.vx
	Ship.y:+ Ship.vy
	
	DrawText Ship.fAngle , 1 , 1
	DrawText Ship.tAngle , 1 , 30
	
End Function





col(Posted 2011) [#3]
You are calculating the ship movement twice, once in TurnShip which gets overridden by the one in MoveShip. I suppose there is an optimisation to cut out all the if statements if you were bothered by them :-

Function turnship()				
		'Set Rotation
		Ship.tAngle = (ATan2(Ship.y-MouseY(),Ship.x-MouseX())+180.0) Mod 360.0
		Local difference:Float = Abs(Ship.tAngle-Ship.fAngle)
		
		Local sign:Int = ((Ship.tAngle<Ship.fAngle)*-1) Or Ship.tAngle>Ship.fAngle
		sign :* ((difference > 180)*-1) Or 1
		Ship.turnrate = 2 * sign
				
		Ship.fAngle = (Ship.fAngle - Ship.turnrate +360) Mod 360	
End Function


other than that, looks ok enough to me :-)

Last edited 2011


Floyd(Posted 2011) [#4]
Do yourself a favor and simply accept that angles should be in the range -180 to +180, as indicated by ATan2. Don't try to hammer them into some other form.

I wrote a little function to wrap angles to the the same range as ATan2. It is used to keep fAngle and difference working consistently.

Strict	

Global GFX_Width		:Int 	= 	700
Global GFX_Height		:Int 	= 	700
Graphics GFX_Width , GFX_Height , 0

AutoMidHandle (True)
Global ImageShip:TImage	 = 	LoadImage("temp.jpg")

Type TShip
	Field x:Float
	Field y:Float
	Field vx: Float
	Field vy: Float
	Field fAngle: Float
	Field tAngle:Float
	Field turnrate:Float
	Field speed:Float
End Type

Global Ship:TShip = New TShip
Ship.x = 100
Ship.y = 100
Ship.speed = 1

Repeat

	Cls

	turnship()
	moveship()
	
	SetRotation Ship.fAngle
	DrawImage ImageShip,Ship.x,Ship.y
	SetRotation 0
	
	Flip
Until KeyHit(KEY_ESCAPE)


Function turnship()

		Ship.tAngle = ATan2( MouseY() - Ship.y, MouseX() - Ship.x )
		Local difference:Float = WrapAngle( Ship.tAngle - Ship.fAngle )
		Ship.turnrate = 2 * Sgn( difference )
		Ship.fAngle = WrapAngle( Ship.fAngle + Ship.turnrate )
		
End Function

Function moveship()	
	
	Ship.vx = Cos(Ship.fAngle) * Ship.speed
	Ship.vy = Sin(Ship.fAngle) * Ship.speed
	
	Ship.x:+ Ship.vx
	Ship.y:+ Ship.vy

End Function

Function WrapAngle:Float( a:Float )   ' to range ( -180, +180 ] just like ATan2
	a:Mod 360
	If a >  +180 Then Return a - 360
	If a <= -180 Then Return a + 360
	Return a
End Function



Paul "Taiphoz"(Posted 2011) [#5]
This community is simply the best I have seen for development, Iv been on a few others, c++ and PHP but this community beats the all hands down.

Thanks. that helped a lot.

Last edited 2011