颜色到图像 space 转换中的幻数
Magic numbers in color-to-image space transformation
以下请无视;我忘记了整数溢出是如何工作的 >.<
在看到关于 this Code Golf 问题的令人难以置信的答案后,我想我可能会在 C# 中生成自己的图像。我偶然发现了一段时间试图制作 XOR 图,发现直接写入组件(例如 red = a ^ b
)不起作用,但是围绕核心 a ^ b
编写围绕对数的三角函数可以;这有什么原因吗?
核心颜色生成器(绘制异或图):
ColorVec currColor = new ColorVec((float)Math.Sin(Math.Log(j ^ i)),
(float)Math.Cos(Math.Log(j ^ i)),
(float)Math.Tan(Math.Log(i ^ j)));
ColorVec
的构造函数:
public ColorVec(float xR, float yG, float zB)
{
red = xR;
green = yG;
blue = zB;
}
在浮点颜色和 Bitmap
期望的八位颜色之间转换的函数:
public byte GetIntRed()
{
return (byte)(red * 255);
}
public byte GetIntGreen()
{
return (byte)(green * 255);
}
public byte GetIntBlue()
{
return (byte)(blue * 255);
}
程序代码:
class Program
{
static void Main(string[] args)
{
short width = 2048;
Random rand = new Random();
Bitmap imageWriting = new Bitmap(width, width);
for (short i = 0; i < width; i += 1)
{
Console.WriteLine(String.Concat("Working... (writing batch ", i, " of ", width, ")"));
for (short j = 0; j < width; j += 1)
{
ColorVec currColor = new ColorVec((float)Math.Sin(Math.Log(j ^ i)),
(float)Math.Cos(Math.Log(j ^ i)),
(float)Math.Tan(Math.Log(i ^ j)));
imageWriting.SetPixel(i, j, Color.FromArgb(1, currColor.GetIntRed(),
currColor.GetIntGreen(),
currColor.GetIntBlue()));
}
}
imageWriting.Save("test.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
}
我觉得这个问题不是很清楚,但还是会尽量提供一些想法。
所以您在某种意义上试图绘制 3D 图:两个变量是 i
和 j
坐标,第三个变量是颜色。您的函数 i^j
(或任何其他此类函数)returns 一个整数,现在您需要将该整数映射到某种颜色。这可以通过多种方式完成,最直接的是:
var color = Color.FromArgb(i ^ j); // will produce more clear plot than your way
这会将结果的一个字节视为 aplha,将其他 3 个字节视为 r\g\b 部分。您正在使用另一种方式,但它没有任何特殊含义。 Sin
、Cos
、Tan
函数只有范围 (-1;1),所以当您将结果乘以 255 并转换为字节时(负浮点数转换为字节也有效) - 你得到一个有效的颜色部分。 Log
功能不是必需的,但如果您应用它 - 结果颜色会有所不同。
以下请无视;我忘记了整数溢出是如何工作的 >.<
在看到关于 this Code Golf 问题的令人难以置信的答案后,我想我可能会在 C# 中生成自己的图像。我偶然发现了一段时间试图制作 XOR 图,发现直接写入组件(例如 red = a ^ b
)不起作用,但是围绕核心 a ^ b
编写围绕对数的三角函数可以;这有什么原因吗?
核心颜色生成器(绘制异或图):
ColorVec currColor = new ColorVec((float)Math.Sin(Math.Log(j ^ i)),
(float)Math.Cos(Math.Log(j ^ i)),
(float)Math.Tan(Math.Log(i ^ j)));
ColorVec
的构造函数:
public ColorVec(float xR, float yG, float zB)
{
red = xR;
green = yG;
blue = zB;
}
在浮点颜色和 Bitmap
期望的八位颜色之间转换的函数:
public byte GetIntRed()
{
return (byte)(red * 255);
}
public byte GetIntGreen()
{
return (byte)(green * 255);
}
public byte GetIntBlue()
{
return (byte)(blue * 255);
}
程序代码:
class Program
{
static void Main(string[] args)
{
short width = 2048;
Random rand = new Random();
Bitmap imageWriting = new Bitmap(width, width);
for (short i = 0; i < width; i += 1)
{
Console.WriteLine(String.Concat("Working... (writing batch ", i, " of ", width, ")"));
for (short j = 0; j < width; j += 1)
{
ColorVec currColor = new ColorVec((float)Math.Sin(Math.Log(j ^ i)),
(float)Math.Cos(Math.Log(j ^ i)),
(float)Math.Tan(Math.Log(i ^ j)));
imageWriting.SetPixel(i, j, Color.FromArgb(1, currColor.GetIntRed(),
currColor.GetIntGreen(),
currColor.GetIntBlue()));
}
}
imageWriting.Save("test.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
}
我觉得这个问题不是很清楚,但还是会尽量提供一些想法。
所以您在某种意义上试图绘制 3D 图:两个变量是 i
和 j
坐标,第三个变量是颜色。您的函数 i^j
(或任何其他此类函数)returns 一个整数,现在您需要将该整数映射到某种颜色。这可以通过多种方式完成,最直接的是:
var color = Color.FromArgb(i ^ j); // will produce more clear plot than your way
这会将结果的一个字节视为 aplha,将其他 3 个字节视为 r\g\b 部分。您正在使用另一种方式,但它没有任何特殊含义。 Sin
、Cos
、Tan
函数只有范围 (-1;1),所以当您将结果乘以 255 并转换为字节时(负浮点数转换为字节也有效) - 你得到一个有效的颜色部分。 Log
功能不是必需的,但如果您应用它 - 结果颜色会有所不同。