Λειτουργία για τη δημιουργία τροχούς χρώμα

ψήφοι
63

Αυτό είναι κάτι που έχω ψευδο-λυθούν πολλές φορές και ποτέ δεν έχουν βρεθεί αρκετά μια λύση για.

Το πρόβλημα είναι να καταλήξουμε σε έναν τρόπο για να παράγουν Nτα χρώματα, που είναι τόσο διακριτές όσο το δυνατόν οποίο Nείναι μια παράμετρος.

Δημοσιεύθηκε 01/08/2008 στις 19:42
πηγή χρήστη
Σε άλλες γλώσσες...                            


8 απαντήσεις

ψήφοι
1

Έχω διαβάσει κάπου το ανθρώπινο μάτι δεν μπορεί να διακρίνει ανάμεσα λιγότερο από 4 τιμές χώρια. Έτσι, αυτό είναι κάτι που πρέπει να θυμάστε. Ο παρακάτω αλγόριθμος δεν αντισταθμιστεί αυτό.

Δεν είμαι σίγουρος ότι αυτό είναι ακριβώς ό, τι θέλετε, αλλά αυτό είναι ένας τρόπος για να δημιουργήσει τυχαία μη-επαναλαμβανόμενες τιμές χρώματος:

(Προσοχή, σε αντίθεση ψευδο-κώδικα μπροστά)

//colors entered as 0-255 [R, G, B]
colors = []; //holds final colors to be used
rand = new Random();

//assumes n is less than 16,777,216
randomGen(int n){
   while (len(colors) < n){
      //generate a random number between 0,255 for each color
      newRed = rand.next(256);
      newGreen = rand.next(256);
      newBlue = rand.next(256);
      temp = [newRed, newGreen, newBlue];
      //only adds new colors to the array
      if temp not in colors {
         colors.append(temp);
      }
   }
}

Ένας τρόπος που θα μπορούσε να βελτιστοποιήσει αυτό για καλύτερη ορατότητα θα ήταν να συγκρίνουμε την απόσταση ανάμεσα σε κάθε νέο χρώμα και όλα τα χρώματα του πίνακα:

for item in color{
   itemSq = (item[0]^2 + item[1]^2 + item[2]^2])^(.5);
   tempSq = (temp[0]^2 + temp[1]^2 + temp[2]^2])^(.5);
   dist = itemSq - tempSq;
   dist = abs(dist);
}
//NUMBER can be your chosen distance apart.
if dist < NUMBER and temp not in colors {
   colors.append(temp);
}

Αλλά αυτή η προσέγγιση θα επιβραδύνει σημαντικά τον αλγόριθμο σας.

Ένας άλλος τρόπος θα ήταν να καταργήσει το τυχαίο και συστηματικά να περάσουν από κάθε 4 αξίες και να προσθέσετε ένα χρώμα σε μια σειρά στο παραπάνω παράδειγμα.

Απαντήθηκε 01/08/2008 στις 20:36
πηγή χρήστη

ψήφοι
3

Δεν είναι επίσης ένας παράγοντας ποια σειρά θα ρυθμίσετε τα χρώματα;

Όπως και αν χρησιμοποιείτε Dillie-Os ιδέα που πρέπει να αναμίξετε τα χρώματα όσο το δυνατόν περισσότερο. 0 64 128 256 είναι από το ένα στο επόμενο. αλλά 0 256 64 128 σε έναν τροχό θα ήταν πιο «χώρια»

Βγάζει νόημα;

Απαντήθηκε 02/08/2008 στις 19:16
πηγή χρήστη

ψήφοι
23

Η πρώτη σκέψη μου σε αυτό είναι «πώς μπορούν να παράγουν Ν διανύσματα σε ένα χώρο που μεγιστοποιούν απόσταση ο ένας από τον άλλο.»

Μπορείτε να δείτε ότι το RGB (ή οποιαδήποτε άλλη κλίμακα που χρησιμοποιείτε που αποτελεί τη βάση στο χρωματικό χώρο) είναι ακριβώς φορείς. Ρίξτε μια ματιά σε τυχαίο σημείο Picking . Μόλις έχετε μια σειρά από φορείς που μεγιστοποιούνται πέρα, μπορείτε να τα αποθηκεύσετε σε έναν πίνακα κατακερματισμού ή κάτι για αργότερα, και μόλις εκτελέσει τυχαίες περιστροφές για να πάρετε όλα τα χρώματα που επιθυμείτε ότι είναι μέγιστη απόσταση μεταξύ τους!

Προβληματισμός σχετικά με αυτό το πρόβλημα περισσότερο, θα ήταν καλύτερα να χαρτογραφήσει τα χρώματα με γραμμικό τρόπο, ενδεχομένως, (0,0,0) → (255.255.255) λεξικογραφικά, και στη συνέχεια να διανέμουν ομοιόμορφα.

Πραγματικά δεν ξέρω πόσο καλά θα λειτουργήσει, αλλά θα πρέπει από το, ας πούμε:

n = 10

ξέρουμε ότι έχουμε 16777216 χρώματα (256 ^ 3).

Μπορούμε να χρησιμοποιήσουμε πόρπες Αλγόριθμος 515 για να βρείτε το λεξικογραφικά ευρετήριο χρώμα. \ Frac {\ Binom {256 ^ 3} {3}} {n} * i. Θα πρέπει πιθανώς να επεξεργαστείτε τον αλγόριθμο για να αποφευχθεί η υπερχείλιση και πιθανώς να προσθέσετε κάποιες μικρές βελτιώσεις ταχύτητας.

Απαντήθηκε 02/08/2008 στις 20:03
πηγή χρήστη

ψήφοι
17

Θα ήταν καλύτερο να βρείτε τα χρώματα μέγιστη μακρινή σε «αντιληπτικά ενιαία» χρωματικό, π.χ. CIELAB (χρησιμοποιώντας Ευκλείδεια απόσταση μεταξύ των L *, a *, b * συντονίζει η απόσταση σας μετρικό) και στη συνέχεια μετατροπή στο χρωματικό χώρο της επιλογής σας. Αντιληπτική ομοιομορφία επιτυγχάνεται με μικροαλλαγές το φάσμα χρωμάτων για την προσέγγιση των μη γραμμικότητες στο ανθρώπινο οπτικό σύστημα.

Απαντήθηκε 12/09/2008 στις 20:00
πηγή χρήστη

ψήφοι
7

Μερικές σχετικών πόρων:

ColorBrewer - Σετ των χρωμάτων σχεδιαστεί για να είναι το μέγιστο διακρίνονται για χρήση σε χάρτες.

Ξεφεύγοντας από RGBland: Επιλογή Χρώματα Στατιστική γραφικών - Μια τεχνική έκθεση που περιγράφει μια σειρά από αλγόριθμους για τη δημιουργία καλό (δηλαδή το μέγιστο διακρίνονται) σύνολα χρωμάτων στο χρώμα HCl χώρο.

Απαντήθηκε 18/09/2008 στις 17:01
πηγή χρήστη

ψήφοι
6

Εδώ είναι μερικά κωδικό για να διαθέσουν τα χρώματα RGB ομοιόμορφα γύρω από ένα HSL ρόδα χρώματος συγκεκριμένων φωτεινότητα.

class cColorPicker
{
public:
    void Pick( vector<DWORD>&v_picked_cols, int count, int bright = 50 );
private:
    DWORD HSL2RGB( int h, int s, int v );
    unsigned char ToRGB1(float rm1, float rm2, float rh);
};
/**

  Evenly allocate RGB colors around HSL color wheel

  @param[out] v_picked_cols  a vector of colors in RGB format
  @param[in]  count   number of colors required
  @param[in]  bright  0 is all black, 100 is all white, defaults to 50

  based on Fig 3 of http://epub.wu-wien.ac.at/dyn/virlib/wp/eng/mediate/epub-wu-01_c87.pdf?ID=epub-wu-01_c87

*/

void cColorPicker::Pick( vector<DWORD>&v_picked_cols, int count, int bright )
{
    v_picked_cols.clear();
    for( int k_hue = 0; k_hue < 360; k_hue += 360/count )
        v_picked_cols.push_back( HSL2RGB( k_hue, 100, bright ) );
}
/**

  Convert HSL to RGB

  based on http://www.codeguru.com/code/legacy/gdi/colorapp_src.zip

*/

DWORD cColorPicker::HSL2RGB( int h, int s, int l )
{
    DWORD ret = 0;
    unsigned char r,g,b;

    float saturation = s / 100.0f;
    float luminance = l / 100.f;
    float hue = (float)h;

    if (saturation == 0.0) 
    {
      r = g = b = unsigned char(luminance * 255.0);
    }
    else
    {
      float rm1, rm2;

      if (luminance <= 0.5f) rm2 = luminance + luminance * saturation;  
      else                     rm2 = luminance + saturation - luminance * saturation;
      rm1 = 2.0f * luminance - rm2;   
      r   = ToRGB1(rm1, rm2, hue + 120.0f);   
      g = ToRGB1(rm1, rm2, hue);
      b  = ToRGB1(rm1, rm2, hue - 120.0f);
    }

    ret = ((DWORD)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)));

    return ret;
}


unsigned char cColorPicker::ToRGB1(float rm1, float rm2, float rh)
{
  if      (rh > 360.0f) rh -= 360.0f;
  else if (rh <   0.0f) rh += 360.0f;

  if      (rh <  60.0f) rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;   
  else if (rh < 180.0f) rm1 = rm2;
  else if (rh < 240.0f) rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;      

  return static_cast<unsigned char>(rm1 * 255);
}

int _tmain(int argc, _TCHAR* argv[])
{
    vector<DWORD> myCols;
    cColorPicker colpick;
    colpick.Pick( myCols, 20 );
    for( int k = 0; k < (int)myCols.size(); k++ )
        printf("%d: %d %d %d\n", k+1,
        ( myCols[k] & 0xFF0000 ) >>16,
        ( myCols[k] & 0xFF00 ) >>8,
        ( myCols[k] & 0xFF ) );

    return 0;
}
Απαντήθηκε 27/09/2008 στις 17:39
πηγή χρήστη

ψήφοι
1

Ξέρω ότι αυτό μια παλιά θέση, αλλά το βρήκα, ενώ ψάχνει για μια λύση PHP με το θέμα και, τέλος, ήρθε με μια απλή λύση:

function random_color($i = null, $n = 10, $sat = .5, $br = .7) {
    $i = is_null($i) ? mt_rand(0,$n) : $i;
    $rgb = hsv2rgb(array($i*(360/$n), $sat, $br));
    for ($i=0 ; $i<=2 ; $i++) 
        $rgb[$i] = dechex(ceil($rgb[$i]));
    return implode('', $rgb);
}

function hsv2rgb($c) { 
    list($h,$s,$v)=$c; 
    if ($s==0) 
        return array($v,$v,$v); 
    else { 
        $h=($h%=360)/60; 
        $i=floor($h); 
        $f=$h-$i; 
        $q[0]=$q[1]=$v*(1-$s); 
        $q[2]=$v*(1-$s*(1-$f)); 
        $q[3]=$q[4]=$v; 
        $q[5]=$v*(1-$s*$f); 
        return(array($q[($i+4)%6]*255,$q[($i+2)%6]*255,$q[$i%6]*255)); //[1] 
    } 
}

Έτσι απλά καλέστε την λειτουργία random_color (), όπου $ i προσδιορίζει το χρώμα, $ n τον αριθμό των πιθανών χρωμάτων, $ κάθισε τον κορεσμό και $ br την φωτεινότητα.

Απαντήθηκε 19/10/2011 στις 02:58
πηγή χρήστη

ψήφοι
0

Για την επίτευξη του «πιο διακριτό» θα πρέπει να χρησιμοποιήσετε μια αντιληπτική χρωματικό χώρο, όπως Lab (ή οποιοδήποτε άλλο αντιληπτικά γραμμικό χρωματικό χώρο) και όχι RGB. Επίσης, μπορούμε να quantize αυτό το χώρο για να μειώσει το μέγεθος του χώρου.

Δημιουργήστε το πλήρες 3D χώρο με όλες τις πιθανές κβαντισμένη εγγραφές και να εκτελέσετε το K-means αλγόριθμο με k=N. Τα προκύπτοντα κέντρα / «σημαίνει» θα πρέπει να είναι περίπου πιο distinguishabl ένας από τον άλλο.

Απαντήθηκε 07/02/2014 στις 18:43
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more