我正在开发一个程序,该程序能够生成具有等高线的陆地和山脉。我想用特定颜色的单独阴影来区分每条轮廓线,例如:
我尝试了几种态度,其中之一就是我在这个网站上找到的这段代码
public static Color[] GetColorShades(Color baseColor, int shadesCount)
{
shadesCount *= 2;
Color[] output = new Color[shadesCount];
for (int index = 0; index < shadesCount; index++)
{
output[index] = DarkenColor(baseColor, (double)index / (double)shadesCount);
}
return output;
}
private static Color DarkenColor(Color color, double fraction)
{
int red = (int)Math.Round(Math.Max(0, color.R - 255 * fraction));
int green = (int)Math.Round(Math.Max(0, color.G - 255 * fraction));
int blue = (int)Math.Round(Math.Max(0, color.B - 255 * fraction));
return Color.FromArgb(red, green, blue);
}
此代码适用于绿色。但由于某种原因无法生成黄色和棕色的色调。白色似乎也是一个问题。
有人能够帮助我设计一种算法,将定义最大高度的数字分成四组,每组都有特定颜色的阴影吗?查看图片寻找灵感
您的“变暗”代码可能不正确,它会同时修改色调和亮度。您可能想要使用色相饱和度值或色相饱和度亮度,因为这些往往更符合我们对颜色的直观理解。这样,如果您想要相同颜色的较深阴影,您可以简单地修改 L 或 V 分量。
另一种选择是为每个波段定义两种颜色,然后在它们之间进行插值:
public static IEnumerable<Color> CreateInterpolatedShades(Color x, Color y, int count) =>
Enumerable.Range(0, count).Select(i => Lerp(x, y, i / (float)count));
public static Color Lerp(this Color x, Color y, float v)
{
var vInv = 1 - v;
var r = (int)(x.R * vInv + y.R * v);
var g = (int)(x.G * vInv + y.G * v);
var b = (int)(x.B * vInv + y.B * v);
var a = (int)(x.A * vInv + y.A * v);
// Clamp to 0-255
r = r < 0 ? 0 : r > byte.MaxValue ? byte.MaxValue : r;
g = g < 0 ? 0 : g > byte.MaxValue ? byte.MaxValue : g;
b = b < 0 ? 0 : b > byte.MaxValue ? byte.MaxValue : b;
a = a < 0 ? 0 : a > byte.MaxValue ? byte.MaxValue : a;
return Color.FromArgb(a, r, g, b);
}
如果插值颜色相当接近,这应该效果很好。如果它们相距较远,您可能需要在 HSV/HSL 空间中进行插值。原理是相同的,但您可能会使用其他数据类型和范围。