LOLWUT: draw Schotter by Georg Nees.

This commit is contained in:
antirez 2018-09-12 11:16:07 +02:00
parent 2ead41e05b
commit eac2a79cf5

View File

@ -151,13 +151,14 @@ void lwDrawSquare(lwCanvas *canvas, int x, int y, float size, float angle) {
* into a circle of radius 1 has the side of length SQRT(2). This way
* size becomes a simple multiplication factor we can use with our
* coordinates to magnify them. */
size /= 1.4142;
size /= 1.4142135623;
size = round(size);
/* Compute the four points. */
float k = M_PI/4 + angle;
for (int j = 0; j < 4; j++) {
px[j] = sin(k) * size + x;
py[j] = cos(k) * size + y;
px[j] = round(sin(k) * size + x);
py[j] = round(cos(k) * size + y);
k += M_PI/2;
}
@ -166,6 +167,46 @@ void lwDrawSquare(lwCanvas *canvas, int x, int y, float size, float angle) {
lwDrawLine(canvas,px[j],py[j],px[(j+1)%4],py[(j+1)%4],1);
}
/* Schotter, the output of LOLWUT of Redis 5, is a computer graphic art piece
* generated by Georg Nees in the 60s. It explores the relationship between
* caos and order.
*
* The function creates the canvas itself, depending on the columns available
* in the output display and the number of squares per row and per column
* requested by the caller. */
lwCanvas *lwDrawSchotter(int console_cols, int squares_per_row, int squares_per_col) {
/* Calculate the canvas size. */
int canvas_width = console_cols*2;
int padding = 2;
float square_side = (float)(canvas_width-padding*2) / squares_per_row;
int canvas_height = square_side * squares_per_col + padding*2;
lwCanvas *canvas = lwCreateCanvas(canvas_width, canvas_height);
for (int y = 0; y < squares_per_col; y++) {
for (int x = 0; x < squares_per_row; x++) {
int sx = x * square_side + square_side/2 + padding;
int sy = y * square_side + square_side/2 + padding;
/* Rotate and translate randomly as we go down to lower
* rows. */
float angle = 0;
if (y > 1) {
float r1 = (float)rand() / RAND_MAX / squares_per_col * y;
float r2 = (float)rand() / RAND_MAX / squares_per_col * y;
float r3 = (float)rand() / RAND_MAX / squares_per_col * y;
if (rand() % 2) r1 = -r1;
if (rand() % 2) r2 = -r2;
if (rand() % 2) r3 = -r3;
angle = r1;
sx += r2*square_side/5;
sy += r3*square_side/5;
}
lwDrawSquare(canvas,sx,sy,square_side,angle);
}
}
return canvas;
}
/* Converts the canvas to an SDS string representing the UTF8 characters to
* print to the terminal in order to obtain a graphical representaiton of the
* logical canvas. The actual returned string will require a terminal that is
@ -196,6 +237,7 @@ sds lwRenderCanvas(lwCanvas *canvas) {
}
int main(void) {
#if 0
lwCanvas *c = lwCreateCanvas(80,80);
for (int i = 0; i < 40; i++) {
lwDrawPixel(c,i,i,1);
@ -203,6 +245,8 @@ int main(void) {
lwDrawLine(c,10,10,60,30,1);
lwDrawSquare(c,40,40,40,0.5);
lwDrawSquare(c,50,40,10,1);
#endif
lwCanvas *c = lwDrawSchotter(80,6,10);
sds rendered = lwRenderCanvas(c);
printf("%s\n", rendered);
}