2012-12-19 14 views
6

Tak więc próbowałem ustalić, jak obliczyć średni odcień obiektów, których kolory są reprezentowane przez wartości HSL. Na szczęście natknąłem się na this Stack Overflow post i ustawiłem pracę na implementację algorytmu podanego w górnej odpowiedzi (pracuję w C++).Uśrednianie wartości okrągłych (w szczególności odcieni w schemacie kolorów HSL)

Niestety, moja implementacja nie działa. Oto w całości; zauważ, że chociaż piszę "Odcień", używam kątów, w stopniach, zgodnie z początkową implementacją (przełączanie z 0-360 kątów na 0-256 odcieni, gdy wiem, że mój kod działa, nie powinno być trudne).

#include <iostream>  
#include <vector> 
#include <cmath> 

#define PI (4*atan(1)) 

int main() 
{ 
    /// 
    /// Calculations adapted from this source: 
    /// https://stackoverflow.com/questions/8169654/how-to-calculate-mean-and-standard-deviation-for-hue-values-from-0-to-360 

    std::vector<double> Hues = {355, 5, 5, 5, 5}; 

    //These will be used to store the sum of the angles 
    double X = 0.0; 
    double Y = 0.0; 

    //Loop through all H values 
    for (int hue = 0; hue < Hues.size(); ++hue) 
    { 
     //Add the X and Y values to the sum X and Y 
     X += cos(Hues[hue]/180 * PI); 
     Y += sin(Hues[hue]/180 * PI); 
    } 

    //Now average the X and Y values 
    X /= Hues.size(); 
    Y /= Hues.size(); 

    //Get atan2 of those 
    double AverageColor = atan2(X, Y) * 180/PI; 

    std::cout << "Average: " << AverageColor << "\n"; 
    return 0; 
} 

Zamiast oczekiwana odpowiedź od 3 (od 355 powinna być równa -5 w tym schemacie), otrzymuję 86.9951.

Czy ktoś może wskazać, co robię źle? Wydaje się to bardzo proste.

Odpowiedz

7

atan2 przyjmuje swoje argumenty w odwrotnej kolejności. Wiem, denerwujące! Więc spróbuj:

double AverageColor = atan2(Y, X) * 180/PI; 

Odpowiedź, którą daje teraz to 3,00488.

+0

O bogowie, to zawstydzające. Powinienem to zobaczyć. Dzięki! – GarrickW

+4

Jednym ze sposobów przypomnienia sobie tego faktu jest zapamiętanie, że próbujesz uzyskać 'atan (Y/X)', z tą różnicą, że chcemy aby nadal działał jako 'X -> 0'. Ten rodzaj wygląda jak 'atan2 (Y, X)'. –

+0

Aby uprościć życie programisty, należy pamiętać, że niektóre języki są w odwrotnej kolejności - na przykład w Excelu atan2 (x; y) –

2

Wypróbuj atan2(Y, X). atan2(a,b) jest podobna do atan(a/b) i potrzebujesz arcus tangensa przeciętnego sinusa ponad przeciętną cosinus.