[Closed] Rounding off to nearest increment?
Im looking to write a function to round off the the nearest increment(i dont know the acual correct name).
For example i have a step size of 30.
eg -60, -30, 0, 30, 60 etc…
Id like to write a function to roundof to the nearest value.
so for example if I have a value of 14, it would be rounded to 0. If i have 15 it would be rounded to 30.
fn RoundToIncrement valfloat valInrement = ()
Is there any easy existing way to do this ?
Thanks
Hi,
There’s no built-in method in MAXScript doing that.
I think you have to write the algorithm like this :
- find in which interval the value is (14 is between 0 and 30)
- find nearest value doing a substraction between the two values of the interval (0 and 30) and the value (14): abs(0-14) < abs(30-14).
Try this
fn RoundToIncrement valfloat valIncrement =
(
result = 0.0
ratio = valfloat/valIncrement as float
modDir = (mod ratio 1)
if modDir < 0 do modDir = 0 - modDir
if valfloat > 0.0 and modDir < 0.5 then result = ((ratio-modDir) as integer*valIncrement) as integer
else if valfloat > 0.0 do result = ((ratio-modDir+1) as integer*valIncrement) as integer
if valfloat < 0.0 do result = ((ratio-modDir) as integer*valIncrement) as integer
result
)
Edit: fixed typos (i think! :))
This is rather easy to express in a functional way without any IFs:
fn RoundToIncrement valfloat valIncrement = (
(floor (1.0*valfloat/valIncrement + 0.5) * valIncrement) as integer )
- You take the original value, multiplied by 1.0 it is ensured to be a float.
- Then you divide it by the increment. The result is a floating point number where the part before the decimal point tells you how often the valIncrement was contained in the valFloat.
- Having this number, you just have to round it up or down if the portion after the decimal point is above or below .5. To do this, you add 0.5 and call floor() on it. So 2.6 turns into 3, -4.3 turns into -4 and so on.
- Now all you have to do is multiply the rounded number you got in step 3 by the ValIncrement and you will be at the closest increment. Just make the value an integer (if you want) and voila!
Why should I prefer the one over the other you might ask?
Well, not only is the functional approach shorter and easier to avoid typos (the other code had at least 4 errors in it, including using val instead of valFloat and valIncrement instead of the valInrement parameter mistyped by the original poster), it is also 2.3 times faster to execute!
Over 1 million iterations, my machine shows 6.250 seconds vs. 2.688 seconds for the functional appoach.
Shut up, you smarta**, you might say.
OK, I will
ha ha, oh yeah nice spot on the typos! Just knocked it up in 5 mins locally here and cut’n’pasted into the post, looks like I missed a couple of variables