Skip to content

Instantly share code, notes, and snippets.

@h4k1m0u
Created July 27, 2024 09:06
Show Gist options
  • Save h4k1m0u/10ea48fd33d85032561ba460405bf28e to your computer and use it in GitHub Desktop.
Save h4k1m0u/10ea48fd33d85032561ba460405bf28e to your computer and use it in GitHub Desktop.
Draw a Sierpinski triangle using Chaos game
#include <gd.h>
// C doesn't allow variable length arrays (even using a constant)
#define N_CORNERS 3
typedef struct {
int x;
int y;
} Point;
/**
* Draw a Sierpinski triangle using Chaos game
* - Js implementation: https://www.youtube.com/watch?v=7gNzMtYo9n4
* - Description: https://mathigon.org/course/fractals/sierpinski
* - GD documentation: https://libgd.github.io/manuals/2.1.1/files/preamble-txt.html
*
* How to build & run:
* $ gcc -lgd sierpinski.c -o sierpinski
* $ ./sierpinski image.png 500 500
*/
int main(int argc, char** argv) {
if (argc != 4) {
printf("USAGE: %s IMAGE WIDTH HEIGHT\n", argv[0]);
return 1;
}
const char* filename = argv[1];
FILE* file = fopen(filename, "wb");
// rgb image
const int WIDTH = atoi(argv[2]);
const int HEIGHT = atoi(argv[3]);
gdImagePtr image = gdImageCreateTrueColor(WIDTH, HEIGHT);
// colors
const int RED = gdTrueColor(0xff, 0, 0);
const int GREEN = gdTrueColor(0, 0xff, 0);
const int BLUE = gdTrueColor(0, 0, 0xff);
int colors[N_CORNERS] = { RED, GREEN, BLUE };
// three triangle corners
Point corner0 = { WIDTH / 2, 0 };
Point corner1 = { 0, HEIGHT };
Point corner2 = { WIDTH - 1, HEIGHT - 1 };
Point corners[N_CORNERS] = { corner0, corner1, corner2 };
for (size_t i_corner = 0; i_corner < N_CORNERS; ++i_corner) {
gdImageSetPixel(image, corners[i_corner].x, corners[i_corner].y, colors[i_corner]);
}
/* chaos game */
const int N_ITERS = 100000;
Point point = { rand() % WIDTH, rand() % HEIGHT };
for (size_t i_iter = 0; i_iter < N_ITERS; ++i_iter) {
int i_corner = rand() % N_CORNERS;
Point corner = corners[i_corner];
Point avg = { (point.x + corner.x) / 2, (point.y + corner.y) / 2 };
point = avg;
gdImageSetPixel(image, point.x, point.y, colors[i_corner]);
}
gdImagePng(image, file);
// free assets
fclose(file);
gdImageDestroy(image);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment