-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdrawable.py
144 lines (114 loc) · 4.12 KB
/
drawable.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
import config as cfg
from affine import Affine
from utils import btu
class Drawable(object):
_sym_plot_limit = 0
def __init__(self):
super(Drawable, self).__init__()
self.plot_offset = (btu(1), 0)
self.extents = (btu(1), btu(1))
def draw(self):
raise NotImplementedError("draw method not implemented")
def draw_multipole(self):
self.draw_multipole_basic()
def draw_multipole_basic(self):
px, py = self.pole_offset
original_offset = self.offset
for i in range(0, self.poles):
self.offset =\
original_offset * Affine.translation(xoff=px * i, yoff=py * i)
self.draw()
self.offset = original_offset
def plot(self, layout, origin, offset, scale, rotation,
poles, pole_offset):
self.layout = layout
self.origin = origin
self.offset = offset
self.rotation = rotation
self.scale = scale
self.poles = poles
self.pole_offset = pole_offset
if poles == 1:
self.draw()
else:
self.draw_multipole()
def sym_plot(self, sym, offset=(0, 0)):
if Drawable._sym_plot_limit >= 20:
raise RecursionError()
Drawable._sym_plot_limit += 1
self.layout = sym.layout
self.scale = sym.scale
self.origin = sym.origin
self.rotation = sym.rotation
self.offset = sym.offset * Affine.translation(*offset)
self.draw()
Drawable._sym_plot_limit -= 1
def add_arc(self, center, radius, start, end):
self.layout.add_arc(
self.trans_xy(center),
self.trans_scale(radius),
start + self.rotation, # Start Angle (draws CCW)
end + self.rotation # End Angle
)
def add_line(self, start, end, **atr):
self.layout.add_line(
self.trans_xy(start),
self.trans_xy(end),
dxfattribs={
'linetype': atr.get('linetype', 'BYLAYER')
}
)
def add_circle(self, center, radius):
self.layout.add_circle(
self.trans_xy(center),
self.trans_scale(radius) # Radius
)
def add_text(self, label, pos, height=10, alignment='MIDDLE_CENTER'):
if cfg.DISABLE_TEXT is not True:
self.layout.add_text(
label, dxfattribs={'height': self.trans_scale(height)}
).set_pos(
self.trans_xy(pos),
align=alignment
)
def add_polyline2d(self, points, attr={}):
self.layout.add_polyline2d(
[self.trans_xy(point) for point in points],
dxfattribs=attr
)
def add_rectangle(self, points, attr={}):
if(len(points) < 2):
raise NotImplementedError(
"Only a list of 2 or more points supported.")
leftmost = min(points, key=lambda x: x[0])
rightmost = max(points, key=lambda x: x[0])
topmost = max(points, key=lambda y: y[1])
botmost = min(points, key=lambda y: y[1])
if(leftmost[0] == rightmost[0]):
raise ValueError("X coordinates must not be the same.")
if(topmost[1] == botmost[1]):
raise ValueError("Y coordinates must not be the same.")
# TL = (leftmost[0], topmost[1])
# TR = (rightmost[0], topmost[1])
# BR = (rightmost[0], botmost[1])
# BL = (leftmost[0], botmost[1])
plist = [
(leftmost[0], topmost[1]),
(rightmost[0], topmost[1]),
(rightmost[0], botmost[1]),
(leftmost[0], botmost[1])
]
self.layout.add_polyline2d(
[self.trans_xy(point) for point in plist],
dxfattribs=attr
)
def move(self, dist):
self.offset = self.offset * Affine.translation(*dist)
def trans_scale(self, number):
return self.scale * number
def trans_xy(self, point):
p = point * Affine.translation(*self.offset)
p *= Affine.rotation(self.rotation)
p *= Affine.translation(*self.origin)
p *= Affine.scale(self.scale)
return p