Atan2 and aiming info.

Blitz3D Forums/Blitz3D Beginners Area/Atan2 and aiming info.

Valgar(Posted 2004) [#1]
Hallo.
I have a function that use atan2 for aiming another object...
direction=atan2(endy-starty,endx-startx)
and i have a array that contain a rotated image from 0 (the image face north) and at degree of 10 ends up facing north again(frame 10 = first frame) so the frame facing south is five(firsta frame facing north rotated 180 degrees clockwise).
I can i know what frame to display at the various atan2 variables?
example:
if atan2 is from 0 to 10 display frame 1

Or there's a better method for sorting the frame to display?


semar(Posted 2004) [#2]
if atan2 is from 0 to 10 display frame 1

frame = floor(angle/10.0)


Hope this helps,
Sergio.


Valgar(Posted 2004) [#3]
I think that doesn't work because i get an "array index uot of bounds" because i store the frame anim in an array.
the function that i use to calculate the direction (based on your hints) is this:

a\angolo2=ATan2( a\cy - a\posizioney, a\cx - a\posizionex )
a\distanza=Sqr( (a\posizionex-a\cx)*(a\posizionex-a\cx)+(a\posizioney-a\cy)*(a\posizioney-a\cy) )
	a\posizionex=a\posizionex+(Cos(a\angolo2)/1)*(a\distanza / a\smoothness)
	a\posizioney=a\posizioney+(Sin(a\angolo2)/1)*(a\distanza / a\smoothness)
fotogramma = Floor(a\angolo2/iNumRotations)
DrawImage enemy,a\posizionex,a\posizioney,fotogramma


And the code for storing the anim is this:
Function LoadObject(ObjectName$,Rotations) 
 
  AutoMidHandle True


  imgTemp = LoadImage(ObjectName$)

  If imgTemp = 0
     Text 100,100,"Invalid Image!"    
  Else
     MaskImage imgTemp,0,0,0

     For iLoop=0 To Rotations-1
  ObjectFrames(iLoop)=CopyImage( imgTemp )

      
  RotateImage ObjectFrames(iLoop), iLoop*360/Rotations
     Next
  EndIf
End Function

I use 8 rotations so iNumRotations=8
The array is also 8 dephts....
I'm trying to do this because i have a path-finding function that find the various waypoints and also make a curve approximation (so the object don't follow blindly the waypoints but smoots them...).
And i don't know how to tell object what direction they are facing....
(non riesco a spiegarmi bene in inglese sorry...)


big10p(Posted 2004) [#4]
This seems to work but I don't know if it's the best way to do it:

num_frames% = 8	; Frames are 0 to 7.
seg# = (360.0/Float(num_frames))
image_no% = Floor((((ATan2(y,x) + (seg/2)) + (360.0+90.0)) Mod 360.0) / seg)



Valgar(Posted 2004) [#5]
So i add this line after the drawimage command??
x&y is the x and y pos at to draw right?


Valgar(Posted 2004) [#6]
UAU it workssssss!
It's all day that i crash my head on the wall trying how to tell that %&$$££***#]€ object that he must face the direction!
Thanks a lot you saved my head :-|
A little answer in my movement object function i have in order:1)atan2 2)cos 3)sin 4)abs 5)atan2 6)sqr 7)cos 8)sin 9)float 10)floor 11)atan2 12)mod
ALL in realtime!!!
Do you think it's too cpu expensive??
Think that this function is for one object......and this function is used in a shoot-em-up with about 20 object onscreen.....
(many thanks)


Stevie G(Posted 2004) [#7]
If I understand you right you have 36 frames here - eahc at 10 degree angles rotating clockwise from north.

You could use this function - quite similar to big10p's but without the use of MOD which is a relatively slow command as I understand it.

Function qangle ( dy#,dx#, segs, offset )
	
	;get an angle between -180 and 180 degrees
	a# = ATan2( dy,dx)
	;convert to an angle between 0 and 360 degrees
	If a < 0 Then a = 360 + a
	Return ( Floor( (a + (180.0 / segs) ) / ( 360.0/segs ) ) + offset ) Mod segs
			
End Function



In your case if you call ..

frame = qangle ( deltax , deltay, 36, 9 )

If your original object was facing east then there would be no need for an offset as 0 degrees is east in screen coords.

... doh!!! I'm using mod too ... ignore me I'm a trumpet!!!


Valgar(Posted 2004) [#8]
Hehe
Thanks for the hint.
I think that the whole procedure thakes tooooooo much processor time for being usefule for a shoot-em-up.....
Basically this function is used to trace a sort of spline curve wich i define graphically the knot points.....
The movement function calculate the curve smoothness,and move the object facing in the correct directions (now thanks to the various help)....firstly i load a sprite and calculate during the load time of the program the various frame.
After finished the animation have the number of rotations that i set and move the object along the curve.
It's a sort of follow way point procedure but it also make much more smooth movements thanks to the spline approximation.
I think it's more usable with an rpg or an adventure game....
Or maybe i use this code only for boss :P
(indeed it's slow....but i'm just happy that it works!)


big10p(Posted 2004) [#9]
Hmmm. Bit surprised it's too slow if you're only displaying ~20 objects. I guess you could speed things up a bit by pre-calculating as much stuff as possible. Also, you may get a small speed gain if you make the following changes to the code snippet I gave you:

; The following 3 variables can be made constant if they don't change during the game.
Const num_frames% = 8	; Frames are 0 to 7.
Const seg# = (360.0/Float(num_frames))
Const half_seg# = seg/2.0

image_no% = Floor((((ATan2(y,x) + half_seg) + 450) Mod 360.0) / seg)



Valgar(Posted 2004) [#10]
A simple question:where you have read those sorto of thing?
In books,or just because you have studied them?
Or pheraps you have proceded with logic?
I have spent a day trying to solve the problem without going nowhere...i'm only curious!


Valgar(Posted 2004) [#11]
The strange thing is that now for a slowdown it thakes about 4 object!
I think that i have eliminated something about 40 sin&cos calculation with some lookup-table(and thanks to you i have made constant).
Constant are significantly faster than variable?
Because in my program i use many variable that remains the same value,so if const are fastest i change them.
(the slowdown i think is something related to approximation.....because it start after that i have created the object....but 60 object for a shoot-em-up i think it's the minimum....
Also....i use types for about everything...from object to player...from alien to bullet!
Maybe i can speed up a little more trying to eliminate some types?(i think that i can eliminate the bullet types...i only use constant to define the damage of the bullet without use of types[in other words i use some if then else instead of some types...but i think i end up in speed down hehe]).


big10p(Posted 2004) [#12]

A simple question:where you have read those sorto of thing?
In books,or just because you have studied them?
Or pheraps you have proceded with logic?
I have spent a day trying to solve the problem without going nowhere...i'm only curious!



No, not from books or study. I just worked it out a bit at a time. I'm not good with maths generally - I'm OK if I can follow the logic of what I'm doing, though. :)


Constant are significantly faster than variable?



Technically speaking, constants should be faster than variables but it's unlikely you'd see much of a speed increase unless you're able to replace hundreds of variables with constants, I'd guess. However, using constants like seg# and half_seg# above should get better speed increases simply because they contain calculations that only need to be done once, instead of every time image_no% is calculated.

As for types, they shouldn't be a problem speed-wise unless you abuse them like, say, searching a huge type list several times a frame, or something like that. I don't know how your're using types or what other calculations you're doing so I can't really say. 4 objects causing slowdown does make me wonder, though - do you have a particularly slow PC? :P


Valgar(Posted 2004) [#13]
I simply think thaty there's something wrong but don't know where (mmm...).
For the types...i use types for aliens and for bullets....so types are used to calculate collision.
And i think that with 20 enemy and 20 bullet onscreen there's something like 60 or so collision cheking....because types are local so if i create 20 alien from the same type...i don't think that i'm checking only one collision but 20!(i'm right?)


big10p(Posted 2004) [#14]
Yeah, if you're checking for collisions between all objects against all other objects then things can get slow fairly quickly. There are ways to get round the problem, though.

I've used a method in the past called 'shifted grid' collision checking which basically divides the playing area into a grid. You then only check for collisions between objects that occupy the same grid cell. To catch collisions between objects on a grid boundary, you also have to 'shift' the grid up, down, left and right, re-checking for collisions each time. Sounds a bit complicated but it worked very well for me. ;)

Have a look at some game dev websites - there are probably several other solutions, too.


Valgar(Posted 2004) [#15]
And if i add another command to calculate the distance and if the distance is inferior at about 10 unit i check for collision...but i think that add other command for calculating the distance is a bad thing....


big10p(Posted 2004) [#16]
'Shifted grid' is very fast. I'll post a demo tomorrow. ;)


big10p(Posted 2004) [#17]
OK, here's the demo. Tried to post in code archives but that's not working, for some reason.

[edit] Code now updated and moved to archives, here:
http://www.blitzbasic.com/codearcs/codearcs.php?code=1065#comments


Stevie G(Posted 2004) [#18]
Now that's pretty fast mate - thanks for sharing!! Would be easy to adapt for a 2d in 3d collision system too..


big10p(Posted 2004) [#19]
np :)

I have just about managed to shoehorn it into the code archives, after much faffing about.


Valgar(Posted 2004) [#20]
Excuse for the delay,i was out of house for about 1 week!
Very thanks for the method,i now study it to see if i can adapt it for my shoot-em up!
Actually i think i use a method very slower.....i use this method because it's the only mode to make my code working!
Basically for every bullet i check collisions.....and for every enemy bullet i check for collision...and for every alien i check collision...if i don't make this way i receive an error "object doesn't exist" or similar...it's because i think that the collisions check start even if no object are onscreen.....i use function for my game.
The fisrt function draw the background and the player......after that if i hit some button on the keyboard i create object to interact with,but this function is enabled only if i hit buttons....the other function are ALWAYS played...and i think it's the error!
Those function make the various object fly around the screen,and that's because they are always active...if not i don't see any object around!
I think that my game logic is terrible....but it's the only way i can see anything moving :P
If i have the time i post the whole code (commented...but in italian -_-' )so everyone see the orrible logic that i use ^^
Thanks.


big10p(Posted 2004) [#21]
Hope the code proves of some use to you. Actually, some of the information I gave in the code above is incorrect so make sure you use the version I put in the archives, here:
http://www.blitzbasic.com/codearcs/codearcs.php?code=1065#comments

There's also a version using a large, scrolling playfield there, too. I'll replace the above code with a link, too.


Valgar(Posted 2004) [#22]
This code is too difficult for me (i have serious problem at understand code made by others....argh),but i re-read it the next year to see if i'm improved :)
I have made a simple program test to see the slowdown of modern pc when used for calculating collision (the standard blitz pixel-perfect collision[images overlap may be faster]).
My amd athlon xp 2100+ 512 ddr400 ram with a radeon 9700pro 128 mb have slowdown with over 900 70 * 50 sprite (ALL in arrays with 10 frame for sprite...)all sprite have a bunch of "sin - cos atan ecc ecc" (i think it's something abput 10 of those calculation for object...)that make them move on a path finding system with function that for every object caslculate the direction that they must face....and EVERY object have a random number (from 0 to 200....and the triggher is the number 2...)of shooting a bullet (sprite of 4*4 pixels...) each with a bunch of "sin-cos-eccecc" that make them center the player.
All graphics is the equivalent of 135 megabytes of ram of data.
All bitmap are uncompressed tga.
I think that this speed is ebough for a shoot-em up.....
And all with collision detections against all....


big10p(Posted 2004) [#23]
Well, if you do decide to investigate the shifted grid method, have a look at this article:
http://www.gamespp.com/algorithms/collisionDetectionHow.html

The code is in C but the text explains things pretty clearly. Ignore the maths stuff that demonstrates how much faster it is than 'normal' collision checking. ;)