commit 588e168273ac602804257bd45a97c3c50221358c Author: Sebastián Santisi Date: Tue Jun 20 11:54:34 2023 -0300 Initial commit diff --git a/contar.c b/contar.c new file mode 100644 index 0000000..e424a97 --- /dev/null +++ b/contar.c @@ -0,0 +1,13 @@ +#include + +int main(void) { + long double z = 0.179; + int i = 0; + while(z > 1e-20) { + z *= 0.99; + i++; + } + + printf("%d %.1fs\n", i, i / 24.); + return 0; +} diff --git a/mandelbrot.c b/mandelbrot.c new file mode 100644 index 0000000..576332c --- /dev/null +++ b/mandelbrot.c @@ -0,0 +1,72 @@ +#include +#include + +#define MAX_ITER 80 +#define ANCHO 640 +#define ALTO 480 +#define FOV 90 +#define PI 3.14159265358979323846 + +typedef struct { + double r, g, b; +} color_t; + +#define LIM(c) (int)(((c) < 1 ? (c) : 1) * 255) + +void color_imprimir(color_t c) { + printf("%d %d %d", LIM(c.r), LIM(c.g), LIM(c.b)); +} + +color_t computar_intensidad(color_t ambiente, double x0, double y0) { + x0 /= ANCHO / 4; + y0 /= ALTO / 4; + double x = 0; + double y = 0; + int n = 0; + while(x*x + y*y <= 4 && n < MAX_ITER) { + double xtemp = x*x - y*y + x0; + y = 2*x*y + y0; + x = xtemp; + n++; + } + + if(n == MAX_ITER) + return ambiente; + + //float h = (n + 1 - log(log2(sqrt(x*x+y*y)))) / MAX_ITER * 360; + float h = n * 360.0 / MAX_ITER; + float xx = (1 - fabs(fmodf(h / 60.0, 2) - 1)); + float r = 0, g = 0, b = 0; + + if(h < 60) + r = 1, g = xx; + else if(h < 120) + g = 1, r = xx; + else if(h < 180) + g = 1, b = xx; + else if(h < 240) + b = 1, g = xx; + else if(h < 300) + b = 1, r = xx; + else + r = 1, b = xx; + + return (color_t){r, g, b}; +} + + +int main(void) { + color_t ambiente = {.05, .05, .05}; + + printf("P3\n%d %d\n255\n", ANCHO, ALTO); + + float vz = ANCHO / 2 / tan(FOV/ 2 * PI / 180); + + for(int vy = ALTO / 2; vy > - ALTO / 2; vy--) + for(int vx = - ANCHO / 2; vx < ANCHO / 2; vx++) { + color_imprimir(computar_intensidad(ambiente, vx, vy)); + putchar('\n'); + } + + return 0; +} diff --git a/mandelbrot_main.c b/mandelbrot_main.c new file mode 100644 index 0000000..d0f5153 --- /dev/null +++ b/mandelbrot_main.c @@ -0,0 +1,188 @@ +#include +#include +#include + +#include + +#define VENTANA_ANCHO 300 +#define VENTANA_ALTO 200 +#define ANCHO VENTANA_ANCHO +#define ALTO VENTANA_ALTO +#define MAX_ITER 10000 +#define JUEGO_FPS 10 + +static double time_in_ms(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0; +} + +//long double xc = - 1.7400623825793398724575; // Derecha: Achicar +//long double yc = 0.0281753397792109; // Abajo: Achicar + +//long double xc = -1.740119020442992652289958266376L; +//long double yc = 0.028019209975637676263081582255L; +//long double xc = 0.264226442163892496529931097626331393L, yc = 0.002572261418806922467217290773078275L; // Video 2 +long double xc = -1.749900374662927212679117139337847675L, yc = 0.000000000002454985822810237255224056L; + +uint32_t computar_intensidad(long double x0, long double y0, long double zoom) { + //x0 = x0 * zoom - 1.7400623825793398724575; // Derecha: Achicar + //y0 = y0 * zoom + 0.0281753397792111; // Abajo: Achicar + x0 = x0 * zoom + xc; // Derecha: Achicar + y0 = y0 * zoom + yc; // Abajo: Achicar + //x0 = x0 * zoom - 1.78; // Derecha: Achicar + //y0 = y0 * zoom + 0.0; // Abajo: Achicar + long double x = 0; + long double y = 0; + int n = 0; + while(x*x + y*y <= 4 && n < MAX_ITER) { + long double xtemp = x*x - y*y + x0; + y = 2*x*y + y0; + x = xtemp; + n++; + } + + if(n == MAX_ITER) + return 0; + + //float h = (n + 1 - log(log2(sqrt(x*x+y*y)))) / MAX_ITER * 360; + float h = (int)(n * 360.0 / 100) % 360; + float xxx = (1 - fabs(fmodf(h / 60.0, 2) - 1)); + uint8_t xx = (xxx < 1 ? xxx : 1) * 255; + uint8_t r = 0, g = 0, b = 0; + + if(h < 60) + r = 255, g = xx; + else if(h < 120) + g = 255, r = xx; + else if(h < 180) + g = 255, b = xx; + else if(h < 240) + b = 255, g = xx; + else if(h < 300) + b = 255, r = xx; + else + r = 255, b = xx; + + return (r << 24) | (g << 16) | (b << 8); +} + + +int main() { + SDL_Init(SDL_INIT_VIDEO); + + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Event event; + + //SDL_CreateWindowAndRenderer(1000, 800, 0, &window, &renderer); + window = SDL_CreateWindow("Mandelbrot", 0, 0, ANCHO, ALTO, 0); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); +// SDL_SetWindowTitle(window, "Mandelbrot"); +int width, height; + SDL_Texture * texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STATIC, ANCHO, ALTO); +// SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, ANCHO, ALTO); + uint32_t canvas[ALTO * ANCHO]; + + int dormir = 0; + + // BEGIN código del alumno + long double zoom = 0.179; + double factor = 0.99; + bool simulate = true; + // END código del alumno + + unsigned int ticks = SDL_GetTicks(); + while(1) { + if(SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) + break; + // BEGIN código del alumno + if (event.type == SDL_KEYDOWN) { + // Se apretó una tecla + switch(event.key.keysym.sym) { + case SDLK_UP: + yc += zoom*5; + break; + case SDLK_DOWN: + yc -= zoom*5; + break; + case SDLK_RIGHT: + xc += zoom*5; + break; + case SDLK_LEFT: + xc -= zoom*5; + break; + case SDLK_PLUS: + factor /= 1.01; + break; + case SDLK_MINUS: + factor *= 1.01; + break; + } + } + else if (event.type == SDL_KEYUP) { + // Se soltó una tecla + switch(event.key.keysym.sym) { + case SDLK_SPACE: + simulate = ! simulate; + case SDLK_UP: + break; + case SDLK_DOWN: + break; + case SDLK_RIGHT: + break; + case SDLK_LEFT: + break; + } + } + // END código del alumno + continue; + } + + // BEGIN código del alumno + double begin = time_in_ms(); + int i = 0; + + if(zoom < 1e-20) + zoom = 0.179; + + if(simulate) + zoom *= factor; + + for(int vy = ALTO / 2; vy > - ALTO / 2; vy--) + for(int vx = - ANCHO / 2; vx < ANCHO / 2; vx++) { + canvas[i++] = computar_intensidad(vx, vy, zoom); + } +printf("%f %.5Le\nlong double xc = %.36LfL, yc = %.36LfL;\n", time_in_ms() - begin, zoom, xc, yc); + + // Implementar imagen_a_textura() cuanto antes! + + // END código del alumno + SDL_UpdateTexture(texture, NULL, canvas, ANCHO * sizeof(uint32_t)); +SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); + ticks = SDL_GetTicks() - ticks; + if(dormir) { + SDL_Delay(dormir); + dormir = 0; + } + else if(ticks < 1000 / JUEGO_FPS) + SDL_Delay(1000 / JUEGO_FPS - ticks); + else + printf("Perdiendo cuadros\n"); + ticks = SDL_GetTicks(); + } + + // BEGIN código del alumno + // No tengo nada que destruir. + // END código del alumno + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + + SDL_Quit(); + return 0; +} + diff --git a/mandelbrot_png.c b/mandelbrot_png.c new file mode 100644 index 0000000..5349624 --- /dev/null +++ b/mandelbrot_png.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +#include + +#define PREFIX "img-" + +#define VENTANA_ANCHO 1920 +#define VENTANA_ALTO 1080 +#define ANCHO VENTANA_ANCHO +#define ALTO VENTANA_ALTO +#define MAX_ITER 500 + +//long double xc = -1.740119020442992652289958266376L; +//long double yc = 0.028019209975637676263081582255L; +long double xc = 0.264226442163892496529931097626331393L, yc = 0.002572261418806922467217290773078275; + +uint32_t computar_intensidad(long double x0, long double y0, long double zoom) { + //x0 = x0 * zoom - 1.7400623825793398724575; // Derecha: Achicar + //y0 = y0 * zoom + 0.0281753397792111; // Abajo: Achicar + x0 = x0 * zoom + xc; // Derecha: Achicar + y0 = y0 * zoom + yc; // Abajo: Achicar + //x0 = x0 * zoom - 1.78; // Derecha: Achicar + //y0 = y0 * zoom + 0.0; // Abajo: Achicar + long double x = 0; + long double y = 0; + int n = 0; + while(x*x + y*y <= 4 && n < MAX_ITER) { + long double xtemp = x*x - y*y + x0; + y = 2*x*y + y0; + x = xtemp; + n++; + } + + if(n == MAX_ITER) + return 0; + + //float h = (n + 1 - log(log2(sqrt(x*x+y*y)))) / MAX_ITER * 360; + //float h = n * 360.0 / MAX_ITER; + float h = (int)(n * 360.0 / 50) % 360; + float xxx = (1 - fabs(fmodf(h / 60.0, 2) - 1)); + uint8_t xx = (xxx < 1 ? xxx : 1) * 255; + uint8_t r = 0, g = 0, b = 0; + + if(h < 60) + r = 255, g = xx; + else if(h < 120) + g = 255, r = xx; + else if(h < 180) + g = 255, b = xx; + else if(h < 240) + b = 255, g = xx; + else if(h < 300) + b = 255, r = xx; + else + r = 255, b = xx; + + return (r << 24) | (g << 16) | (b << 8); +} + + +int main() { + long double zoom = 0.179; + double factor = 0.99; + + size_t n = 0; + for(double z = zoom; z >= 1e-20; z *= factor) + n++; + + double *zooms = malloc(n * sizeof(double)); + zooms[0] = zoom; + for(size_t i = 1; i < n; i++) + zooms[i] = zooms[i - 1] * factor; + + #pragma omp parallel for schedule(dynamic) + for(int i = 0; i < n; i++) { + printf("%d\n", i); + + char aux[100]; + sprintf(aux, "%s%05d.ppm", PREFIX, i); + FILE *f = fopen(aux, "wt"); + fprintf(f, "P3\n%d %d\n255\n", ANCHO, ALTO); + + + for(int vy = ALTO / 2; vy > - ALTO / 2; vy--) + for(int vx = - ANCHO / 2; vx < ANCHO / 2; vx++) { + uint32_t c = computar_intensidad(vx, vy, zooms[i]); + fprintf(f, "%d %d %d\n", c >> 24, (c >> 16) & 0xFF, (c >> 8) & 0xFF); + } + fclose(f); + + sprintf(aux, "convert %s%05d.ppm %s%05d.png; rm %s%05d.ppm", PREFIX, i, PREFIX, i, PREFIX, i); + system(aux); + } + + system("ffmpeg -y -framerate 24 -i " PREFIX "%05d.png -c:v libx264 -crf 0 output.mp4"); + + return 0; +} +