Pincushion experiment

This commit is contained in:
Matthias Neeracher 2021-11-14 06:07:31 +01:00
parent c19a1e8876
commit 16e60427d1

93
pincushion.py Executable file
View File

@ -0,0 +1,93 @@
#!/usr/bin/env python3
import math
import sys
M=2
N=5
L=20.0
B=2.5
def frange(*args):
"""frange([start, ] end [, step [, mode]]) -> generator
A float range generator. If not specified, the default start is 0.0
and the default step is 1.0.
Optional argument mode sets whether frange outputs an open or closed
interval. mode must be an int. Bit zero of mode controls whether start is
included (on) or excluded (off); bit one does the same for end. Hence:
0 -> open interval (start and end both excluded)
1 -> half-open (start included, end excluded)
2 -> half open (start excluded, end included)
3 -> closed (start and end both included)
By default, mode=1 and only start is included in the output.
"""
mode = 1 # Default mode is half-open.
n = len(args)
if n == 1:
args = (0.0, args[0], 1.0)
elif n == 2:
args = args + (1.0,)
elif n == 4:
mode = args[3]
args = args[0:3]
elif n != 3:
raise TypeError('frange expects 1-4 arguments, got %d' % n)
assert len(args) == 3
try:
start, end, step = [a + 0.0 for a in args]
except TypeError:
raise TypeError('arguments must be numbers')
if step == 0.0:
raise ValueError('step must not be zero')
if not isinstance(mode, int):
raise TypeError('mode must be an int')
if mode & 1:
i, x = 0, start
else:
i, x = 1, start+step
if step > 0:
if mode & 2:
from operator import le as comp
else:
from operator import lt as comp
else:
if mode & 2:
from operator import ge as comp
else:
from operator import gt as comp
while comp(x, end):
yield x
i += 1
x = start + i*step
def cushion(x0, y0, hole, space):
yoff = .866*space # sqrt(3)/2
xodd = list(frange(x0+B, x0+L-B, space, 3))
xeven = list(frange(x0+B+.5*space, x0+L-B, space, 3))
row = 0
for y in frange(y0+B, y0+L-B, yoff, 3):
row += 1
if (row & 1) == 1:
xrow = xodd
else:
xrow = xeven
for x in xrow:
print('<circle cx="{}" cy="{}" r="{}" stroke="black" fill="none"/>'.format(x, y, hole))
print('<svg viewBox="-1 -1 101 41" width="102mm" height="42mm" stroke-width="0.1" xmlns="http://www.w3.org/2000/svg">')
print('<rect height="{}" width="{}" stroke="black" fill="none"/>'.format(M*L, N*L))
for i in range(1,M):
print('<line x1="0" y1="{}" x2="{}" y2="{}" stroke="red"/>'.format(i*L, N*L, i*L))
for j in range(1,N):
print('<line x1="{}" y1="0" x2="{}" y2="{}" stroke="red"/>'.format(j*L, j*L, M*L))
HOLE = [0.1, 0.05]
SPACE = [2.0, 1.5, 1.0, 0.75, 0.5]
for i in range(M):
for j in range(N):
cushion(j*L, i*L, HOLE[i], SPACE[j])
print('</svg>')