Pincushion experiment
This commit is contained in:
parent
c19a1e8876
commit
16e60427d1
93
pincushion.py
Executable file
93
pincushion.py
Executable 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>')
|
Loading…
Reference in New Issue
Block a user