Java- 创建一个离散的彩虹色数组

4

很难描述我想做的事情。我基本上想创建一个离散的彩虹渐变,这样对于任何一行具有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));
    }

我已经完成了这个,但是我手头没有算法。从我记得的来看,这不是一件容易的事情,这是一个相当复杂的算法。在我找到有用的算法之前,我在 Paint 的颜色编辑器中四处观察 RGB 在 2D 范围内的工作方式。这里可以看到我所做的示例(我的颜色数组在底部)http://tinypic.com/view.php?pic=whl0eu&s=8#.U0Wz4_ldW3Q - zgc7009
@zgc7009 看起来相当复杂! - Fraser Price
还需要一些调整,但是确实相当复杂。等我回到我的桌面电脑时,我会看看能否找到算法,至少给你一个开始的地方。 - zgc7009
还需考虑Color.getHSBColor,可查看这里 - trashgod
2个回答

15

您的代码想法是正确的,但需要稍微改变一下颜色的运行方式。

假设您从绿色开始:

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()]);

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

附言:就我所用过的情况而言,上述线性淡化效果已经足够,并且看起来符合预期。个人认为,您不需要通过使用正弦和余弦或其他数学方法来使事情变得复杂。


非常感谢,真的很有帮助! - Fraser Price

13

你可以使用HSV(hue, saturation, value)代替RGB。

在HSV中,颜色范围仅受一个变量(色相)的影响。如果你从0到360运行,则涵盖了所有颜色范围。

HSV scheme

代码示例:

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});
}

HSV color scheme


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接