我喜欢随机生成 - 以及随机颜色 - 所以我决定将它们组合起来并制作一个简单的2d景观生成器。我的想法是,根据块的高度,(是的,地形由块组成)使其更亮或更暗,最靠近顶部的东西更亮,而朝向底部的东西更暗。我让它以灰度工作,但正如我所知,你不能真正使用基本的RGB颜色,并使其更轻,因为RGB值之间的比例,或任何类型,似乎是不可用的。解? HSL。或者也许HSV,说实话我还是不知道区别。我指的是H 0-360,S& V / L = 0-100。虽然......好吧,360 = 0,所以这是360值,但如果你实际上有0-100,那就是101.它真的是0-359和1-100(或0-99?),但颜色选择编辑(目前指的是GIMP ...... MS绘画超过100饱和度)允许您输入这些值?
无论如何,我找到了HSL-> RGB转换的公式(here& here。据我所知,最终公式是相同的,但是我会提供代码(请注意,这是来自后者的easyrgb.com链接):
Hue_2_RGB
float Hue_2_RGB(float v1, float v2, float vH) //Function Hue_2_RGB
{
if ( vH < 0 )
vH += 1;
if ( vH > 1 )
vH -= 1;
if ( ( 6 * vH ) < 1 )
return ( v1 + ( v2 - v1 ) * 6 * vH );
if ( ( 2 * vH ) < 1 )
return ( v2 );
if ( ( 3 * vH ) < 2 )
return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 );
return ( v1 );
}
和另一段代码:
float var_1 = 0, var_2 = 0;
if (saturation == 0) //HSL from 0 to 1
{
red = luminosity * 255; //RGB results from 0 to 255
green = luminosity * 255;
blue = luminosity * 255;
}
else
{
if ( luminosity < 0.5 )
var_2 = luminosity * (1 + saturation);
else
var_2 = (luminosity + saturation) - (saturation * luminosity);
var_1 = 2 * luminosity - var_2;
red = 255 * Hue_2_RGB(var_1, var_2, hue + ( 1 / 3 ) );
green = 255 * Hue_2_RGB( var_1, var_2, hue );
blue = 255 * Hue_2_RGB( var_1, var_2, hue - ( 1 / 3 ) );
}
抱歉,不确定修复空格的好方法。
我用自己的名字,色调,饱和度和亮度替换了H,S,L值。我回头看了看,但除非我遗漏了一些东西,否则我会正确地更换它。但是,除了C ++所需的部分之外,hue_2_RGB函数完全未经编辑。 (例如变量类型)。我也常常对所有东西都有整数--R,G,B,H,S,L - 然后它出现在我身上...... HSL是公式的浮点 - 或者至少,它似乎应该是。所以我使用变量(var_1,var_2,所有v,R,G,B,色调,饱和度,亮度)浮点数。所以我不相信这是某种数据丢失错误。另外,在输入公式之前,我有hue / = 360,饱和度/ = 100,发光度/ = 100.请注意,在此之前,我有hue = 59,饱和度= 100,发光度= 70.我相信我得到了正确的色调为360以确保0-1,但尝试/ = 100也没有解决它。
所以,我的问题是,为什么公式不起作用?谢谢,如果你能提供帮助。
编辑:如果问题不明确,请对其进行评论。
答案 0 :(得分:0)
你的前提是错的。您可以缩放RGB颜色。例如,Java中的Color类包含名为.darker()和.brighter()的命令,这些命令使用.7的因子,但您可以使用任何您想要的。
public Color darker() {
return new Color(Math.max((int)(getRed() *FACTOR), 0),
Math.max((int)(getGreen()*FACTOR), 0),
Math.max((int)(getBlue() *FACTOR), 0),
getAlpha());
}
public Color brighter() {
int r = getRed();
int g = getGreen();
int b = getBlue();
int alpha = getAlpha();
/* From 2D group:
* 1. black.brighter() should return grey
* 2. applying brighter to blue will always return blue, brighter
* 3. non pure color (non zero rgb) will eventually return white
*/
int i = (int)(1.0/(1.0-FACTOR));
if ( r == 0 && g == 0 && b == 0) {
return new Color(i, i, i, alpha);
}
if ( r > 0 && r < i ) r = i;
if ( g > 0 && g < i ) g = i;
if ( b > 0 && b < i ) b = i;
return new Color(Math.min((int)(r/FACTOR), 255),
Math.min((int)(g/FACTOR), 255),
Math.min((int)(b/FACTOR), 255),
alpha);
}
简而言之,将所有三种颜色乘以相同的静态因子,您将拥有相同的颜色比例。这是一个有损操作,您需要确保将颜色压缩以保持在范围内(这比舍入误差更有损耗。)
坦率地说,任何转换为RGB到HSV的只是数学,而改变HSV V因子只是数学,更改它是更多的数学。你不需要任何这些。你可以做数学。这将使最大组件颜色更大而不会弄乱颜色之间的比例。
-
如果问题更具体,您只想获得更好的结果。有更好的方法来计算这个。您可以转换为亮度组件,而不是静态缩放亮度(L不指亮度)。这基本上是以特定方式加权的。颜色科学和计算正在处理人类观察者,它们比实际数学更重要。为了解释这些人类的一些怪癖,需要“解决问题”与人类普遍认为的更相似。 Luma的规模如下:
Y = 0.2126 R + 0.7152 G + 0.0722 B
这类似地反映在权重30,59,11中,其被错误地认为是良好的颜色距离权重。这些重量是人类对亮度感知的颜色贡献。例如,人类看到最亮的蓝色非常暗。虽然黄色(与蓝色完全相反)被认为是如此明亮,以至于你甚至无法在白色背景下制作它。包括的多个颜色空间Y'CbCr通过缩放解释了对亮度感知的这些差异。然后你可以改变那个值,当你缩小它时它会再次缩放。
导致不同的颜色,这应该更像人类所说的相同颜色的“更轻”版本。这个人类系统有更好和更好的近似值,因此使用更好和更好的数学来解释它通常会给你更好更好的结果。
有关这些问题的详细概述。 http://www.compuphase.com/cmetric.htm