From: Zhihu, author: roasted eggplant
Link: https://www.zhihu.com/question/30262900
Here's what happened:
There is a big guy abroad who StackExchange
launched a Tweetable Mathematical Art
competition called.
Contestants need to C++
write three functions, RD, GR, and BL, that represent the three primary colors. Each function cannot exceed 140 characters. Each function will receive two integer parameters i and j (0 ≤ i, j ≤ 1023), and then need to return an integer between 0 and 255, representing the color value of the pixel located at (i, j).
For example, if RD(0, 0) and GR(0, 0) both return 0, but BL(0, 0) returns 255, then the pixel in the upper left corner of the image is blue.
The code written by the contestants will be inserted into the program below (I made some minor changes), and will eventually generate an image with a size of 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);
}
I have selected some of my favorite works and shared them with you below. First is a piece from Martin Büttner:
![7a70af3dc37e0ac02fda32029433271b.jpeg](https://img-blog.csdnimg.cn/img_convert/7a70af3dc37e0ac02fda32029433271b.jpeg)
Its code is as follows:
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);
}
Also from Martin Büttner:
![8ddad18c596d4cf4d206a6a6ad77ad2c.jpeg](https://img-blog.csdnimg.cn/img_convert/8ddad18c596d4cf4d206a6a6ad77ad2c.jpeg)
This is currently the number one work. Its code is as follows:
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];
}
The image below is still by Martin Büttner:
![0b76819afd605679d7d2e50d1f893824.jpeg](https://img-blog.csdnimg.cn/img_convert/0b76819afd605679d7d2e50d1f893824.jpeg)
It’s hard to imagine that Mandelbrot fractal graphics can be drawn with just this little code:
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 also made a picture of the Mandelbrot set. The difference from the previous one is that this picture depicts the result of a partial enlargement of the Mandelbrot set:
![2c2aad4fc3f4e22552d54a032416deaf.jpeg](https://img-blog.csdnimg.cn/img_convert/2c2aad4fc3f4e22552d54a032416deaf.jpeg)
Its code is as follows:
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);
}
This is another work by Manuel Kasten:
![bd9284b6557870788599d4335b95bd68.jpeg](https://img-blog.csdnimg.cn/img_convert/bd9284b6557870788599d4335b95bd68.jpeg)
The code that generates this picture is very interesting: the function relies on static variables to control the painting process, and the two parameters i and j are not used at all!
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;
}
This is from githubphagocyte:
![6a215358898e6f81264a04f75f15a270.jpeg](https://img-blog.csdnimg.cn/img_convert/6a215358898e6f81264a04f75f15a270.jpeg)
Its code is as follows:
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;
}
Here's another one from githubphagocyte:
![eae18c7f1ca5e26dd795c25fe0a0fee9.jpeg](https://img-blog.csdnimg.cn/img_convert/eae18c7f1ca5e26dd795c25fe0a0fee9.jpeg)
This is a picture obtained using the diffusion-limited aggregation model. It takes a lot of time to run the program. The code is very interesting: it cleverly uses macro definitions to break the boundaries between functions, and the word limit of the three pieces of code can be used together.
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];
}
This last picture is from Eric Tressler:
![642ac51d16b76ef342912ff06577d66c.jpeg](https://img-blog.csdnimg.cn/img_convert/642ac51d16b76ef342912ff06577d66c.jpeg)
This is the Feigenbaum bifurcation diagram obtained by logistic mapping. As before, the corresponding code also cleverly uses macro definitions to save characters:
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;
}
How about it? With just a few lines of code, you can draw such a gorgeous image. Do you have any wild ideas? You can copy the code above and give it a try!
--- EOF ---