-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmake_bookshelf.py
149 lines (126 loc) · 5.04 KB
/
make_bookshelf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""
Usage:
python3 make_bookshelf.py > bookshelf.tex; pdflatex bookshelf.tex
"""
class Panel:
def __init__(self, width, height, fill=None):
self.width = width
self.height = height
self.fill = fill
def draw(self, scale):
drawcmd = r"\filldraw[draw=black,fill={}]".format(self.fill) if self.fill else r"\draw"
return r"{} (0,0) rectangle ({},{});".format(drawcmd, self.width/scale, self.height/scale)
class Door:
def __init__(self, width, height, doornob_side, border=50, doornob_radius=10):
self.width = width
self.height = height
self.doornob_side = doornob_side
self.border = border
self.doornob_radius = doornob_radius
def draw(self, scale):
w, h, i, r = self.width/scale, self.height/scale, self.border/scale, self.doornob_radius/scale
res = r"\draw (0,0) rectangle ({},{});".format(w, h) + "\n"
res += r"\draw ({},{}) rectangle ({},{});".format(i, i, w-i, h-i) + "\n"
if self.doornob_side == "left":
res += r"\draw ({}, {}) circle ({});".format(w - i/2, h/2, r)
if self.doornob_side == "topleft":
res += r"\draw ({}, {}) circle ({});".format(w - i/2, h - i/2, r)
elif self.doornob_side == "right":
res += r"\draw ({}, {}) circle ({});".format(i/2, h/2, r)
elif self.doornob_side == "topright":
res += r"\draw ({}, {}) circle ({});".format(i/2, h - i/2, r)
elif self.doornob_side is None:
pass
else:
raise ValueError(self.doornob_side)
return res
class Shelves:
def __init__(self, width, height, shelve_spacing, shelve_thick, closed):
self.width = width
self.height = height
self.shelve_spacing = shelve_spacing
self.shelve_thick = shelve_thick
self.closed = closed
def draw(self, scale):
w, h, st = (
round(self.width/scale, 2), round(self.height/scale, 2),
round(self.shelve_thick/scale, 2),
)
sss = self.shelve_spacing
if isinstance(sss, (int, float)):
sss = [sss]
res = r"\draw ({}, {}) -- ({}, {});".format(st, 0, st, h) + "\n"
res += r"\draw ({}, {}) -- ({}, {});".format(w-st, 0, w-st, h) + "\n"
if self.closed in ["left", "both"]:
res += r"\draw ({}, {}) -- ({}, {});".format(w, 0, w, h) + "\n"
if self.closed in ["right", "both"]:
res += r"\draw ({}, {}) -- ({}, {});".format(0, 0, 0, h) + "\n"
ss = round(sss[0]/scale, 2)
ch = ss
count = 0
while ch < h:
res += r"\draw ({},{}) rectangle ({},{});".format(
st, round(ch-st, 2), round(w-st, 2), round(ch, 2)
) + "\n"
count += 1
ss = round(sss[min([count, len(sss)-1])]/scale, 2)
ch += ss
return res[:-1]
W = 3220
H = 2700
skirting_height = 150
crown_height = 150
base_height = 720
counter_height = 50
counter_overhang = 20
shelve_width = 20
shelving_spacing = [450, 250]
base = [ # right to left
Panel(50, base_height),
Door(600, base_height, "topleft"),
Door(450, base_height, "topleft"),
Door(450, base_height, "topright"),
Door(450, base_height, "topleft"),
Door(450, base_height, "topright"),
Door(600, base_height, "topright"),
]
shelving_height = H - base_height - counter_height - crown_height - skirting_height
top = [
Panel(50, shelving_height),
Shelves(600, shelving_height, shelving_spacing, 20, closed=None),
Shelves(900, shelving_height, shelving_spacing, 20, closed=None),
Shelves(900, shelving_height, shelving_spacing, 20, closed=None),
Shelves(600, shelving_height, shelving_spacing, 20, closed=None),
]
total_width = sum([b.width for b in base])
rows = [
[Panel(total_width + counter_overhang, skirting_height, "white"),],
base,
[Panel(total_width + counter_overhang, counter_height, "white")],
top,
[Panel(total_width, crown_height)],
]
tex = r"""\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=0.4, xscale=-1]
"""
xoffset = yoffset = 0
scale = 100 # hack, 3220 -> 32.2
tex += " % wall\n"
tex += r" \draw (0,0) rectangle ({:.2f},{:.2f});".format(W/scale, H/scale) + "\n"
tex += r" \filldraw[draw=black,fill=gray] ({:.2f},{:.2f}) rectangle ({:.2f},{:.2f});".format(
total_width/scale, 0, W/scale, H/scale) + "\n"
for i, row in enumerate(rows):
xoffset = 0
tex += f"\n % ROW={i}\n"
for ii, box in enumerate(row):
tex += f" % box={ii}\n"
tex += " " + box.draw(scale).replace("\n", "\n ") + "\n"
tex += r" \tikzset{{shift={{({},{})}}}}".format(box.width/scale, 0) + "\n"
xoffset += box.width/scale
tex += r" \tikzset{{shift={{({},{})}}}}".format(-xoffset, box.height/scale) + "\n"
tex+=r"""
\end{tikzpicture}
\end{document}"""
print(tex)