Largest-Triangle-Three Bucket Downsampling Graphs in C# (For an Array of Floats) http://i.imgur.com/UwhvV45.png

May 3, 2015 ยท View on GitHub

public float[] Downsample(float[] array, int Length) { int insert = 0; float[] window = new float[Length]; float[] window_x = new float[Length]; int bucket_size_less_start_and_end = Length - 2;

float bucket_size = (float)(array.Length - 2) / bucket_size_less_start_and_end; 
int a = 0;
int next_a = 0;
int max_area_point_x = 0;
float max_area_point_y = 0f;
window[insert] = array[a]; // Always add the first point
window_x[insert] = 0;
insert++;
for (int i = 0; i < bucket_size_less_start_and_end; i++)
{
    // Calculate point average for next bucket (containing c)
    float avg_x = 0;
    float avg_y = 0;
    int start = (int)(Math.Floor((i + 1) * bucket_size) + 1);
    int end = (int)(Math.Floor((i + 2) * bucket_size) + 1);
    if (end >= array.Length)
    {
        end = array.Length;
    }
    int span = end - start;
    for (; start < end; start++)
    {
        avg_x += start;
        avg_y += array[start];
    }
    avg_x /= span;
    avg_y /= span;

    // Get the range for this bucket
    int bucket_start = (int)(Math.Floor((i + 0) * bucket_size) + 1);
    int bucket_end = (int)(Math.Floor((i + 1) * bucket_size) + 1);

    // Point a
    float a_x = a;
    float a_y = array[a];
    float max_area = -1;
    for (; bucket_start < bucket_end; bucket_start++)
    {
        // Calculate triangle area over three buckets
        float area = Math.Abs((a_x - avg_x) * (array[bucket_start] - a_y) - (a_x - (float)bucket_start) * (avg_y - a_y)) * 0.5f;
        if (area > max_area)
        {
            max_area = area;
            max_area_point_x = bucket_start;
            max_area_point_y = array[bucket_start];
            next_a = bucket_start; // Next a is this b
        }
    }
    // Pick this point from the Bucket
    window[insert] = max_area_point_y;
    window_x[insert] = max_area_point_x;
    insert++;

    // Current a becomes the next_a (chosen b)
    a = next_a;
}

window[insert] = array[array.Length - 1]; // Always add last
window_x[insert] = array.Length;

return window;

}