How do I make an object move around a point?

BlitzMax Forums/BlitzMax Programming/How do I make an object move around a point?

WERDNA(Posted 2010) [#1]
I'd like to make an object rotate around a point, without using
Rotateimage. The object image itself doesn't have to rotate, just
it's position. Also I'd like to be able to resize the circumference of it's circular movement
so I can shrink or expand the movement circle.

I'm assuming I need Cos and Sin for this(which I'm still not very good
at using ;),
but any code examples you could give me would be great.

Thanks folks!


matibee(Posted 2010) [#2]
When rotating around a point other than the origin (0,0), it's simply a matter of rotating around the origin then adding the translation. See if this helps..




CGV(Posted 2010) [#3]
Well here's some code I use to plot points on a circle.

It's a lot simpler than matibee's code so it might be easier for you to understand how to adapt it to your needs.

The step value in the for loop controls how many dots are drawn.

The SeHandle line just centers the dots on the X,Y coordinates.

Hope it helps.

SuperStrict
Graphics 640, 480, 0

Global CenterX:Int = 200
Global CenterY:Int = 200
Global X:Float = 0
Global Y:Float = 0
Global Radius:Int = 100


While Not KeyHit(KEY_ESCAPE)
	
	SetHandle(2, 2)

	For Local i:Int = 0 To 360 Step 4
	
		X=Cos(i)*Radius
		Y=Sin(i)*Radius
		
		DrawOval(CenterX+X, CenterY+Y, 4, 4)
		
		Flip
	Next
		
Wend



WERDNA(Posted 2010) [#4]
I'll give both examples a shot.

Basically I'm going for the most efficient option I can find, that won't
reduce FPS in the slightest.

Thanks, I'll let you know how they work out.


CGV(Posted 2010) [#5]
I don't think there will be any difference in speed between the two examples since it's the Sin and Cos functions that eat up all the FPS.

In my case I used this code to pre-calculate the x,y coordinates and stored them in an array for use in my game.

Depending on how variable your radii are going to be pre-calculating the coordinates may not be an option for you, but if your going to have several fixed radii then pre-calculating is the way to go.

You might even want to alter your design to make that possible.

Last edited 2010


WERDNA(Posted 2010) [#6]
Depending on how variable your radii are going to be pre-calculating the coordinates may not be an option for you, but if your going to have several fixed radii then pre-calculating is the way to go.

You might even want to alter your design to make that possible.

That's a rather nifty idea. Although how much FPS does Sin and Cos really eat up?
enough to matter?


CGV(Posted 2010) [#7]
I never tested it but when I saw that it took 2 seconds for the points of the circle to be plotted I figured the old 8-bit approach might be called for.

And since my game used just one fixed radius it was a no brainer.

If you want to get a sense of how slow it is, change the 4 in the step value to 1, that will plot every point in the circumference of the circle.

On my 2.6GHz dual-core it takes about 6.5 seconds!


Hummelpups(Posted 2010) [#8]
if you just use natural numbers for cos and sin u can
save their result in an array before mainloop

Last edited 2010


Hummelpups(Posted 2010) [#9]
whoops.

Last edited 2010


Jasu(Posted 2010) [#10]
I wouldn't use precalculated lookup tables unless I was using Sin and Cos like thousands of times per tick. And I wouldn't use them at all for important game logic tasks, like in calculating object positions. On the other hand for displaying graphics they do fine as human eye is not that accurate.

Sin and Cos are floating point operations, which take their time, but they aren't slowest of the lot, we're still talking about nanoseconds. ACos and ASin are a lot slower. :)

I would suggest Werdna you to get very familiar with Sin and Cos. I'd say they are essential for 2D graphics as they are fundamental pieces of geometry (along with Tan). You could use this as a starting point: http://www.blitzbasic.com/Community/posts.php?topic=25485
It's Blitz3D, but theory applies.

CGV's code isn't very good in showing Sin/Cos speed. Drawoval is slow as hell in itself, not to mention the flip inside the for loop.


_JIM(Posted 2010) [#11]
@CGV You are using Flip (1) inside the loop so at most you are probably plotting 60 points per second. That's 1.5 seconds to plot your circle in steps of 4 degrees.

I really wouldn't bother trying to improve the speed of sin and cos unless we're talking about particle systems with lots of particles or some kind of per-pixel operation. Or software transformations (software renderer).

Try to focus more on getting the game finished :)

Also, there's not loads of modifications if you want to switch to a lookup table. Instead of Sin(x) and Cos(x) you will have to use PSin[x] and PCos[x] assuming PSin and PCos are your precalculated arrays. A global search and replace and your code is converted.


WERDNA(Posted 2010) [#12]
I really wouldn't bother trying to improve the speed of sin and cos unless we're talking about particle systems with lots of particles or some kind of per-pixel operation. Or software transformations (software renderer).

Sounds good to me. I think I'll stick with Sin and Cos for now, and just put some time
into getting really comfortable using them. Then I'll move on to other options 'only' if
I need to.

Thanks everyone!


CGV(Posted 2010) [#13]
Sheesh! I never noticed Flip was inside the loop. Sorry about that WERDNA.


WERDNA(Posted 2010) [#14]
np, CGV, lol. Don't worry about it :)


Jesse(Posted 2010) [#15]
here is an object type that allow movement per pixel instead of per degree. this is so an object can move at the same speed no matter what the radius of the object is:
SuperStrict
Type Torbit
	Field center:Float
	Field radius:Float
	Field speed:Float
	Field angle:Float
	Field vx:Float
	Field vy:Float
	
	Const RATE:Float = Pi/180.0
	
	Function Create:Torbit(Angle:Float, radius:Float,speed:Float)
		Local o:Torbit = New Torbit
		O.angle:Float = Angle
		o.angle = Angle
		o.speed = speed
		o.radius = radius
		Return o
	End Function

	Method update()
		angle = (angle+ (1.0/(RATE * radius)*speed)) Mod 360.0
		vx = Cos(Angle) * radius
		vy = Sin(Angle) * radius
	End Method
	

End Type


Graphics 800,600

Local orbit:torbit = Torbit.Create(0,250,1.0)

Repeat
	
	orbit.update()
	Plot 400+orbit.vx,300+orbit.vy ',2,2
	Flip
Until KeyDown(key_escape)



WERDNA(Posted 2010) [#16]
Thanks Jesse!

I'll finally have a bit of free time tomorrow to experiment with some of this. Haven't been
able to code for days now, and I'm feeling blitz deprived ;(