Skip to content

Instantly share code, notes, and snippets.

@AndreVallestero
Created January 28, 2025 23:00
Show Gist options
  • Save AndreVallestero/ead6b0b09e9e3277c868f1ca841168d0 to your computer and use it in GitHub Desktop.
Save AndreVallestero/ead6b0b09e9e3277c868f1ca841168d0 to your computer and use it in GitHub Desktop.
Rohmbic Dodecahedron Cross Section
import numpy as np
import math
from PIL import Image, ImageDraw
import cv2
PPI = 100
PPMM = round(PPI / 25.4)
PLATE_WIDTH = 220 # ender 3 220mm
BUILD_HEIGHT = 150 #250 # ender 3 250mm
VID_DIM = (PLATE_WIDTH * PPMM, PLATE_WIDTH * PPMM)
VID_LENGTH = 10 # seconds
VID_FPS = 30
VID_FRAMES = VID_LENGTH * VID_FPS
LAYER_HEIGHT = BUILD_HEIGHT / VID_FRAMES
TILE_RADIUS = 25 # mm
TILE_HEIGHT = TILE_RADIUS * 1.5
TILE_HALF_OFFSET = TILE_RADIUS * 3 ** .5 / 2
TILE_WIDTH = TILE_HALF_OFFSET * 2
video = cv2.VideoWriter("video.mp4", cv2.VideoWriter_fourcc(*"mp4v"), VID_FPS, VID_DIM)
for i in range(VID_FRAMES):
# 6 phases (2 sets of 3)
current_height = BUILD_HEIGHT * i / VID_FRAMES
phase = current_height % (TILE_HEIGHT * 2) * 6 / (TILE_HEIGHT * 2)
img = Image.new("L", VID_DIM, color = "white")
draw = ImageDraw.Draw(img)
if phase < 2 or 5 <= phase:
for y in range(math.ceil(PLATE_WIDTH / TILE_HEIGHT) + 1):
for x in range(math.ceil(PLATE_WIDTH / TILE_WIDTH) + 1):
x_pos = (x) * (TILE_WIDTH - 1)
if y % 2: x_pos += TILE_HALF_OFFSET
draw.regular_polygon(bounding_circle=(x_pos * PPMM, (y) * (TILE_HEIGHT - 1) * PPMM, TILE_RADIUS * PPMM), n_sides=6, rotation=90, outline="black", width=PPMM)
else:
for y in range(math.ceil(PLATE_WIDTH / TILE_HEIGHT) + 2):
for x in range(math.ceil(PLATE_WIDTH / TILE_WIDTH) + 2):
x_pos = (x-.5) * (TILE_WIDTH - 1)
if y % 2: x_pos += TILE_HALF_OFFSET
draw.regular_polygon(bounding_circle=(x_pos * PPMM, (y-1/3) * (TILE_HEIGHT - 1) * PPMM, TILE_RADIUS * PPMM), n_sides=6, rotation=90, outline="black", width=PPMM)
if 1 < phase < 2:
for y in range(math.ceil(PLATE_WIDTH / TILE_HEIGHT) + 2):
for x in range(math.ceil(PLATE_WIDTH / TILE_WIDTH) + 2):
x_pos = (x-.5) * (TILE_WIDTH - 1)
if y % 2: x_pos += TILE_HALF_OFFSET
draw.regular_polygon(bounding_circle=(x_pos * PPMM, (y-1/3) * (TILE_HEIGHT - 1) * PPMM, TILE_RADIUS * PPMM * (phase - 1)), n_sides=3, rotation=60, fill="white", outline="black", width=PPMM)
elif 2 <= phase < 3:
for y in range(math.ceil(PLATE_WIDTH / TILE_HEIGHT) + 2):
for x in range(math.ceil(PLATE_WIDTH / TILE_WIDTH) + 2):
x_pos = (x) * (TILE_WIDTH - 1)
if y % 2: x_pos += TILE_HALF_OFFSET
draw.regular_polygon(bounding_circle=(x_pos * PPMM, (y) * (TILE_HEIGHT - 1) * PPMM, TILE_RADIUS * PPMM * (3 - phase)), n_sides=3, fill="white", outline="black", width=PPMM)
elif 4 < phase < 5:
for y in range(math.ceil(PLATE_WIDTH / TILE_HEIGHT) + 2):
for x in range(math.ceil(PLATE_WIDTH / TILE_WIDTH) + 2):
x_pos = (x) * (TILE_WIDTH - 1)
if y % 2: x_pos += TILE_HALF_OFFSET
draw.regular_polygon(bounding_circle=(x_pos * PPMM, (y) * (TILE_HEIGHT - 1) * PPMM, TILE_RADIUS * PPMM * (phase - 4)), n_sides=3, fill="white", outline="black", width=PPMM)
elif 5 <= phase < 6:
for y in range(math.ceil(PLATE_WIDTH / TILE_HEIGHT) + 2):
for x in range(math.ceil(PLATE_WIDTH / TILE_WIDTH) + 2):
x_pos = (x-.5) * (TILE_WIDTH - 1)
if y % 2: x_pos += TILE_HALF_OFFSET
draw.regular_polygon(bounding_circle=(x_pos * PPMM, (y-1/3) * (TILE_HEIGHT - 1) * PPMM, TILE_RADIUS * PPMM * (6-phase)), n_sides=3, rotation=60, fill="white", outline="black", width=PPMM)
video.write(cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR))
video.release()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment