Angles-Rotation-Limits?
BlitzMax Forums/BlitzMax Beginners Area/Angles-Rotation-Limits?
| ||
I have a spinning ball that spins about it's center. I use this code to prevent the angle increasing forever but it has a snag. Whenever I want to change the direction the ball spins it locks up or skips. If RotAngle >=360 then RotAngle = 0 If RotAngle <=0 then RotAngle = 360 Now the problem is that if any of the balls have an angle of 0 it's changed to 360 and if any have an ang;e of 360 it's changed to 0. This is where the problem is. The two lines of code fight eachother when checking the Max angle. I thought I would try and leave the angle for one direction and not check it but it just goes in to negative and increases. What would be the best method to make sure that the positive and negative values never go beyond 360/-360 and bringing them to 0 safely without conflicts? Thanks :) |
| ||
This is a bit better.If RotAngle >359 then RotAngle :- 360 If RotAngle <0 then RotAngle :+ 360 [edit] Besides, just follow your code:- RotAngle = 380 If RotAngle >=360 then RotAngle = 0 RotAngle = 0 If RotAngle <=0 then RotAngle = 360 RotAngle = 360 If RotAngle >=360 then RotAngle = 0 RotAngle = 0 If RotAngle <=0 then RotAngle = 360 RotAngle = 360 If RotAngle >=360 then RotAngle = 0 RotAngle = 0 If RotAngle <=0 then RotAngle = 360 RotAngle = 360 Can you see the problem yet? ;) Remember there is no such thing as the 360th degree, only 0-359. |
| ||
Hahah, Thanks Enay. It works perfect. Now make me a cheese sandwich :) |
| ||
I usually solve these ping-pong behaviours of values by adjusting the value with an operator and keeping it in range with min max values. Example: Global angle:Int = 0 Global maxAngle:Int = 360 Global minAngle:Int = -360 Global operator:Int = 1 Repeat angle:+operator If angle > maxAngle or angle < minAngle Then 'Here's the trick! You invert the operator 'when you reach min or max! operator = - operator End If Forever The advantage of adjusting the angle value with the operator is that you only get one place in the code where you actually modify the angle value. The 'direction' of the adjustment is handled by the operator and the min/max values. Encapsulation and separation of concerns! EDIT: Ooops! I just realized that you did not want a ping-ponging value... You wanted to wrap it! Sorry. //PetBom |
| ||
Remember there is no such thing as the 360th degree, only 0-359. What an odd statement. Most of the Max commands return angle ranges of -180<=angle<180. And 360 degrees works exactly the same as 0 degrees in almost all situations. Also if you cap angles at 359 you'll never be able to have an angle of 359.5 |
| ||
would this be of any use?RotAngle :+ Alter 'alter by a minus or a posative number While RotAngle<0.0 ; RotAngle:+720.0 ; Wend 'Ensure its a posative number RotAngle = RotAngle Mod 360.0 'Limit it from 0.0 to 360.0 It will let the number wrap around. |
| ||
And here's a much better way(IMO) to roll over angles.While RotAngle>=180 RotAngle:-360 Wend While RotAngle<-180 RotAngle:+360 Wend |
| ||
Ehhhh...You guys mean If/EndIf and not While/Wend, right? |
| ||
Ehhhh...You guys mean If/EndIf and not While/Wend, right? No.To explain a little more. The While/Wend method allows for large angle jumps of 360 degrees or more. Using If/Endif in this situation would still leave your angle out of the desired range. To make the code a little more usable I would make a function from it so it is reusable in many situations. Function WrapAngle:Float(ang:Float) While ang>=180 ang:-360 Wend While ang<-180 ang:+360 Wend Return ang End FunctionAnd then you could use it thus. RotAngle=WrapAngle(RotAngle) |
| ||
I think my way is most efficient, ;) Although admittedly there will be a problem is you move more than 360 degrees in either direction in any one frame. > What an odd statement. Most of the Max commands return angle > ranges of -180<=angle<180. I'm talking in the literal sense, because there are only 360 degrees in a circle. To go lower or higher is simply wrapping around the other side. Sure you can have -70 and 700, but mathematically speaking they're still variants of 0-359.999999etc. That's what I was saying. :) |
| ||
Value = Value Mod 360 If Value < 0 Value :+360 |
| ||
I was going to say, why hasn't anyone mentioned Mod yet? But Nelvin got to it finally. |
| ||
I was going to say, why hasn't anyone mentioned Mod yet? But Nelvin got to it finally. Is my post invisable! |
| ||
I was going to say, why hasn't anyone mentioned Mod yet? But Nelvin got to it finally. Except unlike Shagwanas version, his doesn't compensate for very large fluctuations in "negative" angles. |
| ||
It does of course, there's just no reason to use any loops at all (introducing an O(n) complexity where O(1) does the job) |
| ||
Wow, did mark fix the mod command? I remember in Blitz3D, MOD being so slow that if..endif and when...wend was preferable. Just did some tests on max and MOD wa 5x faster. |
| ||
Nelvin wins, his way is best :o) |
| ||
You could do: Value = Value Mod (360*Sgn(Value)) |