I have a C# method that projects the value of a number from an interval to a target interval.
For example: we have an interval of -1000 and 9000 and a value of 5000; if we want to project this value to an interval of 0..100 we get 60.
Here is the method:
/// <summary> /// Projects a value to an interval /// </summary> /// <param name='val'>The value that needs to be projected</param> /// <param name='min'>The minimum of the interval the value comes from</param> /// <param name='max'>The maximum of the interval the value comes from</param> /// <param name='intervalTop'>The minimum of the interval the value will /// be projected to</param> /// <param name='intervalBottom'>The maximum of the interval the value will /// be projected to</param> /// <returns>Projected value</returns> public decimal ProjectValueToInterval(decimal val, decimal min, decimal max, decimal intervalBottom, decimal intervalTop) { decimal newMin = Math.Min(0, min); decimal valueIntervalSize = Math.Abs(max - newMin); decimal targetIntervalSize = Math.Abs(intervalTop - intervalBottom); decimal projectionUnit = targetIntervalSize / valueIntervalSize; return (val * projectionUnit) + Math.Abs((newMin * projectionUnit)); }
This method needs to be called for thousands of values.
I was wondering if there is a more efficient way to do this in C#? If yes, what changes do you suggest?
Just maths. What you’re ‘projecting’ is a normalisation of ranges A-B and A’-B’ such that:
ratio r = (x-A) / (B-A) = (y-A’) / (B’-A’)
which using your terms is:
(val-min) / (max-min) = (returnValue-intervalBottom) / (intervalTop-intervalBottom)
which solves for returnValue as: