Last active
April 26, 2021 03:10
-
-
Save louisswarren/aac24e1b3106f8c13b8cf3247393624f to your computer and use it in GitHub Desktop.
Menger sponge sides
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.PHONY: default | |
default: menger8.png | |
%.png: %.pbm | |
convert $^ $@ | |
menger%.pbm: menger | |
./$^ $* > $@ | |
menger%.svg: menger.py | |
python3 $^ $* > $@ | |
menger: menger.c | |
.PHONY: clean | |
clean: | |
rm -f menger *.png *.svg |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
long three_power(long n) | |
{ | |
long i; | |
long x = 1; | |
for (i = 0; i < n; ++i) | |
x *= 3; | |
return x; | |
} | |
int | |
main(int argc, char *argv[]) | |
{ | |
int n = 4; | |
long i, j, k, x, y; | |
long dim; | |
if (argc > 1 && !(n = atoi(argv[1]))) { | |
fprintf(stderr, "Usage: menger <level>\n"); | |
return 1; | |
} | |
dim = three_power(n); | |
if (dim > ((size_t) -1) / dim) { | |
fprintf(stderr, "Dimension too large.\n"); | |
return 1; | |
} | |
printf("P1\n%ld %ld\n", dim, dim); | |
/* VLA trick */ | |
char (*board)[dim] = malloc(dim * dim); | |
memset(board, '1', dim * dim); | |
memset(&board[dim/3][dim/3], '0', dim / 3); | |
for (i = 0; i < dim/3; ++i) { | |
for (j = 0; j < dim/3; ++j) { | |
for (k = 0; k < n; ++k) { | |
x = three_power(k); | |
if ((x <= i % (3 * x) && i % (3 * x) < 2 * x) | |
&& (x <= j % (3 * x) && j % (3 * x) < 2 * x)) { | |
board[i][j] = '0'; | |
break; | |
} | |
} | |
} | |
} | |
for (i = 0; i < dim/3; ++i) { | |
fwrite(board[i], dim/3, 1, stdout); | |
fwrite(board[i], dim/3, 1, stdout); | |
fwrite(board[i], dim/3, 1, stdout); | |
} | |
for (i = 0; i < dim/3; ++i) { | |
fwrite(board[i], dim/3, 1, stdout); | |
fwrite(board[dim/3] + dim/3, dim/3, 1, stdout); | |
fwrite(board[i], dim/3, 1, stdout); | |
} | |
for (i = 0; i < dim/3; ++i) { | |
fwrite(board[i], dim/3, 1, stdout); | |
fwrite(board[i], dim/3, 1, stdout); | |
fwrite(board[i], dim/3, 1, stdout); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
import sys | |
from svg import * | |
def log(*a, **k): | |
print(*a, **k, file=sys.stderr) | |
def svg_square_centred(p, size, *args, **kwargs): | |
return svg_rect((p[0] - size/2, p[1] - size/2), size, size, *args, **kwargs) | |
# Basic header | |
svg_header() | |
svg_open(width=1200, height=1200, x_bias=-150, y_bias=-150, xw=300, yh=300) | |
svg_square_centred((0,0), 300) | |
def menger(n, p=(0,0), k=1): | |
unit = 300/3**k | |
svg_square_centred(p, unit, fill='white') | |
if k < n: | |
menger(n, (p[0] - unit, p[1] - unit), k + 1) | |
menger(n, (p[0] , p[1] - unit), k + 1) | |
menger(n, (p[0] + unit, p[1] - unit), k + 1) | |
menger(n, (p[0] - unit, p[1] ), k + 1) | |
menger(n, (p[0] + unit, p[1] ), k + 1) | |
menger(n, (p[0] - unit, p[1] + unit), k + 1) | |
menger(n, (p[0] , p[1] + unit), k + 1) | |
menger(n, (p[0] + unit, p[1] + unit), k + 1) | |
if len(sys.argv) >= 2: | |
menger(int(sys.argv[1])) | |
else: | |
menger(4) | |
# Footer | |
svg_close() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def xml(tag, _xml_tag_is_a_singleton=True, **options): | |
s = f'<{tag}' | |
kw_attrib = lambda x: x.replace('_', '-') | |
if options: | |
s += ' ' | |
s += ' '.join(f'{kw_attrib(k)}="{str(v)}"' for k, v in options.items()) | |
if _xml_tag_is_a_singleton: | |
s += ' />' | |
else: | |
s += '>' | |
print(s) | |
def xml_open(*args, **kwargs): | |
xml(*args, **kwargs, _xml_tag_is_a_singleton=False) | |
def xml_close(tag): | |
print(f'</{tag}>') | |
def svg_header(): | |
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>' | |
def svg_open(width, height, x_bias, y_bias, xw, yh): | |
vb = f'{x_bias} {y_bias} {xw} {yh}' | |
ns = 'http://www.w3.org/2000/svg' | |
xml_open('svg', width=width, height=height, viewBox=vb, xmlns=ns) | |
def svg_close(): | |
xml_close('svg') | |
def svg_poly(*points, **opts): | |
point_str = ' '.join(f'{x},{y}' for x, y in points) | |
xml('polyline', points=point_str, **opts) | |
def svg_circle(point, radius, **opts): | |
xml('circle', cx=point[0], cy=point[1], r=radius, **opts) | |
def svg_line(p1, p2, **opts): | |
xml('line', x1=p1[0], y1=p1[1], x2=p2[0], y2=p2[1], **opts) | |
def svg_rect(p, width, height, x_radius=0, y_radius=0, **opts): | |
xml('rect', x=p[0], y=p[1], width=width, height=height, | |
rx=x_radius, ry=y_radius, **opts) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To freeze your computer, try
make menger8.png