I think you're complicating the problem by introducing Math.abs which, I was
once told by a mathematically inclined colleague, is an arithmetic atrocity
(I've taken note of that since then and the nice thing is that almost
always, signs just work they way out without any extra help).
The formula is simpler than you probably think. You just need to find the
size of the range, that is the difference between the max and the min
values. Forget about signs, just take the max value and substract the min.
Easy as that.
If you have, say 10 and -4, the range size will be 14:
10 - (-4)
--
10 + 4 = 14
The signs don't matter, as long as you always substract the smaller value
from the bigger one.
Now, once you have this value, you just have to find how far the ranged
value is from min and then scale it.
Let's say your value is 3. I picked 3 because it's easy to see it's in the
middle and that the result should be 0.5.
So:
rangeSize is 14 (max - min).
min is -4
rangedValue is 3:
How far is rangedValue from min?
rangedValue - min
That is:
3 - (-4)
or
3 + 4 = 7
Now, the last step, scaling it:
(rangedValue - min) / rangeSize
Replacing the values:
(3 - (-4) ) / 14
(3 + 4) / 14
7 / 14 = 0.5
And there you have it.
So a function to normalize a ranged value could look like this:
function rangedToNormal(ranged:Number,min:Number,max:Number):Number {
var rangeSize:Number = max - min;
return (ranged - min) / rangeSize;
}
Going the other way is simple too:
function normalToRanged(normal:Number,min:Number,max:Number):Number {
var rangeSize:Number = max - min;
return min + normal * rangeSize;
}
(Though above you might want to validate that the normal value is actually
normalized before converting it to the passed range)
Also, I'm not sure how you are calculating the min and max values of your
list, but if there aren't other specific requirements, you could just use
Math.max and Math.min. They accept a variable number of arguments, not just
two, so Function::apply comes handy here:
var min:Number = Math.min.apply(null,list);
This will give you the min value of the list with just one line, no loops,
etc.
So, to wrap it up, you could write your function in just a few lines, like
this:
function normalizeNumbers(list:Array):Array {
var min:Number = Math.min.apply(null,list);
var max:Number = Math.max.apply(null,list);
var len:int = list.length;
var result:Array = [];
for(var i:int = 0; i len; i++) {
result[i] = rangedToNormal(list[i],min,max);
}
return result;
}
Cheers
Juan Pablo Califano
2010/11/29 Karim Beyrouti ka...@kurst.co.uk
Hello FlashCoder...
maybe it's because it's late but it's getting a little confusing, and
google is not being friendly right now.
seems to works fine with positive numbers, however - i am trying to
normalise a range of positive and negative numbers... ( code simplified not
to find min and max values ).
I am currently am coming up a little short... hope this code does not give
anyone a headache; if you fancy a stab, or if you can point me in the right
direction
... otherwise ... will post results when i get there...
Code:
public function test() {
trace('')
trace( testNormalizeNumbers( [ 1 , 1.5 , 2 ] , 2 , 1 ).toString()
);
trace('')
trace( testNormalizeNumbers( [ 1 , 1.5 , 5 , 1 , 6.4 , 6, 3, -2.6,
-1 , 3.5 ] , 6.4 , -2.6 ).toString() );
trace('')
trace( testNormalizeNumbers( [ -1 , -1.5 , -5 , -1 , -6.4 , -6, -3,
-2.6, -1 , -3.5 ] ,-1 , -6.4 ).toString() );
}
public function testNormalizeNumbers( a : Array , max : Number , min :
Number ) : Array {
var result : Array = new Array();
var nMax: Number= ( min 0 ) ? max - min : max +
Math.abs( min );
for ( var c : int = 0 ; c a.length ; c++ ){
var pRangedValue: Number = ( min 0 ) ?
a[c] - min : a[c] + Math.abs( min );
var normalizedValue : Number = pRangedValue / nMax;
result.push( normalizedValue );
}
return result;
}
Thanks
Karim ___
Flashcoders mailing list
Flashcoders@chattyfig.figleaf.com
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
___
Flashcoders mailing list
Flashcoders@chattyfig.figleaf.com
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders