0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如果让程序自动来填写每一个像素点,最后会是一副什么画呢?

Android编程精选 来源:小林coding 作者:烧茄子 2022-04-13 14:59 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Hi,大家好。

我们知道,在计算机中要显示颜色,一般都是用R、G、B三个0-255范围内的整数来描述。

89413620-ba77-11ec-aa7f-dac502259ad0.png

这一点,即便你不是从事前端、客户端这些与界面交互相关的开发工作,也应该知道。

也就是说,你现在在屏幕上看到的任何一个像素点的颜色,都可以用RGB三个整数值来表示。

那就有一个有趣的问题:如果让程序自动来填写每一个像素点,最后会是一副什么画呢?

最近我在知乎就看到了这么一个有趣的话题,看完真的让人称奇,独乐乐不如众乐乐,分享给大家。

事情是这么一回事:

国外有个大佬在StackExchange上发起了一个叫做 Tweetable Mathematical Art 的比赛。

参赛者需要用C++编写代表三原色的RD、GR、BL三个函数,每个函数都不能超过 140 个字符。每个函数都会接到 i 和 j 两个整型参数(0 ≤ i, j ≤ 1023),然后需要返回一个 0 到 255 之间的整数,表示位于 (i, j) 的像素点的颜色值。

举个例子,如果 RD(0, 0) 和 GR(0, 0) 返回的都是 0 ,但 BL(0, 0) 返回的是 255 ,那么图像的最左上角那个像素就是蓝色。

参赛者编写的代码会被插进下面这段程序当中(我做了一些细微的改动),最终会生成一个大小为 1024×1024 的图片。

//NOTE:compilewithg++filename.cpp-std=c++11
#include
#include
#include
#defineDIM1024
#defineDM1(DIM-1)
#define_sq(x)((x)*(x))//square
#define_cb(x)abs((x)*(x)*(x))//absolutevalueofcube
#define_cr(x)(unsignedchar)(pow((x),1.0/3.0))//cuberoot

unsignedcharGR(int,int);
unsignedcharBL(int,int);

unsignedcharRD(inti,intj){
//YOURCODEHERE
}
unsignedcharGR(inti,intj){
//YOURCODEHERE
}
unsignedcharBL(inti,intj){
//YOURCODEHERE
}

voidpixel_write(int,int);
FILE*fp;
intmain(){
fp=fopen("MathPic.ppm","wb");
fprintf(fp,"P6
%d%d
255
",DIM,DIM);
for(intj=0;jfor(inti=0;ireturn0;
}
voidpixel_write(inti,intj){
staticunsignedcharcolor[3];
color[0]=RD(i,j)&255;
color[1]=GR(i,j)&255;
color[2]=BL(i,j)&255;
fwrite(color,1,3,fp);
}

我选了一些自己比较喜欢的作品,放在下面和大家分享。首先是一个来自 Martin Büttner 的作品:

8950cdba-ba77-11ec-aa7f-dac502259ad0.jpg

它的代码如下:

unsignedcharRD(inti,intj){
return(char)(_sq(cos(atan2(j-512,i-512)/2))*255);
}

unsignedcharGR(inti,intj){
return(char)(_sq(cos(atan2(j-512,i-512)/2-2*acos(-1)/3))*255);
}

unsignedcharBL(inti,intj){
return(char)(_sq(cos(atan2(j-512,i-512)/2+2*acos(-1)/3))*255);
}

同样是来自 Martin Büttner 的作品:

895d3dde-ba77-11ec-aa7f-dac502259ad0.jpg

这是目前暂时排名第一的作品。它的代码如下:

unsignedcharRD(inti,intj){
#definer(n)(rand()%n)
staticcharc[1024][1024];
return!c[i][j]?c[i][j]=!r(999)?r(256):RD((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}

unsignedcharGR(inti,intj){
staticcharc[1024][1024];
return!c[i][j]?c[i][j]=!r(999)?r(256):GR((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}

unsignedcharBL(inti,intj){
staticcharc[1024][1024];
return!c[i][j]?c[i][j]=!r(999)?r(256):BL((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}

下面这张图片仍然出自 Martin Büttner 之手:

896ae57e-ba77-11ec-aa7f-dac502259ad0.jpg

难以想象, Mandelbrot 分形图形居然可以只用这么一点代码画出:

unsignedcharRD(inti,intj){
floatx=0,y=0;intk;for(k=0;k++<256;){floata=x*x-y*y+(i-768.0)/512;y=2*x*y+(j-512.0)/512;x=a;if(x*x+y*y>4)break;}
returnlog(k)*47;
}

unsignedcharGR(inti,intj){
floatx=0,y=0;intk;for(k=0;k++<256;){floata=x*x-y*y+(i-768.0)/512;y=2*x*y+(j-512.0)/512;x=a;if(x*x+y*y>4)break;}
returnlog(k)*47;
}

unsignedcharBL(inti,intj){
floatx=0,y=0;intk;for(k=0;k++<256;){floata=x*x-y*y+(i-768.0)/512;y=2*x*y+(j-512.0)/512;x=a;if(x*x+y*y>4)break;}
return128-log(k)*23;
}

Manuel Kasten 也制作了一个 Mandelbrot 集的图片,与刚才不同的是,该图描绘的是 Mandelbrot 集在某处局部放大后的结果:

897933f4-ba77-11ec-aa7f-dac502259ad0.jpg

它的代码如下:

unsignedcharRD(inti,intj){
doublea=0,b=0,c,d,n=0;
while((c=a*a)+(d=b*b)<4&&n++<880)
{b=2*a*b+j*8e-9-.645411;a=c-d+i*8e-9+.356888;}
return255*pow((n-80)/800,3.);
}

unsignedcharGR(inti,intj){
doublea=0,b=0,c,d,n=0;
while((c=a*a)+(d=b*b)<4&&n++<880)
{b=2*a*b+j*8e-9-.645411;a=c-d+i*8e-9+.356888;}
return255*pow((n-80)/800,.7);
}

unsignedcharBL(inti,intj){
doublea=0,b=0,c,d,n=0;
while((c=a*a)+(d=b*b)<4&&n++<880)
{b=2*a*b+j*8e-9-.645411;a=c-d+i*8e-9+.356888;}
return255*pow((n-80)/800,.5);
}

这是 Manuel Kasten 的另一作品:

89866c22-ba77-11ec-aa7f-dac502259ad0.jpg

生成这张图片的代码很有意思:函数依靠 static 变量来控制绘画的进程,完全没有用到 i 和 j 这两个参数!

unsignedcharRD(inti,intj){
staticdoublek;k+=rand()/1./RAND_MAX;intl=k;l%=512;returnl>255?511-l:l;
}

unsignedcharGR(inti,intj){
staticdoublek;k+=rand()/1./RAND_MAX;intl=k;l%=512;returnl>255?511-l:l;
}

unsignedcharBL(inti,intj){
staticdoublek;k+=rand()/1./RAND_MAX;intl=k;l%=512;returnl>255?511-l:l;
}

这是来自 githubphagocyte 的作品:

8993b03a-ba77-11ec-aa7f-dac502259ad0.jpg

它的代码如下:

unsignedcharRD(inti,intj){
floats=3./(j+99);
floaty=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
return(int((i+DIM)*s+y)%2+int((DIM*2-i)*s+y)%2)*127;
}

unsignedcharGR(inti,intj){
floats=3./(j+99);
floaty=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
return(int(5*((i+DIM)*s+y))%2+int(5*((DIM*2-i)*s+y))%2)*127;
}

unsignedcharBL(inti,intj){
floats=3./(j+99);
floaty=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
return(int(29*((i+DIM)*s+y))%2+int(29*((DIM*2-i)*s+y))%2)*127;
}

这是来自 githubphagocyte 的另一个作品:

89a4472e-ba77-11ec-aa7f-dac502259ad0.jpg

这是一张使用 diffusion-limited aggregation 模型得到的图片,程序运行起来要耗费不少时间。代码很有意思:巧妙地利用宏定义,打破了函数与函数之间的界限,三段代码的字数限制便能合在一起使用了。

unsignedcharRD(inti,intj){
#defineDDIM
#defineMm[(x+D+(d==0)-(d==2))%D][(y+D+(d==1)-(d==3))%D]
#defineRrand()%D
#defineBm[x][y]
return(i+j)?256-(BL(i,j))/2:0;
}

unsignedcharGR(inti,intj){
#defineAstaticintm[D][D],e,x,y,d,c[4],f,n;if(i+j<1){for(d=D*D;d;d--){m[d%D][d/D]=d%6?0:rand()%2000?1:255;}for(n=1
returnRD(i,j);
}

unsignedcharBL(inti,intj){
A;n;n++){x=R;y=R;if(B==1){f=1;for(d=0;d<4;d++){c[d]=M;f=fif(f>2){B=f-1;}else{++e%=4;d=e;if(!c[e]){B=0;M=1;}}}}}returnm[i][j];
}

最后这张图来自 Eric Tressler:

89b672b4-ba77-11ec-aa7f-dac502259ad0.jpg

这是由 logistic 映射得到的 Feigenbaum 分岔图。和刚才一样,对应的代码也巧妙地利用了宏定义来节省字符:

unsignedcharRD(inti,intj){
#defineAfloata=0,b,k,r,x
#defineBinte,o
#defineC(x)x>255?255:x
#defineRreturn
#defineDDIM
RBL(i,j)*(D-i)/D;
}

unsignedcharGR(inti,intj){
#defineEDM1
#defineFstaticfloat
#defineGfor(
#defineHr=a*1.6/D+2.4;x=1.0001*b/D
RBL(i,j)*(D-j/2)/D;
}

unsignedcharBL(inti,intj){
Fc[D][D];if(i+j<1){A;B;G;a0.1){Gb=0;b0;k1-x);if(k>D/2){e=a;o=(E*x);c[e][o]+=0.01;}}}}}RC(c[j][i])*i/D;
}

怎么样,短短几行代码,就能画出如此绚烂的图像,你有没有什么脑洞大开的想法,可以复制上面的代码来试一试啊!

-End-

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66850
  • C++
    C++
    +关注

    关注

    22

    文章

    2122

    浏览量

    76714
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73155

原文标题:这几行代码,真的骚!

文章出处:【微信号:AndroidPush,微信公众号:Android编程精选】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于STM32F103C8T6驱动WS2812彩灯模块点亮RGB灯

    、WS2812模块简介 WS2812是集控制电路与发光电路于体的智能外控LED光源。其外型与
    的头像 发表于 12-04 11:29 5544次阅读
    基于STM32F103C8T6驱动WS2812彩灯模块点亮RGB灯

    基于FPGA的肤色检测方案简介

    顺序构建3*3方块矩阵,然后对矩阵中的像素点进行运算,对于腐蚀操作就是“与”,对于膨胀操作就是“或”。在vivado中,可以使用shift RAM构建方块矩阵。shift RAM的深度设置为图像
    发表于 10-28 07:07

    请问各位大神,我要用串口控制12台串联的气体流量计,想要做好一点该怎么修改程序

    台机器的读操作都放在顺序平铺结构里面了,然后前面板就是次只能读台机器的流量,此时如果我要执行写操作,比如写设定流量值的大小,我就只能在读相邻机器的流量之间加一个时间延时,这样
    发表于 09-30 11:13

    请问cyw920719b2q40evb如何设置每一个蓝牙芯片的mac地址不样?

    请问下 cyw920719b2q40evb 如何设置每一个蓝牙芯片的mac地址不? 谢谢
    发表于 07-07 06:34

    如何烧录程序进入自己的20829板里

    Hi,请问如何烧录程序进入自己的20829板里?可以使用20829EVK的J11实现么?或者有没有其它的烧录工具
    发表于 07-01 07:42

    max9979把DOUT也share到根线上,如果次只片选其中CS#, 其他未被片选的芯片DOUT会是高阻态吗?

    我有10路max9979, 共用路SPI控制接口(其中CS#是独立的)。 当我把DOUT也share到根线上,如果次只片选其中
    发表于 06-11 06:19

    请问DMD为何和色轮配合可以投影出彩色图像?

    之前得到的回答是“红光照射到DMD上时,只有红色像素点的镜子呈开的状态反射光,绿光照时,只有绿色像素点的镜子反射光,蓝光照射时,只有蓝色像素点的镜子反射光” 但我还有以下几个疑问: 1.色轮转
    发表于 03-03 06:51

    DLP4100在激光照明情况下,DMD上面加载一副空白图像之,反射出来就不是均匀的图像了,为什么?

    我现在所用的产品是DLP4100,在激光照明情况下,DMD上面加载一副空白图像之,,反射出来就不是均匀的图像了,而是带有随机噪声的一副图,这个是怎么回事? 加载在DMD上的图片和DMD反射出来的图片分别如下图:
    发表于 02-28 07:28

    MCU通过DLPC150的parallel interface传输RGB数据时,是如何确定像素已经传输完成的

    to the horizontal and vertical syncs. 1.如果我使用MCU向DLPC150传输854*480像素,时序图是怎样的?有没有传输几个
    发表于 02-28 07:26

    直接用激光打在DMD上,反射出来的图形每一个像素的光会有晕开的现象怎么解决?

    请问会产生以下问题的原因是什么 有办法去除吗 另外发现如果用激光直接打在DMD上 反射出来的图形每一个像素的光会有晕开的现象 有办法解决吗? 谢谢
    发表于 02-28 07:03

    请问DLP9000X如何实现8bit灰度图显示?

    的? 2.8bit灰度图显示到底如何实现? 例如张图有两像素点A和B,像素值分别为A【
    发表于 02-20 06:26

    FPGA图像处理基础----实现缓存卷积窗口

    像素行与像素窗口 幅图像是由一个个像素点构成的,对于幅480*272大小的图片来说,其宽度是
    的头像 发表于 02-07 10:43 1427次阅读
    FPGA图像处理基础----实现缓存卷积窗口

    ADC124S051在每一个SCLK周期,DIN与DOUT是同时发生的吗?

    DOUT? 我在实际测试中发现,在每一个SCLK,DIN选择的通道,总是在下次DOUT输出,请问这个正常现象吗?如果是,这个芯片为什么会这么设计?谢谢!
    发表于 01-23 06:40

    请问TVP5158分辨率D1与HalfD1是如何转换的?

    的数据格式之间到底是如何转换的。比如说我要将D1分辨率的数据变成HalfD1的分辨率,其中可以从手册中看出是将D1格式数据行中的像素点去掉了半,但是去掉的这
    发表于 12-23 06:31

    ADS8326采样AD值,直跳动10来个,是什么原因引起的?

    ADS8326,目前测试情况不是很理想,暂时无法排查出什么原因,现在的现象是: 采样AD值,直跳动10来个。而我们现在实际要求的比较高,要保证跳动1-3
    发表于 12-20 06:44