|
@@ -3,6 +3,7 @@ from math import sqrt
|
3
|
3
|
from math import degrees
|
4
|
4
|
from math import acos
|
5
|
5
|
|
|
6
|
+from synergine2.exceptions import SynergineException
|
6
|
7
|
from synergine2.simulation import SubjectMechanism, Subjects, Subject
|
7
|
8
|
from synergine2.simulation import Simulation as BaseSimulation
|
8
|
9
|
|
|
@@ -81,6 +82,14 @@ DIRECTION_MODIFIERS = {
|
81
|
82
|
}
|
82
|
83
|
|
83
|
84
|
|
|
85
|
+class XYZException(SynergineException):
|
|
86
|
+ pass
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+class PositionNotPossible(XYZException):
|
|
90
|
+ pass
|
|
91
|
+
|
|
92
|
+
|
84
|
93
|
def get_degree_from_north(a, b):
|
85
|
94
|
if a == b:
|
86
|
95
|
return 0
|
|
@@ -130,6 +139,9 @@ class ProximityMixin(object):
|
130
|
139
|
direction_round_decimals = 0
|
131
|
140
|
distance_round_decimals = 2
|
132
|
141
|
|
|
142
|
+ def have_to_check_position_is_possible(self) -> bool:
|
|
143
|
+ return True
|
|
144
|
+
|
133
|
145
|
def get_for_position(
|
134
|
146
|
self,
|
135
|
147
|
position,
|
|
@@ -145,6 +157,9 @@ class ProximityMixin(object):
|
145
|
157
|
if subject == exclude_subject:
|
146
|
158
|
continue
|
147
|
159
|
|
|
160
|
+ if self.have_to_check_position_is_possible() and not simulation.is_possible_position(subject.position):
|
|
161
|
+ continue
|
|
162
|
+
|
148
|
163
|
distance = round(
|
149
|
164
|
self.get_distance_of(
|
150
|
165
|
position=position,
|
|
@@ -196,18 +211,35 @@ class XYZSubjects(Subjects):
|
196
|
211
|
|
197
|
212
|
self.xyz = {}
|
198
|
213
|
|
|
214
|
+ def have_to_check_position_is_possible(self) -> bool:
|
|
215
|
+ return True
|
|
216
|
+
|
199
|
217
|
def remove(self, value: XYZSubjectMixin):
|
200
|
218
|
super().remove(value)
|
201
|
219
|
del self.xyz[value.position]
|
202
|
220
|
|
203
|
221
|
def append(self, p_object: XYZSubjectMixin):
|
204
|
222
|
super().append(p_object)
|
|
223
|
+
|
|
224
|
+ if self.have_to_check_position_is_possible() \
|
|
225
|
+ and not self.simulation.is_possible_subject_position(p_object, p_object.position):
|
|
226
|
+ raise PositionNotPossible('Position {} for {} is not possible'.format(
|
|
227
|
+ p_object.position,
|
|
228
|
+ p_object,
|
|
229
|
+ ))
|
|
230
|
+
|
205
|
231
|
self.xyz[p_object.position] = p_object
|
206
|
232
|
|
207
|
233
|
|
208
|
234
|
class XYZSimulation(BaseSimulation):
|
209
|
235
|
accepted_subject_class = XYZSubjects
|
210
|
236
|
|
|
237
|
+ def is_possible_subject_position(self, subject: XYZSubjectMixin, position: tuple) -> bool:
|
|
238
|
+ return self.is_possible_position(position)
|
|
239
|
+
|
|
240
|
+ def is_possible_position(self, position: tuple) -> bool:
|
|
241
|
+ return True
|
|
242
|
+
|
211
|
243
|
|
212
|
244
|
def get_direction_from_north_degree(degree: float):
|
213
|
245
|
for range, direction in DIRECTION_FROM_NORTH_DEGREES.items():
|