Question

Comment feriez-vous pour créer une gamme de couleurs RVB uniformément répartie sur la gamme de couleurs spectrale? Pour ressembler à un véritable arc-en-ciel.

Était-ce utile?

La solution

Utilisez plutôt HSL: réglez la luminosité et la saturation et faites varier la teinte de 0 à 360, puis convertissez-le en RVB.

HSL décrit les couleurs telles qu'elles sont perçues par les gens. RVB les décrit comme ils sont utilisés par les machines. Vous ne pouvez donc rien faire qui soit visuellement agréable en utilisant directement RVB.

Autres conseils

Vous pouvez utiliser l’ espace colorimétrique HSV et parcourir la dimension Hue.

L’approche la plus simple consiste à effectuer une interpolation linéaire (en RVB) entre chaque paire consécutive de cette séquence:

  • # ff0000 rouge
  • # ffff00 jaune
  • # 00ff00 vert
  • # 00ffff cyan
  • # 0000ff bleu
  • # ff00ff magenta
  • # ff0000 retour au rouge

Cela devrait vous donner à peu près le même résultat que de parcourir les valeurs de teinte dans HSV ou HSL, mais vous permet de travailler directement en RVB. Notez que seul un composant change pour chaque interpolation, ce qui simplifie les choses. Voici une implémentation Python:

def rainbow():
  r, g, b = 255, 0, 0
  for g in range(256):
    yield r, g, b
  for r in range(255, -1, -1):
    yield r, g, b
  for b in range(256):
    yield r, g, b
  for g in range(255, -1, -1):
    yield r, g, b
  for r in range(256):
    yield r, g, b
  for b in range(255, -1, -1):
    yield r, g, b
  • Rouge (couleur Web) (Hex: # FF0000) (RVB: 255, 0, 0)
  • Orange (roue de couleur orange) (Hex: # FF7F00) (RVB: 255, 127, 0)
  • Jaune (couleur Web) (Hex: # FFFF00) (RVB: 255, 255, 0)
  • Vert (X11) (Vert électrique) (HTML / CSS “Chaux”) (Roue de couleurs verte) (Hex: # 00FF00) (RGB: 0, 255, 0)
  • Bleu (couleur Web) (Hex: # 0000FF) (RGB: 0, 0, 255)
  • Indigo (Indigo électrique) (Hex: # 6600FF) (RGB: 102, 0, 255)
  • Violet (Violet électrique) (Hex: # 8B00FF) (RGB: 139, 0, 255)

Entre chaque couleur, effectuer une interpolation linéaire.

Cette classe le fera avec PHP, transmettra au constructeur le nombre de couleurs que vous souhaitez dans votre arc-en-ciel et la propriété $ sequence contiendra un tableau de codes hexadécimaux rrggbb.

class color
{
    public $sequence = array();

    /**
     * constructor fills $sequence with a list of colours as long as the $count param
     */
    public function __construct($count, $s = .5, $l = .5)
    {
        for($h = 0; $h <= .85; $h += .85/$count)    //.85 is pretty much in the middle of the violet spectrum
        {
            $this->sequence[] = color::hexHSLtoRGB($h, $s, $l);
        }
    }

    /**
     * from https://stackoverflow.com/questions/3597417/php-hsv-to-rgb-formula-comprehension#3642787
     */
    public static function HSLtoRGB($h, $s, $l)
    {

        $r = $l;
        $g = $l;
        $b = $l;
        $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : (l + $s - l * $s);
        if ($v > 0){
              $m;
              $sv;
              $sextant;
              $fract;
              $vsf;
              $mid1;
              $mid2;

              $m = $l + $l - $v;
              $sv = ($v - $m ) / $v;
              $h *= 6.0;
              $sextant = floor($h);
              $fract = $h - $sextant;
              $vsf = $v * $sv * $fract;
              $mid1 = $m + $vsf;
              $mid2 = $v - $vsf;

              switch ($sextant)
              {
                    case 0:
                          $r = $v;
                          $g = $mid1;
                          $b = $m;
                          break;
                    case 1:
                          $r = $mid2;
                          $g = $v;
                          $b = $m;
                          break;
                    case 2:
                          $r = $m;
                          $g = $v;
                          $b = $mid1;
                          break;
                    case 3:
                          $r = $m;
                          $g = $mid2;
                          $b = $v;
                          break;
                    case 4:
                          $r = $mid1;
                          $g = $m;
                          $b = $v;
                          break;
                    case 5:
                          $r = $v;
                          $g = $m;
                          $b = $mid2;
                          break;
              }
        }
        return array('r' => floor($r * 255.0),
                    'g' => floor($g * 255.0), 
                    'b' => floor($b * 255.0)
                    );
    }

    //return a hex code from hsv values
    public static function hexHSLtoRGB($h, $s, $l)
    {
        $rgb = self::HSLtoRGB($h, $s, $l);
        $hex = base_convert($rgb['r'], 10, 16) . base_convert($rgb['g'], 10, 16) . base_convert($rgb['b'], 10, 16);
        return $hex;
    }
}

Pour tester, par exemple:

$c = new color(100);
foreach($c->sequence as $col)
  print "<div style='background-color:#$col'>$col</div>\n";

Je ne réclame de crédit que pour l’emballage de cette classe, la fonction originale a été trouvée dans cet article: Compréhension des formules PHP HSV à RGB

Les autres solutions nécessitent des quantités de code et des branches conditionnelles assez importantes, ce qui les rend inadaptées aux GPU. Je suis récemment arrivé à la formule simple comme par magie suivante dans GLSL. C'est essentiellement la même chose dans OpenCL:

vec3 HueToRGB(float hue) {
  vec3 h = vec3(hue, hue + 1.0/3.0, hue + 2.0/3.0);
  return clamp(6.0 * abs(h - floor(h) - 0.5) - 1.0, 0.0, 1.0);
}

Cela vous donnera une couleur arc-en-ciel qui correspond à la valeur de teinte donnée en RVB linéaire. Pour l’utiliser dans une image, convertissez-le en sRGB, puis multipliez-le par 255.

Voici une version C ++:

float clamp(float value, float low, float high) {
  return value < low ? low : (value > high ? high : value);
}
void HueToRGB(float hue, float *rgb) {
  rgb[0] = hue;
  rgb[1] = hue + 1.f/3.f;
  rgb[2] = hue + 2.f/3.f;
  for (unsigned i = 0; i < 3; ++i) {
    rgb[i] = clamp(6.0f * fabsf(rgb[i] - floorf(rgb[i]) - 0.5f) - 1.f, 0.f, 1.f);
  }
}

La clé ici est de réaliser que le graphe de chacune des coordonnées R, V, B en fonction de la valeur de teinte est une valeur pincée d'une fonction de triangle périodique, et que l'on peut l'obtenir comme valeur absolue d'une dent de scie. fonction, x - sol (x) .

Je sais que la question est plutôt ancienne, mais voici ma solution simple et facile à comprendre, qui devrait être facile à utiliser dans la plupart des langages de programmation. Remplacez les étapes et whichStep par vos propres valeurs.

int steps = 1280;
int stepChange = 1280 / steps;
int change = stepChange * whichStep;
int r=0, g=0, b=0;

if (change < 256)
{
    r = 255;
    g += change;
}
else if (change < 512)
{
    r = 511 - change;
    g = 255;
}
else if (change < 768)
{
    g = 255;
    b = change-512;
}
else if (change < 1024)
{
    g = 1023 - change;
    b = 255;
}
else
{
    r = change - 1024;
    b = 255;
}

Je peux dessiner un arc-en-ciel par programmation avec JavaScript et HTML5.

Exemple RainbowVis-JS avec arc en ciel

Je crée un dégradé à partir de rgb (255,0,0) - > rgb (255,255,0) - > rgb (0,255,0) - > rgb (0,255,255) - > rgb (0,0255) - > rgb (255,0,255).

Je calcule les valeurs de couleur hexadécimales le long du dégradé à l'aide de ma bibliothèque RainbowVis-JS (qui enchaîne simplement les dégradés). Je dessine l'arc forme avec HTML5 Canvas, en passant en revue les couleurs.

<!DOCTYPE html>
<html>
  <head>
    <script src="rainbowvis.js"></script>
  </head>
  <body>
    <script type="text/javascript">
      window.onload = function(){

        var RAINBOW_WIDTH = 60;
        var RAINBOW_RADIUS = 130;

        // Library class
        var rainbow = new Rainbow();
        rainbow.setNumberRange(1, RAINBOW_WIDTH);
        rainbow.setSpectrum(
          'FF0000', 'FFFF00', '00FF00',
          '00FFFF', '0000FF', 'FF00FF'
        );

        // Canvas
        var canvas = document.getElementById('MyCanvas');
        var context = canvas.getContext('2d');

        context.lineWidth = 1;
        for (var i = 1; i <= RAINBOW_WIDTH; i++) {
          context.beginPath();
          context.arc(canvas.width/2, canvas.width/2, RAINBOW_RADIUS - i+1, 
            Math.PI, 0, false);
          context.strokeStyle = '#' + rainbow.colourAt(i); // Library function
          context.stroke();
        }
      };
    </script>
    <canvas id="MyCanvas" width="300" height="300">
      <p>Rainbow arc example. Your browser doesn't support canvas.</p>
    </canvas>
  </body>
</html>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top