Language agnostic 给我画一道彩虹

Language agnostic 给我画一道彩虹,language-agnostic,colors,rgb,Language Agnostic,Colors,Rgb,您将如何在光谱颜色范围内均匀分布一系列RGB颜色?以使其看起来像真正的彩虹。改用HSL:固定亮度和饱和度,将色调从0更改为360,然后转换为RGB HSL描述人们感知的颜色。RGB将它们描述为机器使用的对象。因此,直接使用RGB无法真正做到任何视觉上令人愉悦的事情。您可以使用,并在色调维度上漫游 红色(卷筒纸颜色)(十六进制:#FF0000)(RGB:255,0,0) 橙色(色轮橙色)(十六进制:#FF7F00)(RGB:255127,0) 黄色(卷筒纸颜色)(十六进制:#FFFF00)(RG

您将如何在光谱颜色范围内均匀分布一系列RGB颜色?以使其看起来像真正的彩虹。

改用HSL:固定亮度和饱和度,将色调从0更改为360,然后转换为RGB

HSL描述人们感知的颜色。RGB将它们描述为机器使用的对象。因此,直接使用RGB无法真正做到任何视觉上令人愉悦的事情。

您可以使用,并在色调维度上漫游

  • 红色(卷筒纸颜色)(十六进制:#FF0000)(RGB:255,0,0)
  • 橙色(色轮橙色)(十六进制:#FF7F00)(RGB:255127,0)
  • 黄色(卷筒纸颜色)(十六进制:#FFFF00)(RGB:255、255、0)
  • 绿色(X11)(电绿色)(HTML/CSS“石灰”)(色轮绿色)(十六进制:#00FF00)(RGB:0250)
  • 蓝色(卷筒纸颜色)(十六进制:#0000FF)(RGB:0,0,255)
  • 靛蓝(电靛蓝)(十六进制:#6600FF)(RGB:102,025)
  • 紫罗兰色(电紫罗兰色)(十六进制:#8B00FF)(RGB:139,025)

在每个颜色之间进行线性插值。

最简单的方法是在此序列中的每个连续对之间进行线性插值(以RGB为单位):

  • #ff0000
    红色
  • #ffff00
    黄色
  • #00ff00
    绿色
  • #00ffff
    青色
  • #0000ff
    蓝色
  • #ff00ff
    品红
  • #ff0000
    返回红色
这将获得与在HSV或HSL中扫描色调值几乎相同的结果,但可以直接在RGB中工作。请注意,每次插值只更改一个组件,这简化了事情。下面是一个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

这个类将使用PHP实现,将彩虹中需要的颜色数传递给构造函数,$sequence属性将包含一个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;
    }
}
类颜色
{
public$sequence=array();
/**
*构造函数用颜色列表填充$sequence,只要$count参数
*/
公共函数构造($count,$s=.5,$l=.5)
{
对于($h=0;$h序列[]=color::hexHSLtoRGB($h,$s,$l);
}
}
/**
*从https://stackoverflow.com/questions/3597417/php-hsv-to-rgb-formula-comprehension#3642787
*/
公共静态函数HSLtoRGB($h、$s、$l)
{
$r=$l;
$g=$l;
$b=$l;
$v=($l 0){
百万美元;
$sv;
$六分仪;
$fract;
$vsf;
$mid1;
$mid2;
$m=$l+$l-$v;
$sv=($v-$m)/$v;
$h*=6.0;
$六分仪=楼层($h);
$fract=$h-$六分仪;
$vsf=$v*$sv*$fract;
$mid1=$m+$vsf;
$mid2=$v-$vsf;
开关(六分仪)
{
案例0:
$r=$v;
$g=$mid1;
$b=$m;
打破
案例1:
$r=$mid2;
$g=$v;
$b=$m;
打破
案例2:
$r=$m;
$g=$v;
$b=$mid1;
打破
案例3:
$r=$m;
$g=$mid2;
$b=$v;
打破
案例4:
$r=$mid1;
$g=$m;
$b=$v;
打破
案例5:
$r=$v;
$g=$m;
$b=$mid2;
打破
}
}
返回数组('r'=>floor($r*255.0),
“g”=>地板($g*255.0),
“b”=>地板($b*255.0)
);
}
//从hsv值返回十六进制代码
公共静态函数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);
返回$hex;
}
}
测试,例如:

$c = new color(100);
foreach($c->sequence as $col)
  print "<div style='background-color:#$col'>$col</div>\n";
$c=新颜色(100);
foreach($c->序列为$col)
打印“$col\n”;
我只要求将其打包成类,原始函数可在本文中找到:
我可以用JavaScript和HTML5编程绘制彩虹

我从rgb(255,0,0)->rgb(255255,0)->rgb(0255,0)->rgb(0255255)->rgb(02555,0)->rgb(0,0255)->rgb(255,0255)生成梯度

我使用我的库(只将渐变链接在一起)沿渐变计算十六进制颜色值。 我用HTML5画布绘制弧形,在颜色中循环

<!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>

window.onload=函数(){
var彩虹_宽度=60;
var RAINBOW_半径=130;
//图书馆课
var rainbow=新彩虹();
彩虹。设置编号排列(1,彩虹宽度);
彩虹光谱(
‘FF0000’、‘FFFF00’、‘00FF00’,
'00FFFF'、'0000FF'、'FF00FF'
);
//帆布
var canvas=document.getElementById('MyCanvas');
var context=canvas.getContext('2d');
context.lineWidth=1;

对于(var i=1;i我知道这是一个相当古老的问题,但这里是我的简单易懂的解决方案,在大多数编程语言中应该很容易使用。 用您自己的值替换步骤和whichStep

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;
}
int steps=1280;
int stepChange=1280/步;
int change=stepChange*whichStep;
int r=0,g=0,b=0;
如果(更改<256)
{
r=255;
g+=变化;
}
否则如果(更改<512)
{
r=511——变化;
g=255;
}
否则如果
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);
}
std::array<float, 3> HueToRGB(float hue, float *rgb) {
  std::array<float, 3> rgb;
  for (unsigned i = 0; i < 3; ++i) {
    const float h = hue + i / 3.f;
    rgb[i] = std::clamp(6.f * std::fabs(h - std::floor(h) - 0.5f) - 1.f, 0.f, 1.f);
  }
  return rgb;
}