¡Nunca te puedes imaginar que el lenguaje C pueda jugar así!

Haga clic en "Uncle Wheat" arriba y seleccione "Cuenta pública superior/estrella"

Productos secos de bienestar, entregados lo antes posible.

Hola a todos, soy Mai, y es un feliz viernes. Algunas personas dicen que los programadores son artistas. Veamos qué obras se pueden dibujar en lenguaje C.

6421b43e791c40efec89d1c570e03d08.png

Sabemos que para mostrar el color en una computadora, generalmente se describe mediante tres números enteros en el rango de 0-255, R, G y B.

5d9dfac927d11480e8eb0e6accf52978.png

Este punto, incluso si no está involucrado en el trabajo de desarrollo del lado del cliente relacionado con la interacción de la interfaz, debe saberlo.

Es decir, el color de cualquier píxel que veas en pantalla se puede representar con tres valores enteros de RGB.

Luego hay una pregunta interesante : si dejas que el programa rellene automáticamente cada píxel, ¿qué tipo de pintura será al final?

Recientemente, vi un tema tan interesante sobre Zhihu. Después de leerlo, es realmente asombroso. No es tan bueno como la música de todos. Quiero compartirlo con todos.

Aquí está la cosa:

Un tipo grande del extranjero lanzó una competencia llamada Tweetable Mathematical Art en StackExchange.

Los concursantes deben escribir tres funciones, RD, GR y BL, que representan los tres colores primarios, en C/C++, y cada función no puede exceder los 140 caracteres. Cada función recibe dos parámetros enteros i y j (0 ≤ i, j ≤ 1023), y luego debe devolver un número entero entre 0 y 255, que representa el valor de color del píxel ubicado en (i, j).

Por ejemplo, si RD(0, 0) y GR(0, 0) devuelven 0, pero BL(0, 0) devuelve 255, entonces el píxel superior izquierdo de la imagen es azul.

El código escrito por el concursante se insertará en el siguiente programa (hice algunos cambios menores), que eventualmente generará una imagen de tamaño 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);
}

He seleccionado algunas de mis obras favoritas para compartir con ustedes a continuación. Primero, una pieza de Martin Büttner:

336d3629cf3fbc555b24623ec8cbf538.png

Su código es el siguiente:

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

Esto también es de Martin Büttner:

fdf6f3ea81680fd4bc5e25a73ba710d8.png

Este es actualmente el trabajo No. 1, y su código es el siguiente:

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

La imagen de abajo todavía es de Martin Büttner:

f0f57c951bffc8c4685348462ca57cb6.png

Es difícil imaginar que los gráficos fractales de Mandelbrot se puedan dibujar con solo este pequeño código:

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 también hizo una imagen del conjunto de Mandelbrot que, a diferencia de ahora, muestra el conjunto de Mandelbrot ampliado en alguna parte:

2c10895da0d16d6b839ff1c2b3235d7e.png

Su código es el siguiente:

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

He aquí otra obra de Manuel Kasten:

bf4bf24eec752a43935da0b65a2603fa.png

El código que genera esta imagen es interesante: la función se basa en variables estáticas para controlar el proceso de pintura, ¡y los dos parámetros i y j no se usan en absoluto!

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

Aquí está el trabajo de githubphagocyte:

7b103096a693725f5ea10964e5129286.png

Su código es el siguiente:

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

Aquí hay otro trabajo de githubphagocyte:

9d079bd56c570c186090cd5a838383e5.png

Esta es una imagen obtenida utilizando el modelo de agregación de difusión limitada, y el programa requiere mucho tiempo para ejecutarse.

El código es interesante: el uso inteligente de definiciones de macros rompe los límites entre funciones y funciones, y el límite de palabras de tres piezas de código se puede usar juntas.

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

La última foto es de Eric Tressler:

72d0bfbcf7fa299b2c9f01bdcfcbe529.png

Este es el diagrama de bifurcación de Feigenbaum obtenido del mapa logístico. Como antes, el código correspondiente hace un uso inteligente de las definiciones de macros para guardar caracteres:

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

¿Qué tal, con solo unas pocas líneas de código, puedes dibujar una imagen tan hermosa? ¿Tienes alguna idea que te abra la mente? ¡Puedes copiar el código anterior y probarlo!

Autor: berenjena quemada

Direccion original:www.zhihu.com/question/30262900/answer/48741026


Los derechos de autor pertenecen al autor original, si hay alguna infracción, comuníquese para eliminarlo.

-- El fin --

Recomendado en el pasado

¡Buen proyecto, no lo mantengas en privado! Ruedas de código abierto para el desarrollo de microcontroladores

¿El desarrollo de MCU nunca usa estructuras de datos?

Después de que la persona que escribió el código incorrecto se fue...

Estoy perplejo, ¿cuál es el papel del final de la enumeración del lenguaje C?

Únase al grupo de intercambio de tecnología integrada y progresen juntos

Haz clic en la tarjeta de arriba para seguirme

f8597695d1d375ec8216e9b8d0785921.png

Todo lo que pediste se ve bien , lo tomo en serio ya que me gusta

Supongo que te gusta

Origin blog.csdn.net/u010632165/article/details/123437316
Recomendado
Clasificación