Click on "Uncle Wheat" above and select "Top/Star Public Account"
Welfare dry goods, delivered as soon as possible
Hello everyone, I'm Mai, and it's a happy Friday. Some people say that programmers are artists. Let's see what works can be drawn in C language.
We know that to display color in a computer, it is generally described by three integers in the range of 0-255, R, G, and B.
This point, even if you are not engaged in front-end, client-side development work related to interface interaction, you should know.
That is to say, the color of any pixel you see on the screen can be represented by three integer values of RGB.
Then there is an interesting question : if you let the program automatically fill in each pixel, what kind of painting will it be in the end?
Recently, I saw such an interesting topic on Zhihu. After reading it, it's really amazing. It's not as good as everyone's music. I want to share it with everyone.
Here's the thing:
A big guy from abroad launched a competition called Tweetable Mathematical Art on StackExchange.
Contestants need to write three functions, RD, GR, and BL, which represent the three primary colors, in C/C++, and each function cannot exceed 140 characters. Each function receives two integer parameters i and j (0 ≤ i, j ≤ 1023), and then needs 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 upper-leftmost pixel of the image is blue.
The code written by the contestant will be inserted into the following program (I made some minor changes), which will eventually generate an image of size 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);
}
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);
}
This is also from Martin Büttner:
This is currently the No. 1 work, and 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:
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, which, unlike just now, depicts the Mandelbrot set zoomed in somewhere:
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);
}
Here is another work by Manuel Kasten:
The code that generates this picture is 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;
}
Here is the work from githubphagocyte:
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 work from githubphagocyte:
This is a picture obtained using the diffusion-limited aggregation model, and the program takes a lot of time to run.
The code is interesting: the clever use of macro definitions breaks the boundaries between functions and functions, and the word limit of 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];
}
The last picture is from Eric Tressler:
This is the Feigenbaum bifurcation diagram obtained from the logistic map. As before, the corresponding code makes clever use of 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, just a few lines of code, you can draw such a gorgeous image, do you have any ideas that open your mind, you can copy the above code and try it!
Author: burnt eggplant
Original address:www.zhihu.com/question/30262900/answer/48741026
The copyright belongs to the original author, if there is any infringement, please contact to delete it.
—— The End ——
Recommended in the past
Good project, don't keep it private! Open source wheels for microcontroller development
MCU development never uses data structures?
After the person who wrote the bad code left...
I'm stumped, what is the role of C language enumeration end?
Join the embedded technology exchange group and make progress together
Click on the card above to follow me
Everything you ordered looks good , I take it seriously as I like it