|
1 class Vertex: |
|
2 def __init__(self, x, y, z): |
|
3 self.x, self.y, self.z = x, y, z |
|
4 def __repr__(self): |
|
5 return str.format('Vertex({!r}, {!r}, {!r})', self.x, self.y, self.z) |
|
6 def distance_to(self, other): |
|
7 # can't use hypot because of 3 arguments |
|
8 from math import sqrt |
|
9 return sqrt( |
|
10 (self.x - other.x) ** 2 + |
|
11 (self.y - other.y) ** 2 + |
|
12 (self.z - other.z) ** 2 |
|
13 ) |
|
14 |
|
15 class LineSegment: |
|
16 def __init__(self, v1, v2): |
|
17 self.v1, self.v2 = v1, v2 |
|
18 def __repr__(self): |
|
19 return str.format('LineSegment({!r}, {!r})', self.v1, self.v2) |
|
20 |
|
21 def is_real(number): |
|
22 return isinstance(number, int) or isinstance(number, float) |
|
23 |
|
24 class TransformationMatrix: |
|
25 ''' |
|
26 A 3×3 matrix forming the top-left portion of a full 4×4 transformation |
|
27 matrix. |
|
28 ''' |
|
29 def __init__(self, values): |
|
30 assert(all(is_real(x) for x in values)) |
|
31 assert len(values) == 9 |
|
32 self.values = values |
|
33 def __repr__(self): |
|
34 return str.format('TransformationMatrix({!r})', self.values) |
|
35 def __getitem__(self, index): |
|
36 return self.values[index] |
|
37 |
|
38 def complete_matrix(matrix, anchor): |
|
39 ''' |
|
40 Combines a 3×3 matrix and an anchor vertex into a full 4×4 |
|
41 transformation matrix. |
|
42 ''' |
|
43 return [ |
|
44 matrix[0], matrix[1], matrix[2], anchor.x, |
|
45 matrix[3], matrix[4], matrix[5], anchor.y, |
|
46 matrix[6], matrix[7], matrix[8], anchor.z, |
|
47 0, 0, 0, 1, |
|
48 ] |
|
49 |
|
50 def transform(vertex, transformation_matrix): |
|
51 ''' |
|
52 Transforms a vertex by a 4×4 transformation matrix. |
|
53 ''' |
|
54 u = transformation_matrix[0] * vertex.x \ |
|
55 + transformation_matrix[1] * vertex.y \ |
|
56 + transformation_matrix[2] * vertex.z \ |
|
57 + transformation_matrix[3] |
|
58 v = transformation_matrix[4] * vertex.x \ |
|
59 + transformation_matrix[5] * vertex.y \ |
|
60 + transformation_matrix[6] * vertex.z \ |
|
61 + transformation_matrix[7] |
|
62 w = transformation_matrix[8] * vertex.x \ |
|
63 + transformation_matrix[9] * vertex.y \ |
|
64 + transformation_matrix[10] * vertex.z \ |
|
65 + transformation_matrix[11] |
|
66 return Vertex(u, v, w) |