Mon, 22 Jan 2018 18:07:19 +0200
refactor
7 | 1 | def degree_rep(angle): |
2 | from math import degrees | |
3 | return '∠ %.2f°' % degrees(angle) | |
4 | ||
5 | def position_vector(vertex): | |
6 | assert isinstance(vertex, Vertex) | |
7 | return Vector(*vertex.coordinates) | |
8 | ||
9 | def angle_magnitude_key(angle): | |
10 | ''' | |
11 | Returns how great an angle is. | |
12 | ''' | |
13 | from math import pi as π | |
14 | normalized_angle = abs(angle) % (2 * π) | |
15 | if normalized_angle > π: | |
16 | normalized_angle = (2 * π) - normalized_angle | |
17 | return normalized_angle | |
18 | ||
0 | 19 | class Vertex: |
20 | def __init__(self, x, y, z): | |
5 | 21 | if not all(is_real(coordinate) for coordinate in (x, y, z)): |
22 | raise ValueError(str.format('Bad vertex coordinates: {!r}', | |
23 | (x, y, z), | |
24 | )) | |
0 | 25 | self.x, self.y, self.z = x, y, z |
26 | def __repr__(self): | |
27 | return str.format('Vertex({!r}, {!r}, {!r})', self.x, self.y, self.z) | |
28 | def distance_to(self, other): | |
29 | # can't use hypot because of 3 arguments | |
30 | from math import sqrt | |
31 | return sqrt( | |
32 | (self.x - other.x) ** 2 + | |
33 | (self.y - other.y) ** 2 + | |
34 | (self.z - other.z) ** 2 | |
35 | ) | |
3
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
1
diff
changeset
|
36 | @property |
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
1
diff
changeset
|
37 | def coordinates(self): |
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
1
diff
changeset
|
38 | return self.x, self.y, self.z |
5 | 39 | def __add__(self, other): |
7 | 40 | assert not (type(self) == type(other) == Vertex) |
41 | if type(self) == Vector and type(other) == Vector: | |
42 | result_type = Vector | |
43 | else: | |
44 | result_type = Vertex | |
45 | return result_type(self.x + other.x, self.y + other.y, self.z + other.z) | |
46 | def __radd__(self, other): | |
47 | return self + other | |
5 | 48 | def __neg__(self): |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
49 | return type(self)(-self.x, -self.y, -self.z) |
5 | 50 | def __sub__(self, other): |
7 | 51 | result = self + (-position_vector(other)) |
52 | if isinstance(other, Vertex): | |
53 | return Vector(*result.coordinates) | |
54 | else: | |
55 | return result | |
5 | 56 | def __mul__(self, scalar): |
7 | 57 | assert is_real(scalar) |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
58 | return type(self)(self.x * scalar, self.y * scalar, self.z * scalar) |
5 | 59 | def __rmul__(self, other): |
60 | return self * other | |
61 | def __truediv__(self, scalar): | |
7 | 62 | assert is_real(scalar) |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
63 | return type(self)(self.x / scalar, self.y / scalar, self.z / scalar) |
5 | 64 | def __floordiv__(self, scalar): |
7 | 65 | assert is_real(scalar) |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
66 | return type(self)(self.x // scalar, self.y // scalar, self.z // scalar) |
5 | 67 | def __matmul__(self, transformation_matrix): |
68 | return transform(self, transformation_matrix) | |
69 | def __eq__(self, other): | |
13 | 70 | return all( |
71 | abs(a - b) < 1e-8 | |
72 | for a, b in zip(self.coordinates, other.coordinates) | |
73 | ) | |
74 | def __ne__(self, other): | |
75 | return not self.__eq__(other) | |
5 | 76 | def __lt__(self, other): |
77 | return self.coordinates < other.coordinates | |
78 | def __hash__(self): | |
79 | return hash(self.coordinates) | |
80 | ||
81 | class VertexOp: | |
82 | def __init__(self, callable): | |
83 | self.callable = callable | |
84 | def __rmul__(self, coordinate): | |
85 | return self.callable(coordinate) | |
0 | 86 | |
87 | class LineSegment: | |
88 | def __init__(self, v1, v2): | |
89 | self.v1, self.v2 = v1, v2 | |
90 | def __repr__(self): | |
91 | return str.format('LineSegment({!r}, {!r})', self.v1, self.v2) | |
3
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
1
diff
changeset
|
92 | @property |
7 | 93 | def length(self): |
94 | return self.v1.distance_to(self.v2) | |
95 | @property | |
3
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
1
diff
changeset
|
96 | def vertices(self): |
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
1
diff
changeset
|
97 | return self.v1, self.v2 |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
98 | def __len__(self): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
99 | return 2 |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
100 | def __getitem__(self, index): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
101 | return self.vertices[index] |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
102 | |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
103 | class IndexRing: |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
104 | def __init__(self, container): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
105 | self.container = container |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
106 | def __getitem__(self, index): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
107 | return self.container[index % len(self.container)] |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
108 | |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
109 | class Vector(Vertex): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
110 | def __init__(self, x, y, z): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
111 | super().__init__(x, y, z) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
112 | def __repr__(self): |
7 | 113 | return str.format('Vector({!r}, {!r}, {!r})', self.x, self.y, self.z) |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
114 | def length(self): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
115 | from math import sqrt |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
116 | return sqrt(self.x ** 2 + self.y ** 2 + self.z ** 2) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
117 | def normalized(self): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
118 | length = self.length() |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
119 | if length > 0: |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
120 | return Vector(self.x / length, self.y / length, self.z / length) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
121 | else: |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
122 | return Vector(0, 0, 0) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
123 | |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
124 | def dot_product(v1, v2): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
125 | ''' Returns the dot product v1 · v2. ''' |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
126 | return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
127 | |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
128 | def cross_product(v1, v2): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
129 | ''' Returns the cross product v1 × v2. ''' |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
130 | return Vector( |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
131 | x = v1.y * v2.z - v1.z * v2.y, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
132 | y = v1.z * v2.x - v1.x * v2.z, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
133 | z = v1.x * v2.y - v1.y * v2.x, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
134 | ) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
135 | |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
136 | def unit_normal(a, b, c): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
137 | x = Matrix3x3([ |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
138 | 1, a.y, a.z, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
139 | 1, b.y, b.z, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
140 | 1, c.y, c.z, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
141 | ]).determinant() |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
142 | y = Matrix3x3([ |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
143 | a.x, 1, a.z, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
144 | b.x, 1, b.z, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
145 | c.x, 1, c.z, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
146 | ]).determinant() |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
147 | z = Matrix3x3([ |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
148 | a.x, a.y, 1, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
149 | b.x, b.y, 1, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
150 | c.x, c.y, 1, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
151 | ]).determinant() |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
152 | return Vector(x, y, z).normalized() |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
153 | |
13 | 154 | class NoIntersection(Exception): |
155 | pass | |
156 | ||
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
157 | def pairs(iterable, *, count = 2): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
158 | ''' |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
159 | Iterates the given iterable and returns tuples containing `count` |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
160 | sequential values in the iterable. |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
161 | |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
162 | Formally, for a vector A with indices 0…n and pair count k, this |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
163 | function yields: |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
164 | (A₀, A₁, …, Aₖ), |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
165 | (A₁, A₂, …, Aₖ₊₁), |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
166 | …, |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
167 | (Aₙ₋₂, Aₙ₋₁, …, Aₖ₋₂), |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
168 | (Aₙ₋₁, A₀, …, Aₖ₋₁). |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
169 | ''' |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
170 | iterable_count = len(iterable) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
171 | for index in range(iterable_count): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
172 | yield tuple( |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
173 | iterable[(index + offset) % iterable_count] |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
174 | for offset in range(count) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
175 | ) |
0 | 176 | |
1 | 177 | class Polygon: |
178 | def __init__(self, vertices): | |
179 | self.vertices = vertices | |
180 | def __repr__(self): | |
181 | return str.format('Polygon({!r})', self.vertices) | |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
182 | def area(self): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
183 | total = Vector(0, 0, 0) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
184 | for v1, v2 in pairs(self.vertices): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
185 | total += cross_product(v1, v2) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
186 | return dot_product(total, unit_normal(self.vertices[0], self.vertices[1], self.vertices[2])) |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
187 | def centroid(self): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
188 | ... |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
189 | raise NotImplementedError |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
190 | def __getitem__(self, index): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
191 | return self.vertices[index % len(self.vertices)] |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
192 | def __len__(self): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
193 | return len(self.vertices) |
7 | 194 | @property |
195 | def perimeter_lines(self): | |
196 | for v1, v2 in pairs(self.vertices): | |
197 | yield LineSegment(v1, v2) | |
198 | @property | |
12 | 199 | def angles(self): |
200 | from math import acos | |
7 | 201 | for v1, v2, v3 in pairs(self.vertices, count = 3): |
202 | vec1 = (position_vector(v3) - position_vector(v2)).normalized() | |
203 | vec2 = (position_vector(v1) - position_vector(v2)).normalized() | |
204 | cosine = dot_product(vec1, vec2) / vec1.length() / vec2.length() | |
12 | 205 | yield acos(cosine) |
206 | @property | |
207 | def smallest_angle(self): | |
208 | return min( | |
209 | angle_magnitude_key(angle) | |
210 | for angle in self.angles) | |
7 | 211 | @property |
212 | def hairline_ratio(self): | |
213 | lengths = [line.length for line in self.perimeter_lines] | |
214 | return max(lengths) / min(lengths) | |
1 | 215 | |
0 | 216 | def is_real(number): |
217 | return isinstance(number, int) or isinstance(number, float) | |
218 | ||
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
219 | def matrix_indices(): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
220 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
221 | Yields index pairs for matrix iteration |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
222 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
223 | from itertools import product |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
224 | yield from product(range(3), range(3)) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
225 | |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
226 | class Matrix3x3: |
0 | 227 | ''' |
228 | A 3×3 matrix forming the top-left portion of a full 4×4 transformation | |
229 | matrix. | |
230 | ''' | |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
231 | class Row: |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
232 | def __init__(self, matrix_ref, i1, i2, i3): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
233 | self.matrix_ref = matrix_ref |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
234 | self.matrix_indices = i1, i2, i3 |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
235 | def __getitem__(self, row_index): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
236 | return self.matrix_ref[self.matrix_indices[row_index]] |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
237 | def __setitem__(self, row_index, value): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
238 | self.matrix_ref[self.matrix_indices[row_index]] = value |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
239 | def __init__(self, values = None): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
240 | if values is not None: |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
241 | assert(all(is_real(x) for x in values)) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
242 | assert len(values) == 9 |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
243 | self.values = values |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
244 | else: |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
245 | self.values = [1, 0, 0, 0, 1, 0, 0, 0, 1] |
0 | 246 | def __repr__(self): |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
247 | if self != Matrix3x3(): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
248 | return str.format('Matrix3x3({!r})', self.values) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
249 | else: |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
250 | return 'Matrix3x3()' |
0 | 251 | def __getitem__(self, index): |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
252 | if isinstance(index, tuple): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
253 | assert all(k in [0, 1, 2] for k in index) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
254 | return self.values[index[0] * 3 + index[1]] |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
255 | else: |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
256 | return Matrix3x3.Row(self, index * 3, index * 3 + 1, index * 3 + 2) |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
257 | def determinant(self): |
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
258 | return sum([ |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
259 | +(self[0, 0] * self[1, 1] * self[2, 2]), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
260 | +(self[0, 1] * self[1, 2] * self[2, 0]), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
261 | +(self[0, 2] * self[1, 0] * self[2, 1]), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
262 | -(self[0, 2] * self[1, 1] * self[2, 0]), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
263 | -(self[0, 1] * self[1, 0] * self[2, 2]), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
264 | -(self[0, 0] * self[1, 2] * self[2, 1]), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
265 | ]) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
266 | @property |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
267 | def scaling_vector(self): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
268 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
269 | Extracts scaling factors from this transformation matrix. |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
270 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
271 | from math import sqrt |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
272 | return Vector( |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
273 | x = sqrt(self[0, 0] ** 2 + self[1, 0] ** 2 + self[2, 0] ** 2), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
274 | y = sqrt(self[0, 1] ** 2 + self[1, 1] ** 2 + self[2, 1] ** 2), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
275 | z = sqrt(self[0, 2] ** 2 + self[1, 2] ** 2 + self[2, 2] ** 2), |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
276 | ) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
277 | @property |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
278 | def rotation_component(self): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
279 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
280 | Extracts rotation from this matrix. |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
281 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
282 | return self.split()[0] |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
283 | def split(self): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
284 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
285 | Extracts the rotation matrix and scaling vector. |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
286 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
287 | vec = self.scaling_vector |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
288 | return Matrix3x3([ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
289 | self[i, j] / vec.coordinates[j] |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
290 | for i, j in matrix_indices() |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
291 | ]), vec |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
292 | @property |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
293 | def contains_scaling(self): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
294 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
295 | Returns whether this matrix contains scaling factors. |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
296 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
297 | vec = self.scaling_vector |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
298 | return abs((vec.x * vec.y * vec.z) - 1) >= 1e-10 |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
299 | @property |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
300 | def contains_rotation(self): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
301 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
302 | Returns whether this matrix contains rotation factors. |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
303 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
304 | return self.rotation_component != Matrix3x3() |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
305 | def __eq__(self, other): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
306 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
307 | Returns whether two matrices are equivalent. |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
308 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
309 | return all( |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
310 | abs(self[(i, j)] - other[(i, j)]) < 1e-10 |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
311 | for i, j in matrix_indices() |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
312 | ) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
313 | def __matmul__(self, other): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
314 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
315 | Computes the matrix multiplication self × other. |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
316 | ''' |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
317 | return Matrix3x3([ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
318 | sum(self[i, k] * other[k, j] for k in range(3)) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
319 | for i, j in matrix_indices() |
6
6da1e81c5652
Added code to compute areas of triangles and quadrilaterals
Santeri Piippo
parents:
5
diff
changeset
|
320 | ]) |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
321 | def __add__(self, other): |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
322 | return Matrix3x3([ |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
323 | a + b |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
324 | for a, b in zip(self.values, other.values) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
325 | ]) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
326 | def __mul__(self, scalar): |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
327 | return Matrix3x3([ |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
328 | x * scalar |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
329 | for x in self.values |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
330 | ]) |
0 | 331 | |
332 | def complete_matrix(matrix, anchor): | |
333 | ''' | |
334 | Combines a 3×3 matrix and an anchor vertex into a full 4×4 | |
335 | transformation matrix. | |
336 | ''' | |
337 | return [ | |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
338 | matrix[0, 0], matrix[0, 1], matrix[0, 2], anchor.x, |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
339 | matrix[1, 0], matrix[1, 1], matrix[1, 2], anchor.y, |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
340 | matrix[2, 0], matrix[2, 1], matrix[2, 2], anchor.z, |
0 | 341 | 0, 0, 0, 1, |
342 | ] | |
343 | ||
344 | def transform(vertex, transformation_matrix): | |
345 | ''' | |
346 | Transforms a vertex by a 4×4 transformation matrix. | |
347 | ''' | |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
348 | return Vertex( |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
349 | x = transformation_matrix[0] * vertex.x \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
350 | + transformation_matrix[1] * vertex.y \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
351 | + transformation_matrix[2] * vertex.z \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
352 | + transformation_matrix[3], |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
353 | y = transformation_matrix[4] * vertex.x \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
354 | + transformation_matrix[5] * vertex.y \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
355 | + transformation_matrix[6] * vertex.z \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
356 | + transformation_matrix[7], |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
357 | z = transformation_matrix[8] * vertex.x \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
358 | + transformation_matrix[9] * vertex.y \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
359 | + transformation_matrix[10] * vertex.z \ |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
360 | + transformation_matrix[11], |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
7
diff
changeset
|
361 | ) |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
362 | |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
363 | def transform_to_xy(polygon): |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
364 | ''' |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
365 | Transforms the provided polygon into the XY plane. The polygon is |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
366 | assumed to be planar. |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
367 | |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
368 | Implementation is based on this StackOverflow answer: |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
369 | https://math.stackexchange.com/a/476311 |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
370 | ''' |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
371 | v1, v2, v3 = polygon.vertices[:3] |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
372 | a, b = v3 - v2, v1 - v2 |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
373 | normal = cross_product(a, b).normalized() |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
374 | v_matrix = Matrix3x3([ |
15 | 375 | 0, 0, -normal.x, |
376 | 0, 0, -normal.y, | |
377 | normal.x, normal.y, 0, | |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
378 | ]) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
379 | try: |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
380 | rotation_matrix = Matrix3x3() |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
381 | rotation_matrix += v_matrix |
15 | 382 | rotation_matrix += (v_matrix @ v_matrix) * (1 / (1 + normal.z)) |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
383 | except ZeroDivisionError: |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
384 | rotation_matrix = Matrix3x3() |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
385 | full_matrix = complete_matrix(rotation_matrix, Vertex(0, 0, 0)) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
386 | return Polygon([ |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
387 | transform(vertex = vertex, transformation_matrix = full_matrix) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
388 | for vertex in polygon.vertices |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
389 | ]) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
390 | |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
391 | def vector_angle(vec_1, vec_2, normalized = False): |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
392 | from math import acos, pi as π |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
393 | cosine = dot_product(vec_1, vec_2) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
394 | try: |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
395 | cosine /= vec_1.length() * vec_2.length() |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
396 | except ZeroDivisionError: |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
397 | return 0 |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
398 | angle = acos(cosine) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
399 | if normalized and angle > π / 2: |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
400 | angle = π - angle |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
401 | return angle |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
402 | |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
403 | def split_quadrilateral(polygon): |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
404 | assert(len(polygon.vertices) == 4) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
405 | vertices = IndexRing(polygon.vertices) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
406 | for i in (0, 1): |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
407 | a, b = vertices[0 + i], vertices[1 + i] |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
408 | c, d = vertices[2 + i], vertices[3 + i] |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
409 | yield Polygon([a, b, c]), Polygon([b, c, d]) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
410 | |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
411 | def triangle_plane_normal(polygon): |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
412 | assert(len(polygon.vertices) == 3) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
413 | a, b, c = polygon.vertices[:3] |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
414 | return cross_product(b - a, b - c) |