Me peindre un arc-en-ciel

comment feriez-vous pour qu'une gamme de couleurs RVB soit uniformément répartie sur toute la gamme de couleurs spectrales? Pour ressembler à un vrai arc-en-ciel.

23
demandé sur Annan 2009-07-31 13:59:00

8 réponses

utilisez HSL à la place: fixez la luminosité et la saturation et variez la teinte de 0 à 360, puis convertissez en RVB.

HSL décrit les couleurs telles qu'elles sont perçues par les gens. RVB Les décrit tels qu'ils sont utilisés par les machines. Donc, vous ne pouvez pas vraiment faire quelque chose visuellement agréable directement en utilisant RGB.

17
répondu Laurent 2009-07-31 10:02:25

vous pouvez utiliser le HSV espace de couleur et marcher à travers la dimension de teinte.

18
répondu John Kugelman 2017-02-08 14:14:01

l'approche la plus simple consiste à effectuer une interpolation linéaire (en RGB) entre chaque paire consécutive dans cette séquence:

  • #ff0000 rouge
  • #ffff00 jaune
  • #00ff00 Vert
  • #00ffff cyan
  • #0000ff bleu
  • #ff00ff magenta
  • #ff0000 retour vers le rouge

cela devrait vous donner à peu près le même résultat que de balayer les valeurs de teinte dans HSV ou HSL, mais vous permet de travailler directement dans RGB. Notez qu'un seul 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
7
répondu Laurence Gonsalves 2009-07-31 10:37:27
  • Rouge (Couleur web) (Hex: # FF0000) (RGB: 255, 0, 0)
  • Orange (Roue Couleur Orange) (Hex: # FF7F00) (RGB: 255, 127, 0)
  • Yellow (web colour) (Hex: #FFFF00) (RGB: 255, 255, 0)
  • Vert (X11) (Vert électrique) (HTML / CSS "Lime") (roue couleur verte) (Hex: #00FF00) (RGB: 0, 255, 0)
  • Bleu (Couleur web) (Hex: # 0000FF) (RGB: 0, 0, 255)
  • Indigo (Electric Indigo) (Hex: #6600FF) (RGB: 102, 0, 255)
  • Violet (Violet électrique) (Hex: #8B00FF) (RGB: 139, 0, 255)

entre chaque couleur effectuer une interpolation linéaire.

1
répondu Luka Rahne 2009-07-31 10:06:50

cette classe le fera avec PHP, passera au constructeur le nombre de couleurs que vous voulez 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 /q/php-hsv-to-rgb-formula-comprehension-32997/"<div style='background-color:#$col'>$col</div>\n";

je demande seulement le crédit pour emballer ceci dans une classe, la fonction originale a été trouvée dans ce post: PHP HSV to RGB formula understanding

1
répondu james-geldart 2017-05-23 12:09:14

je sais que c'est une question assez ancienne, mais voici ma solution simple et facile à comprendre, qui devrait être facile à utiliser dans la plupart des langages de programmation. Remplacez steps 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;
}
0
répondu Bóg Programowania 2015-05-28 12:48:44

les autres solutions nécessitent des quantités assez importantes de code et de ramification conditionnelle, ce qui les rend impropres aux GPU. Je suis récemment arrivé à la formule suivante magiquement simple 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 teinte indiquée en RVB linéaire. Pour utiliser dans une image, convertir en sRGB puis multiplier 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 graphique de chacune des coordonnées R, G, B en fonction de la valeur de hue est une valeur fixée d'une fonction de triangle périodique, et qui peut être obtenue comme la valeur absolue d'une fonction de sawtooth, x - floor(x) .

0
répondu Krzysztof Kosiński 2016-01-07 19:25:23

je peux dessiner un arc-en-ciel programmatique avec JavaScript et HTML5.

RainbowVis-JS example with rainbow arc

je fais un dégradé de rgb(255,0,0) -> rgb(255,255,0) -> rgb(0,255,0) -> rgb(0,255,255) -> rgb(0,0,255) -> rgb(255,0,255).

Je calcule les valeurs des couleurs hex le long du gradient en utilisant Ma bibliothèque RainbowVis-JS (qui enchaîne simplement les gradients ensemble). Je dessine l'arc forme avec une toile HTML5, en boucle à travers 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>
-1
répondu anomal 2012-02-29 04:31:42