|
@@ -32,6 +32,7 @@ https://surfer.nmr.mgh.harvard.edu/
|
|
import collections
|
|
import collections
|
|
import contextlib
|
|
import contextlib
|
|
import datetime
|
|
import datetime
|
|
|
|
+import itertools
|
|
import locale
|
|
import locale
|
|
import re
|
|
import re
|
|
import struct
|
|
import struct
|
|
@@ -63,34 +64,6 @@ def setlocale(temporary_locale):
|
|
Vertex = collections.namedtuple('Vertex', ['right', 'anterior', 'superior'])
|
|
Vertex = collections.namedtuple('Vertex', ['right', 'anterior', 'superior'])
|
|
|
|
|
|
|
|
|
|
-class PolygonalChain:
|
|
|
|
-
|
|
|
|
- def __init__(self, vertex_indices: typing.Iterable[int]):
|
|
|
|
- self.vertex_indices: typing.Deque[int] = collections.deque(vertex_indices)
|
|
|
|
-
|
|
|
|
- def __eq__(self, other: 'PolygonalChain') -> bool:
|
|
|
|
- return self.vertex_indices == other.vertex_indices
|
|
|
|
-
|
|
|
|
- def __repr__(self) -> str:
|
|
|
|
- return 'PolygonalChain(vertex_indices={})'.format(tuple(self.vertex_indices))
|
|
|
|
-
|
|
|
|
- def connect(self, other: 'PolygonalChain') -> None:
|
|
|
|
- if self.vertex_indices[-1] == other.vertex_indices[0]:
|
|
|
|
- self.vertex_indices.pop()
|
|
|
|
- self.vertex_indices.extend(other.vertex_indices)
|
|
|
|
- elif self.vertex_indices[-1] == other.vertex_indices[-1]:
|
|
|
|
- self.vertex_indices.pop()
|
|
|
|
- self.vertex_indices.extend(reversed(other.vertex_indices))
|
|
|
|
- elif self.vertex_indices[0] == other.vertex_indices[0]:
|
|
|
|
- self.vertex_indices.popleft()
|
|
|
|
- self.vertex_indices.extendleft(other.vertex_indices)
|
|
|
|
- elif self.vertex_indices[0] == other.vertex_indices[-1]:
|
|
|
|
- self.vertex_indices.popleft()
|
|
|
|
- self.vertex_indices.extendleft(reversed(other.vertex_indices))
|
|
|
|
- else:
|
|
|
|
- raise ValueError('polygonal chains do not overlap')
|
|
|
|
-
|
|
|
|
-
|
|
|
|
class _PolygonalCircuit:
|
|
class _PolygonalCircuit:
|
|
|
|
|
|
_VERTEX_INDICES_TYPE = typing.Tuple[int]
|
|
_VERTEX_INDICES_TYPE = typing.Tuple[int]
|
|
@@ -140,6 +113,42 @@ class Triangle(_PolygonalCircuit):
|
|
return 'Triangle(vertex_indices={})'.format(self.vertex_indices)
|
|
return 'Triangle(vertex_indices={})'.format(self.vertex_indices)
|
|
|
|
|
|
|
|
|
|
|
|
+class PolygonalChainsNotOverlapingError(ValueError):
|
|
|
|
+ pass
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class PolygonalChain:
|
|
|
|
+
|
|
|
|
+ def __init__(self, vertex_indices: typing.Iterable[int]):
|
|
|
|
+ self.vertex_indices: typing.Deque[int] = collections.deque(vertex_indices)
|
|
|
|
+
|
|
|
|
+ def __eq__(self, other: 'PolygonalChain') -> bool:
|
|
|
|
+ return self.vertex_indices == other.vertex_indices
|
|
|
|
+
|
|
|
|
+ def __repr__(self) -> str:
|
|
|
|
+ return 'PolygonalChain(vertex_indices={})'.format(tuple(self.vertex_indices))
|
|
|
|
+
|
|
|
|
+ def connect(self, other: 'PolygonalChain') -> None:
|
|
|
|
+ if self.vertex_indices[-1] == other.vertex_indices[0]:
|
|
|
|
+ self.vertex_indices.pop()
|
|
|
|
+ self.vertex_indices.extend(other.vertex_indices)
|
|
|
|
+ elif self.vertex_indices[-1] == other.vertex_indices[-1]:
|
|
|
|
+ self.vertex_indices.pop()
|
|
|
|
+ self.vertex_indices.extend(reversed(other.vertex_indices))
|
|
|
|
+ elif self.vertex_indices[0] == other.vertex_indices[0]:
|
|
|
|
+ self.vertex_indices.popleft()
|
|
|
|
+ self.vertex_indices.extendleft(other.vertex_indices)
|
|
|
|
+ elif self.vertex_indices[0] == other.vertex_indices[-1]:
|
|
|
|
+ self.vertex_indices.popleft()
|
|
|
|
+ self.vertex_indices.extendleft(reversed(other.vertex_indices))
|
|
|
|
+ else:
|
|
|
|
+ raise PolygonalChainsNotOverlapingError()
|
|
|
|
+
|
|
|
|
+ def segments(self) -> typing.Iterable[_LineSegment]:
|
|
|
|
+ indices = self.vertex_indices
|
|
|
|
+ return map(_LineSegment, zip(indices, itertools.islice(indices, 1, len(indices))))
|
|
|
|
+
|
|
|
|
+
|
|
class Label:
|
|
class Label:
|
|
|
|
|
|
# pylint: disable=too-many-arguments
|
|
# pylint: disable=too-many-arguments
|