【问题标题】:How to cycle through FULL RGB spectrum smoothly如何平滑地循环通过 FULL RGB 光谱
【发布时间】:2019-05-15 15:15:11
【问题描述】:

我正在尝试平滑地循环通过 RGB 光谱,但到目前为止,我只能制作平滑地通过 768 色 (256*3) 或通过 16777216 色 (256^3) 的代码离散跳跃。

下面是运行流畅的代码:

void loop() { 
  setColor(255,0,0);
  setColor(255,255,0);
  setColor(0,255,0);
  setColor(0,255,255);
  setColor(0,0,255);
  setColor(255,0,255);
}

void setColor(int red, int green, int blue) {
  while ( r != red ) {
    if ( r < red ) r += 1;
    if ( r > red ) r -= 1;
    _setColor();
    delay(10);
  }
  while ( g != green){
    if ( g < green ) g += 1;
    if ( g > green ) g -= 1;
    _setColor();
    delay(10);
  }
  while ( b != blue){
    if ( b < blue ) b += 1;
    if ( b > blue ) b -= 1;
    _setColor();
    delay(10);
  }
}


void _setColor() {
  analogWrite(redPin, r);
  analogWrite(greenPin, g);
  analogWrite(bluePin, b); 
}

这是遍历每个 RGB 值的代码:

void loop() { 
  for (r = 0; r <= 255; r++) {
    for (g = 0; g <= 255; g++) {
      for (b = 0; b <= 255; ++) {
        analogWrite(redPin, r);
        analogWrite(greenPin, g);
        analogWrite(bluePin, b); 
      }
    }
}

平滑代码永远不会组合颜色的最大值/最小值之间的值,即我从来没有得到像 [128,64,72] 这样的东西,只有像 [255,64,0] 或 [0,0, 72]。

离散代码遍历每个蓝色值,然后增加绿色值,然后从 0 开始返回蓝色,即 [0,0,254] -> [0,0,255] -> [0,1,0] -> [0,1,1] 创建离散跳跃。

我正在尝试获得一个平滑的循环,它会遍历所有可能的 RGB 值,这可能吗?

【问题讨论】:

  • 由于色彩空间是三维的,如果您只想查看所有值,例如可以使用希尔伯特曲线。可能看起来不太好。这取决于你为什么要经历所有这些以及如何。

标签: c++ arduino arduino-uno


【解决方案1】:

当然,您可以连续访问 256^3 空间中的每个点。

最简单的方法是从一条线开始,然后将一条线变成一个平面,然后将一个平面变成一个立方体。

struct simple_generator {
  int current = 0;
  int min = 0;
  int max = 255;
  int direction = 1;
  bool advance() // returns false iff we hit the end
  {
    if (current + direction > max || current+direction < min) {
      direction = -direction;
      return false;
    }
    current += direction;
    return true;
   }
 };

现在让我们用它来制作一个生成器。

template<std::size_t N>
struct shape_generator {
  simple_generator state[N];
  int operator[](std::size_t i) const { return state[i].current; }
  bool advance() {
    for (std::size_t i = 0; i < N; ++i) {
      if (state[i].advance())
        return true;
    }
    return false;
  }
};

现在这是做什么的,它使第一个简单的生成器前进,直到它溢出(这导致生成器停止并反转方向)。如果溢出,它会“递归”推进下一个。

如果每个生成器都溢出,则返回 false。否则返回 true。

这将产生一条非常无聊的曲线,因为它看起来像“蓝色到顶部,然后返回,返回顶部,然后返回”。只有经过多次循环后,才会出现任何绿色。只有经过多次绿色循环后,才会出现红色。

更高级的人会使用真实空间填充曲线的近似值,例如希尔伯特曲线。但这应该可行

Live example with a max of 5,因为为 256^3 个元素运行它似乎很粗鲁。

【讨论】:

    猜你喜欢
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 2016-05-08
    • 1970-01-01
    相关资源
    最近更新 更多