94 lines
2.8 KiB
Python
Executable File
94 lines
2.8 KiB
Python
Executable File
#!/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>')
|