#include #include "studio/bitmap.h" #include "studio/geometry.h" #include "studio/movie/movie.h" #include "studio/pen.h" #include "studio/random.h" #include "triangles.h" static struct bitmap *draw(const struct vertices triangle, const matrix composition, struct bitmap * const image) { assert(image); assert(image->depth == grey8); const colour paper = image->clear; const colour ink = {.grey[level] = 255 - paper.grey[level]}; const double pressure = 1.0; const struct vertices point = { .A = transform(triangle.A, composition), .B = transform(triangle.B, composition), .C = transform(triangle.C, composition) }; return line(line(line( clearbitmap(image, paper), point.A, point.B, ink, pressure), point.B, point.C, ink, pressure), point.C, point.A, ink, pressure ); } static struct movie animate(struct movie video, struct bitmap * const image, const matrix composition, const struct vertices from, const struct vertices to, const unsigned frames) { const struct vertices transition = { .A = divide(subtract(from.A, to.A), scalar(frames)), .B = divide(subtract(from.B, to.B), scalar(frames)), .C = divide(subtract(from.C, to.C), scalar(frames)) }; for (unsigned frame = 0; frame < frames; ++frame) { video = rendermovie(video, draw((struct vertices){ .A = add(from.A, multiply(transition.A, scalar(frame))), .B = add(from.B, multiply(transition.B, scalar(frame))), .C = add(from.C, multiply(transition.C, scalar(frame))) }, composition, image)); } return video; } int video(void * const output, int objects) { (void)output; if (objects < 0) return 0; struct movie video = openmovie((struct movie){ .title = "triangles", .width = 1280, .height = 720, .framerate = 60, .destination = webm, .webm.filename = "triangles.webm" }); struct bitmap *image = createbitmap((struct bitmap){ .width = video.width, .height = video.height, .depth = grey8, .clear.grey[level] = 255 }); const vector size = scalar(min(video.width, video.height)); const matrix composition = scale(size, translate( divide(subtract(size, (vector){.x = video.width, .y = video.height}), scalar(2.0)), identity() )); unsigned shapes[(90 * 90) - 1] = {0}; for (unsigned number = 0; number < count(shapes); ++number) { const unsigned shuffle = any(number); shapes[number] = shapes[shuffle]; shapes[shuffle] = number; } objects = (objects > 0 && objects < count(shapes)) ? objects : count(shapes); const unsigned duration = (((unsigned)video.framerate + 7) / 8) * 8; const struct vertices beginning = triangle(shape(shapes[0])); struct vertices object = beginning; for (size_t number = 1; number < objects; ++number) { const struct vertices next = triangle(shape(shapes[number])); video = animate(video, image, composition, object, next, duration); object = next; } video = closemovie(animate(video, image, composition, object, beginning, duration)); image = destroybitmap(image); return 1; }