-
Notifications
You must be signed in to change notification settings - Fork 2
/
View2DEngine.py
232 lines (168 loc) · 6.45 KB
/
View2DEngine.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
from PyQt5.QtCore import * # core Qt functionality
from PyQt5.QtWidgets import *
from PyQt5.QtGui import * # extends QtCore with GUI functionality
from Model import *
from ProjectSettings import *
from Definition import *
import math as m
# -------------------------------- TO BE REMOVED --------------------------------
COLORS_FLOOR_PLAN = ['blue', 'violet']
COLORS_PANEL = ['orange']
COLORS_NODE = ['green']
# New 2D view
# View Objects --------------------------------
class ViewObject:
def __init__(self):
self.color = ''
self.size = 1.0
self.dim_x = 1.0
self.dim_y = 1.0
def setColor(self, color):
self.color = color
def setSize(self, size):
self.size = size
def setDimX(self, x):
self.dim_x = x
def setDimY(self, y):
self.dim_y = y
def findDimX(self):
# Assume x is positive
x_all = []
for member in self.members:
x_all.append(member.start_node.x)
x_all.append(member.end_node.x)
return max(x_all)
def findDimY(self):
# Assume y is positive
y_all = []
for member in self.members:
y_all.append(member.start_node.y)
y_all.append(member.end_node.y)
return max(y_all)
class ViewMember(ViewObject):
def __init__(self):
super().__init__()
self.members = []
def addMember(self, member):
self.members.append(member)
class ViewNode(ViewObject):
def __init__(self):
super().__init__()
self.nodes = []
def addNode(self, node):
self.nodes.append(node)
class ViewText(ViewObject):
def __init__(self):
super().__init__()
self.texts = []
self.members = []
self.location = Node() # x must range from 0 to 1
# Note: make sure the text correpsonds to the right member
def addText(self, text):
self.texts.append(text)
def addMember(self, member):
self.members.append(member)
def setLocation(self, location):
self.location = location
# View2D Widget -------------------------------
class View2DWidget(QWidget):
def __init__(self, *args, **kwargs):
super().__init__()
self.members = []
self.nodes = []
self.texts = []
self.dimension_x = self.size().width()
self.dimension_y = self.size().height()
def addMember(self, vMember):
self.members.append(vMember)
def addNode(self, vNode):
self.nodes.append(vNode)
def addText(self, vText):
self.texts.append(vText)
def reset(self):
self.members.clear()
self.nodes.clear()
self.texts.clear()
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
for vMember in self.members:
self.drawMember(painter, vMember)
for vNode in self.nodes:
self.drawNode(painter, vNode)
for vText in self.texts:
self.drawText(painter, vText)
painter.end()
def drawMember(self, painter, vMember):
p = painter.pen()
p.setColor(QColor(vMember.color))
p.setWidth(vMember.size)
painter.setPen(p)
for member in vMember.members:
start = member.start_node
end = member.end_node
x1, y1 = self.convertCoordinates(vMember, start.x, start.y)
x2, y2 = self.convertCoordinates(vMember, end.x, end.y)
painter.drawLine(x1, y1, x2, y2)
def drawNode(self, painter, vNode):
p = painter.pen()
p.setColor(QColor(vNode.color))
p.setWidth(vNode.size)
painter.setPen(p)
for node in vNode.nodes:
x1, y1 = self.convertCoordinates(vNode, node.x, node.y)
painter.drawPoint(x1, y1)
def drawText(self, painter, vText):
p = painter.pen()
p.setColor(QColor(vText.color))
painter.setPen(p)
painter.setFont(QFont("Times", vText.size))
location = vText.location
for i in range(len(vText.texts)):
text = vText.texts[i]
member = vText.members[i]
start = member.start_node
end = member.end_node
# translate text parallel to the member
x = start.x + (end.x - start.x) * location.x
y = start.y + (end.y - start.y) * location.x
# translate text perpendicular to the member
angle = member.angle()
dx = m.cos(angle - m.pi / 2) * location.y
dy = m.sin(angle - m.pi / 2) * location.y
x1, y1 = self.convertCoordinates(vText, x + dx, y + dy)
painter.drawText(x1, y1, text)
# Methods to convert coordinates for objects to be displayed properly -----------------------------------
def convertCoordinates(self, vObject, x, y):
view_factor, dummy, view_factor_y = self.viewFactors(vObject)
center_x, center_y = self.centerdxdy(vObject)
# y coordinate is negative since y postive is downward in QPainter
coordinates = (
x * view_factor + center_x,
-y * view_factor + center_y,
)
return coordinates
def viewFactors(self, vObject):
dim_x = vObject.dim_x
dim_y = vObject.dim_y
# Maximum length
maxLength = max(dim_x, dim_y) + Algebra.EPSILON
view_factor_x = self.dimension_x * View2DConstants.RATIO / maxLength
view_factor_y = self.dimension_y * View2DConstants.RATIO / maxLength
# Find the smallest view factor so that the object fits in the window
view_factor = min(view_factor_x, view_factor_y)
return view_factor, view_factor_x, view_factor_y
def centerdxdy(self, vObject):
''' find the translations required to center the displayed object '''
dim_x = vObject.dim_x
dim_y = vObject.dim_y
view_factor, dummy, view_factor_y = self.viewFactors(vObject)
center_x = (self.dimension_x - view_factor * dim_x) / 2
# margin in the y direction
margin_y = self.dimension_y * (1 - View2DConstants.RATIO) / 2
# translation due to the difference of side lengths in x and y direction
lengthDiff = max(dim_x - dim_y, 0) / 2
# translation due to the difference of the x and y dimensions of the view window
dimDiff = max(view_factor_y - view_factor, 0) * dim_y / 2
center_y = view_factor * dim_y + margin_y + dimDiff + lengthDiff * view_factor
return center_x, center_y