了解绘制图形的方式

时间:2015-07-22 18:34:01

标签: c image graphics drawing draw

enter image description here

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

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

为什么这么短的代码会产生如此有趣的图像? 它有名字吗?目的是什么?它有什么作用?

2 个答案:

答案 0 :(得分:2)

这里没有任何神秘感,因为对图像的分析和一点观察表明。

首先,图像尺寸为514 x 514,删除边框时,有效尺寸为512 x 512.

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

暂时忽略蓝色组件,红色和绿色参数将传递像素坐标。由于颜色范围是0..255并且坐标范围是0..511,因此红色和绿色将每次“包裹”两次以产生四个相同的图块。每个瓷砖(如你所见)将沿着一个对角线从红色(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);
}

现在测试它以查看它在(0,0)返回的内容

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

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

最后,注意圆圈沿着右边缘和底边缘没有完全到达边界,有一个1像素宽的条带。这是因为圆心被传递给distance 255,图像大小是偶数个像素,所以没有确切的中心。

QED

答案 1 :(得分:1)

这段代码就像你注意到的那样一次绘制一个像素,这确实是个谜,因为我们没有setpen的内容或者距离函数。

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

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

如果你想绘制不同类型的图像,你可以改变获取每个像素的功能,并在不同的图像之间进行这种改变。

您可以尝试使用一个函数来替换当前函数,该函数使用等式设置颜色 - 例如sin(x)表示红色,sin(y)表示绿色,cos(x)表示蓝色表示这是一个非常有趣的结果,功能非常简单。

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

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