private ImageUtility.float3 ComputeMode( ImageUtility.float3[] _Values )
{
int COUNT = _Values.Length;
// The idea is simply to discretize the set of values and count the ones that are the most represented
float Start = _Values[0].y;
float End = _Values[_Values.Length-1].y;
float IntervalLength = 0.0f, Normalizer = 0.0f;
if ( Math.Abs( End - Start ) > 1e-6f )
{
IntervalLength = (End - Start) / COUNT;
Normalizer = 1.0f / IntervalLength;
}
// Fill bins
int[] Bins = new int[COUNT];
ImageUtility.float3[] BinsSum = new ImageUtility.float3[COUNT];
for ( int i=0; i < _Values.Length; i++ )
{
int BinIndex = Math.Min( COUNT-1, (int) Math.Floor( (_Values[i].y - Start) * Normalizer ) );
Bins[BinIndex]++;
BinsSum[BinIndex] += _Values[i];
}
// Find the one that contains most values (yep, that's the mode!)
int MaxValuesCount = 0;
int MaxValuesBinIndex = -1;
for ( int BinIndex=0; BinIndex < COUNT; BinIndex++ )
if ( Bins[BinIndex] > MaxValuesCount )
{ // More filled up bin discovered!
MaxValuesCount = Bins[BinIndex];
MaxValuesBinIndex = BinIndex;
}
ImageUtility.float3 ModeXYZ = (1.0f / MaxValuesCount) * BinsSum[MaxValuesBinIndex];
return ModeXYZ;
}