2012-12-19 5 views
6

Così stavo cercando di capire come calcolare la tonalità media di un numero di oggetti i cui colori sono rappresentati da valori HSL. Per fortuna, mi sono imbattuto in this Stack Overflow post e ho iniziato a lavorare implementando l'algoritmo fornito nella risposta principale (sto lavorando in C++).Valori circolari medi (in particolare Hues nello schema di colori HSL)

Sfortunatamente, la mia implementazione non sembra funzionare. Eccolo, per intero; nota che sebbene io scriva "Hue" sto usando angoli, in gradi, come per l'implementazione iniziale (passando da 0-360 angoli a 0-256 tonalità, una volta che so che il mio codice funziona, non dovrebbe essere difficile).

#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; 
} 

Invece della risposta attesa di 3 (dal 355 dovrebbe essere equivalente a -5 in questo schema), ottengo 86,9951.

Qualcuno può indicare cosa sto facendo male? Questo sembra molto semplice.

risposta

7

atan2 riprende i suoi argomenti in ordine inverso. Lo so, fastidioso! Quindi prova:

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

La risposta che dà ora è 3.00488.

+0

Oh dio, è imbarazzante. Avrei dovuto vederlo. Grazie! – GarrickW

+4

Un modo per ricordarsi di questo fatto è ricordare che quello che stai cercando di fare è ottenere 'atan (Y/X)', eccetto che vogliamo che funzioni ancora come 'X -> 0'. Questo tipo di assomiglia a 'atan2 (Y, X)'. –

+0

Per semplificare la vita del programmatore, notare che alcune lingue sono nell'ordine inverso, ad esempio in Excel atan2 (x; y) –

2

Prova atan2(Y, X). atan2(a,b) è simile a atan(a/b) e serve l'arcotangente del seno medio rispetto al coseno medio.

Problemi correlati