Forums > MaxMSP

keeping numbers in range

October 10, 2009 | 7:46 pm

Hello list.

I tried to find a solution to this small problem. After doing arithmetic operations on numbers within a chosen range, the result often fall out of range. I’m trying to keep the result in the permitted range by "folding" it. I guess this must be a very fundamental problem which experienced programmers got a very efficent solution for? Or I hope it is, since my solution seems very convoluted.

Sorry if the problem is poorly described, I guess looking at the patch will offer a better description.

I would gratefully welcome any other solution

Cheers
LL

– Pasted Max Patch, click to expand. –

October 10, 2009 | 10:22 pm

i cannot look at max5 patches, but there is [abs],
[clip], [split] for a start.

for things like keeping a range after performing [cos] and
things like that, there is no other option than to find the
desired scaling by trying it out; if the range is 0. – 7.
but should bw 0. – 1. [/ 7.] should help.


October 10, 2009 | 10:57 pm

Appreciate your input Roman, so I made a quick max4 port of what I’m doing. I’m not looking for an external or an object to do this, but a mathematical operation simpler than this method with an conditional statement. If such exists;)

#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P comment 308 148 100 196617 choose delay;
#P comment 183 39 100 196617 start cycle;
#P comment 98 359 100 196617 delayed index;
#P number 44 322 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 217 227 27 196617 t b i;
#P newex 205 272 27 196617 – 1;
#P number 310 170 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 219 201 100 196617 expr abs($f1 – $f2);
#P number 98 345 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 99 298 133 196617 if $i1 > 0 then $f1 else $f2;
#P newex 195 115 53 196617 t i i i i;
#P newex 98 238 76 196617 expr $i1 – $f2;
#N counter;
#X flags 0 0;
#P newobj 98 162 66 196617 counter;
#P newex 99 138 52 196617 metro 50;
#P toggle 106 115 15 0;
#P newex 194 94 43 196617 int 512;
#P newex 168 60 27 196617 t i b;
#P toggle 168 37 15 0;
#P comment 19 347 100 196617 current index;
#P connect 12 0 7 1;
#P connect 12 0 11 1;
#P connect 6 0 15 0;
#P connect 6 0 7 0;
#P connect 6 0 11 0;
#P connect 13 0 9 1;
#P connect 8 1 13 0;
#P connect 11 0 14 0;
#P connect 14 0 13 0;
#P connect 14 1 13 1;
#P connect 9 0 10 0;
#P connect 7 0 9 0;
#P connect 8 0 6 4;
#P connect 3 0 8 0;
#P connect 5 0 6 0;
#P connect 4 0 5 0;
#P connect 1 0 2 0;
#P connect 2 0 4 0;
#P connect 2 1 3 0;
#P window clipboard copycount 19;



Ch
October 11, 2009 | 3:53 pm

hi,

I think you just need a kind of modulo :

– Pasted Max Patch, click to expand. –

Ch


October 11, 2009 | 5:50 pm

well, beside the question how much sense it makes, you
can for sure make that shorter.

instead of the if

[if $i1 > 0 then $f1 else $f2]

you can use an expr

[expr $i1*($i1>0) + $i2*($i1< =0)]

so that you can combine it with the other expr into

[expr $i1*(($i1 - $f2)>0) + $i3*(($i1 - $f2)< =0)]

for the rest i dont really see what it is about – you can
probably replace other 6 objects by a single [- ].

the use of modulo also seems a right idea, itonly has that little proboem that 512 will be 0 again.y you can use some
+1 shifting procedure to fix that, or use the following formula
which is taking from [110.loopi]:

[expr ((($i1%$i2) + ($i2)*(($i1%$i2)==0))*($i1>=0)) + ((((($i1%$i2)+$i2) + (-$i2)*((($i1%$i2)+$i2)==0))*($i1<0)))]

where input 1 would be your counter output (which no longer would have to be limited to 1-512!) and the secondinput is
your 512.

the same for full floating point modulo looks slightly more anal:

[expr ((($f1-int($f1/$f2)*$f2) + ($f2)*(($f1-int($f1/$f2)*$f2)==0))*($f1>=0)) + ((((($f1-int($f1/$f2)*$f2)+$f2) + (-$f2)*((($f1-int($f1/$f2)*$f2)+$f2)==0))*($f1<0)))]

-110


October 12, 2009 | 4:34 am

one kind of hack way to do this would be to get the number result, then use that to [uzi] that many numbers into a [counter] that has the range you want, and counting mode is up/down. So if you want values from 0-100, and a value like 135 should fold back to 65, you’d have

uzi 135
counter 2 0 100 (2 is the counting mode: up/down)
fire!

it’ll ping-pong within the range, sort of an auto-modulus, but mirrored instead of restarting. Probably you’ll need to add or subtract 1 at some point to deal with "off-by-one" problems, but hey. And if you want floats just scale them at the end, as counter only plays with ints.


Viewing 6 posts - 1 through 6 (of 6 total)