tags:

views:

177

answers:

3

Hello, I have a value range from 0 to 255.

There is a method that returns an array with a min and max values within this range, i.e: 13, 15, 20, 27, 50 ... 240 where 13 is the min and 240 is the max

I need to scale these values so that 13 becomes 0 and 240 becomes 255 and scale all the other values between them proportionally.

Is there any C# method that does that?

thanks!

+12  A: 

Use this formula

y=mx+c

where m = (255-0)/(244-13) and c= -13*m

So you have to just transform the array as such

 public double[] GetScaling(double[] arr, double min, double max)
{
    double m = (max-min)/(arr.Max()-arr.Min());
    double c = min-arr.Min()*m;
    var newarr=new double[arr.Length];
    for(int i=0; i< newarr.Length; i++)
       newarr[i]=m*arr[i]+c;
    return newarr;
}
Ngu Soon Hui
Instead of specifiying 244 and 13, you should really retrieve the actual min and max of the specified array.
ccomet
@ccomet, that should be trivial
Ngu Soon Hui
@ccomet, update to make the code secgment more general.
Ngu Soon Hui
thanks!! worked perfectly! But double m = (255-0)/(244-13); returns an int, it should be converted to double...
John S
+2  A: 

If you're using .NET 3.5, then LINQ can easily obtain the minimum and maximum values from any IEnumerable<T> object, which an array is.

int[] values = new int[] { 0, 1, 2, ... 255 };

int minValue = values.Min();
int maxValue = values.Max();

If you're looking for something to scale the whole array...

public static int[] Scale(int[] values, int scaledMin, int scaledMax)
{
    int minValue = values.Min();
    int maxValue = values.Max();

    float scale = (float)(scaledMax - scaledMin) / (float)(maxValue - minValue);
    float offset = minValue * scale - scaledMin;

    int[] output = new int[values.Length];

    for (int i = 0; i < values.Length; i++)
    {
        output[i] = (int)Math.Round(values[i] * scale - offset, 0);
    }

    return output;
}
Adam Robinson
He knows the max and min. He wants to transform the values in the middle so that they become from 0 to 255.
Daniel Daranas
@Daniel: it's good practice to construct reusable methods whether he knows the values or not.
fearofawhackplanet
@fearofawhackplanet: My comment was only appliable for a first version of the question, which just said how you can find the maximum and the minimum, and nothing about scaling. Interestingly, this version has only existed in my dreams: http://stackoverflow.com/posts/2675221/revisions
Daniel Daranas
Edits within 5 minutes of posting are not recorded. But worry not! I saw the "dream" version you saw.
ccomet
@ccornet Thanks, I didn't know this!
Daniel Daranas
+1  A: 

To find min and max

var min = Array.Min();
var max = Array.Max();

To scale value in a range (minScale, int maxScale)

private double Scale(int value , int min, int max, int minScale, int maxScale)
{
  double scaled = minScale + (double)(value - min)/(max-min) * (maxSale - minScale);
  return scaled;
}
digEmAll