Skip to content

Instantly share code, notes, and snippets.

@SakuraSa
Created November 16, 2020 15:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SakuraSa/9d8fa0d01e54806d0230a0fdac02b3fb to your computer and use it in GitHub Desktop.
Save SakuraSa/9d8fa0d01e54806d0230a0fdac02b3fb to your computer and use it in GitHub Desktop.

mandelbrot

build & run

make clean && make && ./mandelbrot

command

  • awsd * for moving camera;
  • qe * for zoom in/out;
  • QE * for rotate camera.
CC=cc
LIBS=-lncurses -lm
CFLAGS=-Wall -O3
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
TARGET=mandelbrot
all: ${OBJ}
${CC} $(CFLAGS) $(LIBS) $^ -o ${TARGET}
%.o: %.c
${CC} ${CFLAGS} -c $< -o $@
clean:
rm -f *.o ${TARGET}
#include <curses.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define PI 3.1415926538
static const char tone[] = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ";
static const int tone_size = 70;
char get_tone(int esc, int limit) {
return tone[tone_size * (limit - esc) / limit];
}
int escape(double x, double y, int limit, double range) {
double a=0, b=0, step;
for(step=0;step<limit-1 && a*a+b*b<range;step++) {
double tmp = a*a - b*b + x;
b = 2*a*b + y;
a = tmp;
}
return step;
}
int main(void) {
WINDOW * mainwin;
if ((mainwin = initscr()) == NULL) {
fprintf(stderr, "Error initialising ncurses.\n");
exit(EXIT_FAILURE);
}
cbreak();
noecho();
// nodelay(mainwin, TRUE);
int key = -1;
double cx = -0.75, cy = 0,
scalar_x=0.037, scalar_y=scalar_x*1.5,
angle = 0;
double mv_x = 0.15, mv_y = 0.3, mv_a = PI / 6, mv_z = 1.3;
int limit = 255;
double range = 1000.0;
char title[1024];
do {
// get screen size
int win_x, win_y;
getmaxyx(mainwin, win_y, win_x);
// move
switch (key) {
case 65:
case 'w':
cx += win_x * scalar_x * mv_x * sin(angle);
cy -= win_y * scalar_y * mv_y * cos(angle);
break;
case 66:
case 's':
cx -= win_x * scalar_x * mv_x * sin(angle);
cy += win_y * scalar_y * mv_y * cos(angle);
break;
case 68:
case 'a':
cx -= win_x * scalar_x * mv_x * cos(angle);
cy -= win_y * scalar_y * mv_y * sin(angle);
break;
case 67:
case 'd':
cx += win_x * scalar_x * mv_x * cos(angle);
cy += win_y * scalar_y * mv_y * sin(angle);
break;
case 'q':
scalar_x *= mv_z;
scalar_y *= mv_z;
break;
case 'e':
scalar_x /= mv_z;
scalar_y /= mv_z;
break;
case 'Q':
angle -= mv_a;
if (angle < 0) angle += PI * 2;
break;
case 'E':
angle += mv_a;
if (angle > PI * 2) angle -= PI * 2;
break;
}
// draw
double sn = sin(angle), cs = cos(angle);
for (int y=0;y<win_y;y++) {
move(y, 0);
for (int x=0;x<win_x;x++) {
double oy = (y - win_y/2) * scalar_y;
double ox = (x - win_x/2) * scalar_x;
double py = cy + ox * sn + oy * cs;
double px = cx + ox * cs - oy * sn;
int esc = escape(px, py, limit, range);
addch(get_tone(esc, limit));
}
}
int deg = (int) (angle/PI*180);
sprintf(title, "X:%.2f Y:%.2f Z:%.8f A:%3d", cx, cy, scalar_x, deg);
mvaddstr(0, 0, title);
refresh();
key = getch();
} while (TRUE);
delwin(mainwin);
endwin();
refresh();
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment