【问题标题】:Java- Creating a discrete rainbow colour arrayJava-创建一个离散的彩虹色数组
【发布时间】:2014-05-23 07:17:01
【问题描述】:

很难描述我想要做什么。我基本上想创建一个离散的彩虹渐变,这样对于 i 数量的 JButton 的任何一行,它们之间的颜色渐变都会看起来像彩虹。

我已经完成了以下操作,但它实际上只创建了一个红色渐变,然后是绿色渐变,然后是蓝色渐变:

Color[] c = new Color[i];
    for(int n = 0; n < i; n++) {
        if(n < i/3) {
            c[n] = new Color(255, 255/(n+1), 255/(n+1));
        } else if(n < 2*i/3) {
            c[n] = new Color(255/(n-(i/3)), 255, 255/(n-(i/3)));
        } else {
            c[n] = new Color(255/(n+1), 255/(n+1), 255);
        }
    }

知道如何获得某种类型的彩虹效果吗?

谢谢

编辑:

使用了一个似乎工作得更好的正弦函数,但不确定如何定义它,所以我在我想要的区域得到一个“彩虹波”:

for(int n = 0; n < i; n++) {
        c[n] = new Color((int)(Math.sin(n) * 127 + 128), (int)(Math.sin(n + Math.PI/2) * 127 + 128), (int)(Math.sin(n + Math.PI) * 127 + 128));
    }

【问题讨论】:

  • 我已经这样做了,但我没有算法。这并不容易,据我所知,这是一个相当复杂的算法。在我想出一个有用的算法之前,我在油漆的颜色编辑器中坐了一会儿,研究 RGB 在 2D 比例上是如何工作的。可以在这里看到我所做的一个示例(我的颜色数组在底部)tinypic.com/view.php?pic=whl0eu&s=8#.U0Wz4_ldW3Q
  • @zgc7009 看起来很复杂!
  • 仍然需要一些调整,但是是的,它非常复杂。当我回到我的桌面时,我会看看我是否找不到算法让你至少给你一个开始的地方。
  • 也可以考虑Color.getHSBColor,见here

标签: java swing colors gradient rgb


【解决方案1】:

您的代码有正确的想法,但您需要以不同的方式运行颜色。

假设您从绿色开始:

Color(  0, 255,   0)

慢慢开始添加一些红色变成黄色:

Color( 51, 255,   0)
Color(102, 255,   0)
Color(153, 255,   0)
Color(204, 255,   0)
Color(255, 255,   0)

然后,取出绿色变成红色:

Color(255, 204,   0)
Color(255, 153,   0)
Color(255, 102,   0)
Color(255,  51,   0)
Color(255,   0,   0)

现在,添加蓝色变成紫色:

Color(255,   0,  51)
Color(255,   0, 102)
Color(255,   0, 153)
Color(255,   0, 204)
Color(255,   0, 255)

然后,去掉红色变成蓝色:

Color(204,   0, 255)
Color(153,   0, 255)
Color(102,   0, 255)
Color( 51,   0, 255)
Color(  0,   0, 255)

将绿色重新添加到青色:

Color(  0,  51, 255)
Color(  0, 102, 255)
Color(  0, 153, 255)
Color(  0, 204, 255)
Color(  0, 255, 255)

最后去掉蓝色变回绿色:

Color(  0, 255, 204)
Color(  0, 255, 153)
Color(  0, 255, 102)
Color(  0, 255,  51)
Color(  0, 255,   0)

当然,在这个圈子里,你可以从任何地方开始,往任何一个方向走。

在代码中,它可能看起来很简单:

List<Color> colors = new ArrayList<Color>();
for (int r=0; r<100; r++) colors.add(new Color(r*255/100,       255,         0));
for (int g=100; g>0; g--) colors.add(new Color(      255, g*255/100,         0));
for (int b=0; b<100; b++) colors.add(new Color(      255,         0, b*255/100));
for (int r=100; r>0; r--) colors.add(new Color(r*255/100,         0,       255));
for (int g=0; g<100; g++) colors.add(new Color(        0, g*255/100,       255));
for (int b=100; b>0; b--) colors.add(new Color(        0,       255, b*255/100));
                          colors.add(new Color(        0,       255,         0));

这里,100 是每个渐变的步数,您可以调整。

如果您需要数组中的颜色,请在最后执行此操作:

Color[] c = colors.toArray(new Color[colors.size()]);

需要注意的一点:人眼对绿色比对红色和蓝色更敏感。因此,您可能希望以比红色和蓝色更小的步长添加和删除绿色。只需使用不同的步长,直到你得到看起来均匀的东西。

PS:对于我使用它的用途,如上所述的线性衰落是完全足够的,并且看起来符合预期。我个人认为您不需要使用 sin 和 cos 或其他数学来使事情复杂化。

【讨论】:

  • 非常感谢,真的很有帮助!
【解决方案2】:

您可以使用 HSV(色调、饱和度、值) 而不是RGB。 在 HSV 中,颜色范围仅受一个变量(色调)影响。 如果您从 0 到 360 度运行,则可以覆盖整个颜色范围。

代码示例:

final int ARRAY_SIZE = 100;
double jump = 360.0 / (ARRAY_SIZE*1.0);
int[] colors = new int[ARRAY_SIZE];
for (int i = 0; i < colors.length; i++) {
    colors[i] = Color.HSVToColor(new float[]{(float) (jump*i), 1.0f, 1.0f});
}

如果您只想覆盖颜色表的一部分(使用我附在下面的图片)。 一个红色的绿松石色数组示例:

final int ARRAY_SIZE = 100;
final int MAX_COLOR = 360;
final int MIN_COLOR = 160;
double jump = (MAX_COLOR-MIN_COLOR) / (ARRAY_SIZE*1.0);
int[] colors = new int[ARRAY_SIZE];
for (int i = 0; i < colors.length; i++) {
    colors[i] = Color.HSVToColor(new float[]{(float) (MIN_COLOR + (jump*i)), 1.0f, 1.0f});
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多