Kyle McCormick 在 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: compile with g++ filename.cpp -std=c++11
#include <iostream>
#include <cmath>
#include <cstdlib>
#define DIM 1024
#define DM1 (DIM-1)
#define _sq(x) ((x)*(x)) // square
#define _cb(x) abs((x)*(x)*(x)) // absolute value of cube
#define _cr(x) (unsigned char)(pow((x),1.0/3.0)) // cube root
unsigned char GR(int,int);
unsigned char BL(int,int);
unsigned char RD(int i,int j){
// YOUR CODE HERE
}
unsigned char GR(int i,int j){
// YOUR CODE HERE
}
unsigned char BL(int i,int j){
// YOUR CODE HERE
}
void pixel_write(int,int);
FILE *fp;
int main(){
fp = fopen("MathPic.ppm","wb");
fprintf(fp, "P6\n%d %d\n255\n", DIM, DIM);
for(int j=0;j<DIM;j++)
for(int i=0;i<DIM;i++)
pixel_write(i,j);
fclose(fp);
return 0;
}
void pixel_write(int i, int j){
static unsigned char color[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 的作品:
它的代码如下:
unsigned char RD(int i,int j){
return (char)(_sq(cos(atan2(j-512,i-512)/2))*255);
}
unsigned char GR(int i,int j){
return (char)(_sq(cos(atan2(j-512,i-512)/2-2*acos(-1)/3))*255);
}
unsigned char BL(int i,int j){
return (char)(_sq(cos(atan2(j-512,i-512)/2+2*acos(-1)/3))*255);
}
同样是来自 Martin Büttner 的作品:
这是目前暂时排名第一的作品。它的代码如下:
unsigned char RD(int i,int j){
#define r(n)(rand()%n)
static char c[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];
}
unsigned char GR(int i,int j){
static char c[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];
}
unsigned char BL(int i,int j){
static char c[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 之手:
难以想象, Mandelbrot 分形图形居然可以只用这么一点代码画出:
unsigned char RD(int i,int j){
float x=0,y=0;int k;for(k=0;k++<256;){float a=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;}return log(k)*47;
}
unsigned char GR(int i,int j){
float x=0,y=0;int k;for(k=0;k++<256;){float a=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;}return log(k)*47;
}
unsigned char BL(int i,int j){
float x=0,y=0;int k;for(k=0;k++<256;){float a=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;}return 128-log(k)*23;
}
Manuel Kasten 也制作了一个 Mandelbrot 集的图片,与刚才不同的是,该图描绘的是 Mandelbrot 集在某处局部放大后的结果:
它的代码如下:
unsigned char RD(int i,int j){
double a=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;}
return 255*pow((n-80)/800,3.);
}
unsigned char GR(int i,int j){
double a=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;}
return 255*pow((n-80)/800,.7);
}
unsigned char BL(int i,int j){
double a=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;}
return 255*pow((n-80)/800,.5);
}
这是 Manuel Kasten 的另一作品:
生成这张图片的代码很有意思:函数依靠 static 变量来控制绘画的进程,完全没有用到 i 和 j 这两个参数!
unsigned char RD(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=512;return l>255?511-l:l;
}
unsigned char GR(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=512;return l>255?511-l:l;
}
unsigned char BL(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=512;return l>255?511-l:l;
}
这是来自 githubphagocyte 的作品:
它的代码如下:
unsigned char RD(int i,int j){
float s=3./(j+99);
float y=(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;
}
unsigned char GR(int i,int j){
float s=3./(j+99);
float y=(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;
}
unsigned char BL(int i,int j){
float s=3./(j+99);
float y=(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 的另一个作品:
这是一张使用 diffusion-limited aggregation 模型得到的图片,程序运行起来要耗费不少时间。代码很有意思:巧妙地利用宏定义,打破了函数与函数之间的界限,三段代码的字数限制便能合在一起使用了。
unsigned char RD(int i,int j){
#define D DIM
#define M m[(x+D+(d==0)-(d==2))%D][(y+D+(d==1)-(d==3))%D]
#define R rand()%D
#define B m[x][y]
return(i+j)?256-(BL(i,j))/2:0;
}
unsigned char GR(int i,int j){
#define A static int m[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
return RD(i,j);
}
unsigned char BL(int i,int j){
A;n;n++){x=R;y=R;if(B==1){f=1;for(d=0;d<4;d++){c[d]=M;f=f<c[d]?c[d]:f;}if(f>2){B=f-1;}else{++e%=4;d=e;if(!c[e]){B=0;M=1;}}}}}return m[i][j];
}
最后这张图来自 Eric Tressler :
这是由 logistic 映射得到的 Feigenbaum 分岔图。和刚才一样,对应的代码也巧妙地利用了宏定义来节省字符:
unsigned char RD(int i,int j){
#define A float a=0,b,k,r,x
#define B int e,o
#define C(x) x>255?255:x
#define R return
#define D DIM
R BL(i,j)*(D-i)/D;
}
unsigned char GR(int i,int j){
#define E DM1
#define F static float
#define G for(
#define H r=a*1.6/D+2.4;x=1.0001*b/D
R BL(i,j)*(D-j/2)/D;
}
unsigned char BL(int i,int j){
F c[D][D];if(i+j<1){A;B;G;a<D;a+=0.1){G b=0;b<D;b++){H;G k=0;k<D;k++){x=r*x*(1-x);if(k>D/2){e=a;o=(E*x);c[e][o]+=0.01;}}}}}R C(c[j][i])*i/D;
}
已阅。
牛13
惊现徐伟大神!
太可怕了
沙发板凳都被抢了555
打开ppm真心不容易啊~~
窃以为Manuel Kasten的代码看起来像Julia集
好吧我错了……貌似两个都是Mandelbrot……
咦?Mandelbrot是Martin那个啊。Manuel那个确实是Julia set
先赞一个。。慢慢研究
伟大的C++啊……
1024。
julia set 和 mandelbrot set的局部很像 我目测不出来 不过既然代码要节省字符 应该是julia set
好!!
PPM 图片可以使用 ps 打开。。。
大爱
真好,学习学习
unsigned char RD(int i,int j){
return (i+j)*2%256;
}
unsigned char GR(int i,int j){
return (i+j)*8%256;
}
unsigned char BL(int i,int j){
return (i+j)*16%256;
}
看起来还好吧。。
这张图看久了会动。
这是我的代码,略长,改了一下终于卡在了140字内。
unsigned char RD(int i,int j){
#define S(f) float w=sqrt(_sq(32-i%64)+_sq(32-j%64))/91,x=sqrt(_sq(i-512)+_sq(j-512))/724;return((f)*w/2048*x-w*x+1)*255;
S(2048-i-j)
}
unsigned char GR(int i,int j){
S(1024-i+j)
}
unsigned char BL(int i,int j){
S(1024+i-j)
}
大概是聚光灯效果,生成的图片我转成jpg放在了http://image15.poco.cn/mypoco/myphoto/20140815/06/1749428752014081506165601.jpg。
ppm文件可以用OnSeeView打开,挺好用的。
还挺不错的。赞!
原来代码可以这么美
看了看官网,这种作图方式似乎没有极限……
在遥远的未来这会不会成为新的图片压缩方式
不用未来啊,当下很多压缩算法就是用这种拟合的思想来实现的,比如JPEG2000
还有分形压缩等等
但是jpeg和矢量都会造成过度图片失真……感觉直接使用代码的方法应该是对这两种压缩的一个加强
之前还见到过用程序代码写视频的,真的就是像这样不靠资源文件的代码写的,而且运行得到的视频不是像这些图片那样看起来那么抽象。
unsigned char RD(int i,int j){
return BL(i,j)*2;
#define t(m,n)_sq(m)+_sq(n)
#define z(m,n)t(m*32-i,n*32-j)
#define q(m,n,k)if(z(m,n)<196)return k*255;if(z(m,n)<225)return 0;
}
unsigned char GR(int i,int j){
BL(i,j);}
unsigned char BL(int i,int j){
q(16,16,1)q(15,16,0)q(16,15,0)q(17,16,0)q(16,17,0)
return(i&31)&&(j&31)?80:0;
}
不错
少了个 return ,这是要下棋啊
数学真是神奇
我被震撼到了,实在是太酷了,每当看到这类惊艳的技能都感觉自己很失败啊。
叹为观止!
看呆了
很神奇。
想试试,请问该用什么软件
求教一下应该怎么执行这个?下了个mingw执行那个 g++ 命令,没有输出也没有生成文件。。
D:\MGW\bin>g++ test.cpp -std=c++11
D:\MGW\bin>mingw32-g++ test.cpp -std=c++11
g++ -o test test.cpp
windows下面生成 test.exe, 之后执行test.exe可以获取图片,查看图片可以使用GIMP
啊,有别的语言的版本么?
写了一个:
http://www.cnblogs.com/daishuo/p/3954422.html
感觉秒杀所有作品。
似乎官方那里有个作品是类似的模拟波纹……而且貌似还支持通过修改参数同时生成多组波纹
长见识
倒数第二个运行起来也太耗时间了吧,跑了十多分钟……
我还以为就我电脑配置差
其实是比较简单的东西。
“难以想象, Mandelbrot 分形图形居然可以只用这么一点代码画出:”,其算法项志刚图形学里有。
不懂图像图形学的会觉得多厉害似的。(关键还是用什么算法!)
果然疼的不是我一个……
http://tieba.baidu.com/p/1043526998(虽然不是1024×1024,没整成三个函数,也不到140字符,没吃几K内存。)
门外汉,如何运行以上代码,用什么工具,步骤?!
求指导如何制作如此高端的博客
叹为观止!
春季万物复苏,也是皮肤容易出现问题的时候,祛痘小妙招让你轻松祛 祛痘小妙招让你轻松祛痘 痘,对于 祛痘小妙招 青春期的少男少女来说,一定要知晓一些祛痘的妙招:
一、祛痘小妙招第一古方:莹肌如玉散。
目前中药里面祛痘的古方中最火的要算莹肌如玉散了,莹肌如玉散出自《普济方》,莹肌如玉散是以楮实、白芨、升麻、甘松、白芷、白丁香、砂仁、糯米末、皂角原料。将这些药材一起研磨成粉,混合均匀后,每天取少量涂脸,即可祛除痘痘,令颜面光洁如玉,因而得名莹肌如玉散。莹肌如玉散配方中不含绿豆,因 男士祛痘小妙招让你远离痘痘 为绿豆只清表面毒素,而不清皮下痘毒。而是采用了升麻等物,升麻不但能像绿豆一样有清热下火的效果,还能升发痘毒,所以祛痘之
快速祛痘小妙招一: 保持良好的生活习惯
1、注意脸部清洁。
祛痘小妙招
长痘痘很多时候都是因为油脂分泌过多堵塞毛孔造成的,因此做好清洁工作就十分必要啦!首先要选择弱酸性的肥皂或刺激性小的洗面奶,在低于 妙招让你轻松祛痘 体温的温水手中揉搓起泡后捧起来洗脸,轻柔的螺旋式按摩一分钟之后,即可用稍热(比体温高一点)的水冲洗干净了。每天洗2-3次,别忘了洗脸后上点化妆水,可以保湿并收缩毛孔哦!
2、保证充足的睡眠。
睡眠不足会导致肝功能下降,体内毒素无法及时排出,自然也就给 http://www.zoobocc.com 了痘痘疯长的机会。想要消灭他们最好在十一点之前睡觉,实在不行也别熬过十二点,而且要睡饱八小时哦!特别是第二
祛痘前,双手一定 祛痘 要清洗干净,最好还要用化妆水擦一次。洗脸后,切记不能用收敛性的化妆水,否则会让毛孔收缩,更难挤出痘痘。青春棒 藏宝教你怎么祛痘 一定要先用酒杯精或化妆水消毒干净,藏宝教你怎么祛痘。用青春棒挤痘痘时,藏宝教你怎么祛痘,所接触到范围较小,不会影响或伤害到痘痘旁边的正常皮肤。不过要记得挤 藏宝教你怎么祛痘 完一颗之后要用纸巾擦干净再进攻下一颗痘痘。若是忘记清洁,挤出来的痘痘留在上面的脓蔓延到下一颗痘痘会很不卫生哦。
Step 2
挤痘痘前,可以先在痘痘的地方擦柔软角质化妆水,这样挤起痘痘来更容易。而对付那些顽强的粉刺时,柔软性角质化妆水同样能起到软化作用,而且这样在挤的时候疼痛感会稍稍减弱些。
Step
来个太极八卦图,娱乐一下。
http://blog.csdn.net/xshbx/article/details/45245389
unsigned char RD(int i,int j){
// YOUR CODE HERE
#define LEFT (i < DIM/2)
#define C1 C(DIM/2, DIM/2, DIM/2)
#define C2 C(DIM/2, DIM/4, DIM/4)
return BL(i, j);
}
unsigned char GR(int i,int j){
// YOUR CODE HERE
#define C3 C(DIM/2, 3*DIM/4, DIM/4)
#define C4 C(DIM/2, DIM/4, DIM/16)
#define C5 C(DIM/2, 3*DIM/4, DIM/16)
return BL(i, j);
}
unsigned char BL(int i,int j){
// YOUR CODE HERE
#define C(x, y, r) (_sq(i – (x)) + _sq(j – (y)) < _sq((r)))
return !C1 ? 127 : C2 ? C4 ? 255 : 0 : C3 ? C5 ? 0: 255 : LEFT ? 0 :255;
}
unsigned char RD(int i,int j){
#define r(n)(rand()%n)
static char c[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];
}
您好,请问可以标明出处转载么?
我只看看不说话
太厲害了。表示已經震驚!
小姐兼职上门服务全套过夜可3p小姐, ΩΩ:147J 845 d8321,美女. 上 门 服 务 项 目 ,4小时两次(按摩、性交、乳交、口爆).6小时/次数不限(按摩、鸳鸯浴、口爆、乳交、性交、情趣变装).
小姐兼职上门服务全套过夜可3p小姐, ΩΩ:147J 845 d8321,美女. 上 门 服 务 项 目 ,4小时两次(按摩、性交、乳交、口爆).6小时/次数不限(按摩、鸳鸯浴、口爆、乳交、性交、情趣变装).
你好!本文可以转载吗?
您好,因为之前我们编辑没有弄清原出处以为是linux.cn的文章没有跟您申请授权就转载了,很抱歉,希望能与您取得联系,为我们的低级失误跟您说声对不起
QQ : 2594320540
手机:13122009555
邮箱:xiao.shikai@sdk.cn
对不起 给您造成麻烦
原来的话题已经[closed],我在论坛对这个话题做了延续
http://www.code-by.org/viewtopic.php?f=2&t=139&p=388#p388
样本代码中函数unsigned char RD(int,int);的声明丢失
unsigned char RD(int i ,int j) {
double x=i-512,y=-j-512;double k;x/=96;y/=96;k=(17*x*x-16*fabs(x)*y+17*y*y);return k<225.0?13.6f*k:0;
}
unsigned char GL(int i, int j) {
return 0;
}
unsigned char BR(int i, int j) {
return 0;
}
12个重叠的爱心,不算啥。
GR,BL,函数错了,虽然没什么关系