Circle movement.
Blitz3D Forums/Blitz3D Programming/Circle movement.
| ||
Hi All, I have a little problem with a program I have created to move a sprite in a circle around a centre point. When the angle reaches 360 degrees I would lile the angle to reset to 0 and start again. Adjusting the speed of the rotation sometimes causes the If condition to be missed due to floating point inacuracy. i,e If S\SA#=360 Or S\SA#=360 Then S\SA#=0 Function below usng types, any Ideas, Function updateships() For s.ship = Each ship Local shipx#, shipz# ;update shipangle# and maintain speed at different distances S\SA#=S\SA#-(S\SP#/S\SD#) If S\SA#=360 Or S\SA#=-360 Then S\SA#=0 ;Update position around radius using the sin/cos functions shipx# = S\SCX# + ( Cos#(S\SA#) * S\SD# ) shipz# = S\SCZ# + ( Sin#(S\SA#) * S\SD# ) ;draw the ship PositionEntity S\SIMAGE,shipx#,S\SY#,shipz# RotateEntity S\SIMAGE,0,(S\SA#-90),0 If S\SID%=0 Then SNAME1=S\SNAME SA1#=S\SA# SX1#=shipx# SZ1#=shipz# SSP1#=S\SP# End If Next End Function |
| ||
Replace If S\SA#=360 Or S\SA#=360 Then S\SA#=0 With If S\SA#>=360 S\SA=S\SA-360 End If Or if you could possibly go more than one rotation in a go ( perhaps if the program is minimized during use and then maximized again ) then you could do this While S\SA>360 S\SA=S\SA-360 Wend I don't really understand why you have an Or in that If statement at all, since both conditions are the same. So if they were supposed to be different, then you may need to adjust the answer, but that's the principle, and it will even deal with situations where you go through more than one turn in a single frame ( eg: when your app is minimized for a while. ) |
| ||
There's basically no need to "normalize" an angle, since Sin() and Cos() functions work without it. But I agree that if this ship exists long enough, the angle starts to lose accuracy so that it becomes visible. The normalizing should be done both ways if object can rotate clockwise too. Function NormalizeAngle#(ang#) If ang >= 360.0 Then return ang Mod 360.0 ElseIf ang < 0.0 Then While ang < 0.0 ang = ang + 360.0 Wend EndIf Return ang End Function |
| ||
I use this function to WRAP a value , should be faster than using MOD.Function WRAP#( value#,lo#,hi#) If value < lo Then value = hi + ( value - lo ) If value >= hi Then value = lo + ( value - hi ) Return value End Function So .. S\SA#=S\SA#-(S\SP#/S\SD#) If S\SA#=360 Or S\SA#=-360 Then S\SA#=0 Would be .. S\SA#= WRAP( S\SA#-(S\SP#/S\SD#) , 0 , 360 ) |