-
Notifications
You must be signed in to change notification settings - Fork 0
/
tikz.py
122 lines (94 loc) · 3.01 KB
/
tikz.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
import sys
import math
from itertools import chain
class Node:
count = 0;
def __init__(self, coordinate, name=None, style='draw, circle, fill, radius=0.5pt, scale=0.2'):
if name is None:
self.name = f'v{self.count}'
else:
self.name = name
self.coordinate = coordinate
self.style = style
Node.count += 1
def nodeCommand(self):
return f'\\node[{self.style}] at ({self.name}) {{}};'
def coordinateCommand(self):
return f'\\coordinate ({self.name}) at {self.coordinate};'
class Path:
def __init__(self, node, style='draw'):
self.style = style
self.command = [fr'\path[{style}] ({node.name})']
def to(self, node, _type='to', style=''):
if style != '':
style = '[' + style + ']'
if isinstance(node, Node):
node = "(" + node.name + ")"
self.command.append(f'{_type}{style} {node}')
return self
def close(self, _type='to', style=''):
if style == '':
self.command.append(f'{_type} cycle')
else:
self.command.append(f'{_type}[{style}] cycle')
return self
def compile(self):
return ' '.join(chain(self.command, [';']))
def curveTo(self, node, control1, control2=None):
if isinstance(node, Node):
node = "(" + node.name + ")"
if control2 is None:
self.command.append(f' .. controls {control1} .. {node}')
else:
self.command.append(f' .. controls {control1} and {control2} .. {node}')
return self
class Figure:
def __init__(self):
self.coordinates = []
self.paths = []
self.nodes = []
def addCoordinate(self, coordinate):
self.coordinates.append(coordinate)
def addNode(self, node):
self.coordinates.append(node.coordinateCommand())
self.nodes.append(node.nodeCommand())
@staticmethod
def preamble():
return [\
"\\documentclass[tikz]{standalone}"\
, "\\usepackage{tikz}"\
, "\\begin{document}"\
, "\\begin{tikzpicture}[]"\
]
@staticmethod
def epilogue():
return [\
"\\end{tikzpicture}"\
, "\\end{document}"\
]
def addPath(self, path):
self.paths.append(path.compile())
def compile(self):
return '\n'.join(chain(self.preamble(), self.coordinates,\
self.paths, self.nodes, self.epilogue()))
def main():
#a circular drawing of V_8
k = 8
points = [(math.cos(i*(2*math.pi)/k), math.sin(i*2*math.pi/k)) for i in range(k)]
f = Figure()
h, *tail = [Node(p) for p in points]
f.addNode(h)
rim = Path(h)
for n in tail:
f.addNode(n)
rim.to(n)
rim.close()
f.addPath(rim)
#spokes
f.addPath(Path(h).to(tail[3]))
for i in range(1, k//2):
f.addPath(Path(tail[i-1]).to(tail[i-1+k//2]))
with open('test.tex', 'w') as texfile:
texfile.write(f.compile())
if __name__ == "__main__":
main()