I have a float that adds up and subtracts based on user input. It turns the hand of a clock around 0-360 degrees. When we go around a second time the degree resets to 0. I want to figure out is how do I count how many times I’ve gone a full revolution around.
In the end Im trying to get a number that goes not from 0-360 but 0-Infinity.
int divider (\ instead of /) is the ‘quotient’… although sadly this doesn’t exist in C#, but does in VB.Net of all places… (it’s inherited from DartmouthBASIC)
Of course you can always just get the quotient by truncating the result from float division (/): Math.Truncate(x / y)
The quotient of course being how many times you’d “gone around” when getting the modulo.
Hmm, I think Modulo is probably the wrong word for my case. I’m simply counting how many times I go a full 0-360 around. @Ryiah how would you keep that second number? In a loop or if statement? Dividing by 360 will obviously represent one revolution but how do I count up from there with multiple revolutions without the number resetting each time?
I don’t really have any code but I’ll write out an example here;
If I turn the minute hand around multiple times it would be easy to divide by 360:
turn 0-360 = 1 revolution;
turn 360-720 = 2 revolutions;
turn 720-1080 = 3 revolution: etc;
The problem is the rotation input is clamped between 0-360; As I make a full rotation past 360 my rotation input goes back to 0 and increments from there.
You instead keep the full raw value, and then you calculate the clamp and the revolutions from that as you need them.
public float angle;
public float AngleClamped
{
get { return _angle % 360f; }
}
public float Revolutions
{
get { return (float)System.Math.Truncate(angle / 360f); }
}
Noting that modulo probably isn’t the best here, because it doesn’t work in negative values the way you probably expect it to. And rather you should use a ‘wrap’ function. This is mine:
public static float Wrap(float value, float max, float min)
{
max -= min;
if (max == 0)
return min;
return value - max * (float)Math.Floor((value - min) / max);
}
Im not clamping the rotation. I get the value from transform.rotation.eulerAngle.z; All I have to work with is the 0-360 rotation input. Therein lies my problem…
Oh man, I didn’t think this would be so difficult. Thank you for your help so far.
I’m confused by this. The transform is the only input I have. I thought there maybe a simple for loop that could count the revolutions of the transform.rotation.z. I can’t seem to find anywhere else online that has tackled the problem. It seems relatively straight forward and I was hoping the amount of code talent here would have an easy solution. Maybe I’m looking at it wrong…
To get the 0-360 variable I use transform.rotation.eulerAngles.z to get the Quaternion rather than Euler which gets wonky by rotating only to 270 radians.
Instead of updating transform.localRotation.eulerAngles.z in that script you want to update the angle in the example code posted by @lordofduct earlier.
You’ll have TWO variables. One that is already defined in the transform.rotation (the view) and one stored in your script (the model).
The ‘view’ isn’t used to store actual useful data. It instead is just there to give a display to what your underlying data is.
Your ‘model’ is what is the actual state information.
Your code updates your model (your custom variable like the source I showed earlier)… and then copies that to the view (the transform).
You never read state information from the view, because it’s considered volatile… it’s not actual data, it’s just the way we want the data to look. We always consult the model to know the actual state of the data.
This is useful for incase the ‘view’ ever changes on you. What if you decide to start making the ‘x’ axis the face, or maybe its some off weird axis like <1,1,1>. What if you change to 2d, or if you decide to display it digitally (like a digital clock). The view is independent of your data.
Furthermore, shape your data in a way that makes sense for your data, and transform it as necessary. Is this a clock? How about storing it as a ‘TimeSpan’ instead, and then copy out the seconds/minutes/etc as rotational values… degrees = seconds * 6, degrees = hours * 30… that sort of thing.
Ok, the only input I have is as a euler which increments 0-270+90 to rotate around. I converted it to a Quaternion to get 0-360 rotation variable to simplify. This would be so easy if I didn’t have to go through a clamped rotation variable. I just don’t know how I can get linear float from the code I posted above…