Created
July 27, 2022 01:24
-
-
Save neizod/50f1d1b76eaff3e5ec6801ffcadfa5fc to your computer and use it in GitHub Desktop.
zooming parabola with infinitely inscribed triangles
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
#!/usr/bin/env python3 | |
from math import log2 | |
COLORS = ['#e50000', '#ff8d00', '#ffee00', '#028121', '#004cff', '#770088'] | |
keyframes = 12 # can't be odd number! | |
per_kf = 4 # minimum = 4 (small filesize), otherwise for smooth animation | |
dur = 20 # longer animation need more per_kf | |
# ============================================================================ | |
assert keyframes % 2 == 0 | |
assert per_kf >= 4 | |
lag = dur / keyframes | |
def pn(number): | |
return str(round(number, 2)) | |
def ppoly(trig): | |
return ' '.join(','.join(map(pn, pair)) for pair in trig) | |
def pairwise(ls): | |
return zip(ls, ls[1:]) | |
def sign(xs, lvl, k=1/2**6): | |
if lvl % 2 == 0: | |
return [k*x for x in xs] | |
return [-k*x for x in xs] | |
def mid(xs): | |
return sum(xs)/2 | |
def make_trig(xs, i=0): | |
xs = [x * 2**(i/per_kf) for x in xs] | |
return [(10*x, -x**2) for x in [mid(xs), *xs]] | |
def print_trig(xs, co, lvl): | |
trigs = [make_trig(xs, i) for i in range(1+per_kf*keyframes)] | |
print(f'<polygon points="0,0 0,0 0,0" stroke="{co}" fill="{co}">') | |
print(f'<animate attributeName="points" begin="{pn(lvl*lag)}s" dur="{dur}s" repeatCount="indefinite"') | |
print(f'values="{";".join(map(ppoly, trigs))}" />') | |
print('</polygon>') | |
def print_main_trig(lvl=0): | |
co = COLORS[(lvl+0)%len(COLORS)] | |
xs = sign([-1, 2], lvl) | |
print_trig(xs, co, lvl) | |
def print_acc_trig(lvl=0): | |
co = COLORS[(lvl+1)%len(COLORS)] | |
xs = sign([1/2, 2], lvl) | |
print_trig(xs, co, lvl) | |
def print_surr_trigs(lvl=0): | |
co = COLORS[(lvl+2)%len(COLORS)] | |
xss = [sign(xs, lvl) for xs in pairwise([1/2, 5/4, 2])] | |
for xs in xss: | |
print_trig(xs, co, lvl) | |
def print_outer_trigs(lvl=0): | |
co = COLORS[(lvl+3)%len(COLORS)] | |
xss = [sign(xs, lvl) for xs in pairwise([1/2, 7/8, 5/4, 13/8, 2])] | |
for xs in xss: | |
print_trig(xs, co, lvl) | |
# ============================================================================ | |
print('<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="-200 -395 400 400">') | |
for i in range(keyframes): | |
print_outer_trigs(-i) | |
print_surr_trigs(-i) | |
print_acc_trig(-i) | |
print_main_trig(-i) | |
print('<path id="parabola" d="M -300,-900 Q 0,900 300,-900 M 900,-900 900,900 -900,900 -900,-900" fill="#fff" stroke="#000" />') | |
print('</svg>') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment