了解图形的绘制方式

Understanding the way a figure is drawn

这是从以下神秘代码中得出的结果,该代码显然是在 canvas 区域上逐个像素地绘制所有内容:

int w, h;

for(w = 0; w < width; w++)
{
    for(h = height-1; h >= 0; h--)
    {
        setpen(w, h, distance(w, h, 255, 255), 0.0F, 1U); // r g b(distance wh : 255) transp pensize
        putpixel(w, h);
    }
}

为什么这么短的代码会产生这么有趣的图像? 它有名字吗?目的?它到底代表了什么?

这段代码一次绘制一个像素,正如你所看到的,这确实是一个谜,因为我们没有setpen的内容,也没有距离函数。

要了解如此简单的代码如何生成如此复杂的图像,您必须首先记住像 getPixelColor(x,y) 这样简单的函数可以通过读取文件中的每个像素来绘制您可以想象的任何可能的图像.通过隐藏这样的细节,可以用简单的代码创建任意复杂的图片。

这个概念在计算机科学中非常重要,被称为"abstraction"。这意味着我们隐藏了如何在其他地方实现并以看似简单的方式访问的函数中选择像素颜色的细节。

如果您想绘制不同类型的图像,您只需更改获取每个像素的函数,并通过在不同图像之间进行此更改即可。

您可以尝试通过将当前函数替换为一个函数来玩这个会用一个非常简单的函数给你一个相当有趣的结果。

就像其他人提到的那样,您也可以研究分形。 Mandelbrot 集是一个有趣的实现,其中确定像素的方程类似于 x=(x-1)^2+C.

http://mathworld.wolfram.com/MandelbrotSet.html

这里没有什么神秘之处,因为图像分析和一点观察表明。

首先,图像尺寸为 514 x 514,去除边框后有效尺寸为 512 x 512。

setpen() 代码中的注释表示前三个参数设置了红色、绿色和蓝色的颜色级别。接下来是透明度,设置为 0。最后一个参数是画笔大小,设置为 1,因此写入的任何像素都不会影响任何邻居。

暂时忽略蓝色分量,将像素坐标传递给红色和绿色参数。由于颜色范围为 0..255,坐标范围为 0..511,因此红色和绿色将各自 "wrap" 两次以生成四个相同的图块。每个图块(如您所见)都会沿着一条对角线从红色 (255,0,b) 逐渐变为绿色 (0,255,b),沿着一条对角线从黑色 (0,0,b) 变为黄色 (255,255,b)另一个对角线。在每个瓦片连接处,坐标从 255 变为 256,使颜色值从 255 变为 0。

现在让我们添加蓝色。我的眼睛告诉我,蓝色分量从中心向外径向增加,并且在半径 256 处再次出现阶跃变化。我在图像的左上角检测到一丝深蓝色(应该是黑色的地方),并且使用图形实用程序中的 "dropper" 工具显示最角落的蓝色级别为 104。

所以现在我将对 distance 函数进行逆向工程。

int distance(int x, int y, int ox, int oy) {
    int dx = x - ox;
    int dy = y - oy;
    return (int)sqroot(dx * dx + dy * dy);
}

现在测试它以查看 returns 在 (0, 0)

dx = 0 - 255
dy = 0 - 255
return 360

由于像素颜色将为 mod 256,因此 360 蓝色将绘制为 (360 - 256) = 104。

最后,请注意圆圈并没有完全到达右侧和底部边缘的边界,有一个 1 像素宽的条带。这是由于圆心传给distance255,图片大小为偶数个像素,所以没有准确的圆心。

QED