Mercurial > touhou
comparison pytouhou/utils/matrix.py @ 28:f405b947624d
Massive sprite updating/matrix handling optimizations
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Fri, 12 Aug 2011 21:40:26 +0200 |
parents | 787d2eb13c2d |
children | e3ba2fa966f6 |
comparison
equal
deleted
inserted
replaced
27:b65d6bc55793 | 28:f405b947624d |
---|---|
1 #TODO: find/learn to use a proper lib | 1 #TODO: find/learn to use a proper lib |
2 | 2 |
3 from math import sin, cos | 3 from math import sin, cos |
4 | 4 |
5 class Matrix(object): | 5 class Matrix(object): |
6 def __init__(self): | 6 def __init__(self, data=None): |
7 self.data = [[0] * 4 for i in xrange(4)] | 7 self.data = data or [[0] * 4 for i in xrange(4)] |
8 | 8 |
9 | 9 |
10 def mult(self, other_matrix): | 10 def mult(self, other_matrix): |
11 result = Matrix() | 11 d1 = self.data |
12 for i in xrange(4): | 12 d2 = other_matrix.data |
13 for j in xrange(4): | 13 return Matrix([[sum(d1[i][a] * d2[a][j] for a in xrange(4)) for j in xrange(4)] for i in xrange(4)]) |
14 result.data[i][j] = sum(self.data[i][a] * other_matrix.data[a][j] for a in xrange(4)) | 14 |
15 return result | 15 |
16 def flip(self): | |
17 self.data[0][:] = (-x for x in self.data[0]) | |
18 | |
19 | |
20 def scale(self, x, y, z): | |
21 d1 = self.data | |
22 d1[0][:] = (a * x for a in d1[0]) | |
23 d1[1][:] = (a * y for a in d1[1]) | |
24 d1[2][:] = (a * z for a in d1[2]) | |
25 | |
26 | |
27 def translate(self, x, y, z): | |
28 d1 = self.data | |
29 a, b, c = (v * m for v, m in zip(d1[3][:3], (x, y, z))) | |
30 d1[0][:] = (v + a for v in d1[0]) | |
31 d1[1][:] = (v + b for v in d1[1]) | |
32 d1[2][:] = (v + c for v in d1[2]) | |
33 | |
34 | |
35 def rotate_x(self, angle): | |
36 d1 = self.data | |
37 cos_a = cos(angle) | |
38 sin_a = sin(angle) | |
39 a = [cos_a * d1[1][i] - sin_a * d1[2][i] for i in range(4)] | |
40 b = [sin_a * d1[1][i] + cos_a * d1[2][i] for i in range(4)] | |
41 d1[1][:] = a | |
42 d1[2][:] = b | |
43 | |
44 | |
45 def rotate_y(self, angle): | |
46 #TODO: check | |
47 d1 = self.data | |
48 cos_a = cos(angle) | |
49 sin_a = sin(angle) | |
50 a = [cos_a * d1[0][i] - sin_a * d1[2][i] for i in range(4)] | |
51 b = [sin_a * d1[0][i] + cos_a * d1[2][i] for i in range(4)] | |
52 d1[0][:] = a | |
53 d1[2][:] = b | |
54 | |
55 | |
56 def rotate_z(self, angle): | |
57 d1 = self.data | |
58 cos_a = cos(angle) | |
59 sin_a = sin(angle) | |
60 a = [cos_a * d1[0][i] - sin_a * d1[1][i] for i in range(4)] | |
61 b = [sin_a * d1[0][i] + cos_a * d1[1][i] for i in range(4)] | |
62 d1[0][:] = a | |
63 d1[1][:] = b | |
16 | 64 |
17 | 65 |
18 @classmethod | 66 @classmethod |
19 def get_translation_matrix(cls, x, y, z): | 67 def get_translation_matrix(cls, x, y, z): |
20 matrix = cls() | 68 return cls([[1., 0., 0., x], |
21 matrix.data[0][0] = 1 | 69 [0., 1., 0., y], |
22 matrix.data[1][1] = 1 | 70 [0., 0., 1., z], |
23 matrix.data[2][2] = 1 | 71 [0., 0., 0., 1.]]) |
24 matrix.data[3][3] = 1 | |
25 matrix.data[0][3] = x | |
26 matrix.data[1][3] = y | |
27 matrix.data[2][3] = z | |
28 return matrix | |
29 | 72 |
30 | 73 |
31 @classmethod | 74 @classmethod |
32 def get_scaling_matrix(cls, x, y, z): | 75 def get_scaling_matrix(cls, x, y, z): |
33 matrix = cls() | 76 return cls([[x, 0., 0., 0.], |
34 matrix.data[0][0] = x | 77 [0., y, 0., 0.], |
35 matrix.data[1][1] = y | 78 [0., 0., z, 0.], |
36 matrix.data[2][2] = z | 79 [0., 0., 0., 1.]]) |
37 matrix.data[3][3] = 1 | |
38 return matrix | |
39 | 80 |
40 | 81 |
41 @classmethod | 82 @classmethod |
42 def get_rotation_matrix(cls, angle, axis): | 83 def get_rotation_matrix(cls, angle, axis): |
43 """Only handles axis = x, y or z.""" | 84 """Only handles axis = x, y or z.""" |
44 matrix = cls() | 85 cos_a = cos(angle) |
45 matrix.data[3][3] = 1 | 86 sin_a = sin(angle) |
46 if axis == 'x': | 87 if axis == 'x': |
47 matrix.data[0][0] = 1 | 88 return Matrix([[ 1., 0., 0., 0.], |
48 matrix.data[1][1] = cos(angle) | 89 [ 0., cos_a, -sin_a, 0.], |
49 matrix.data[1][2] = -sin(angle) | 90 [ 0., sin_a, cos_a, 0.], |
50 matrix.data[2][1] = sin(angle) | 91 [ 0., 0., 0., 1.]]) |
51 matrix.data[2][2] = cos(angle) | |
52 elif axis == 'y': | 92 elif axis == 'y': |
53 matrix.data[0][0] = cos(angle) | 93 return Matrix([[ cos_a, 0., sin_a, 0.], |
54 matrix.data[0][2] = sin(angle) | 94 [ 0., 1., 0., 0.], |
55 matrix.data[2][0] = -sin(angle) | 95 [-sin_a, 0., cos_a, 0.], |
56 matrix.data[2][2] = cos(angle) | 96 [ 0., 0., 0., 1.]]) |
57 matrix.data[1][1] = 1 | |
58 elif axis == 'z': | 97 elif axis == 'z': |
59 matrix.data[0][0] = cos(angle) | 98 return Matrix([[ cos_a, -sin_a, 0., 0.], |
60 matrix.data[0][1] = -sin(angle) | 99 [ sin_a, cos_a, 0., 0.], |
61 matrix.data[1][0] = sin(angle) | 100 [ 0., 0., 1., 0.], |
62 matrix.data[1][1] = cos(angle) | 101 [ 0., 0., 0., 1.]]) |
63 matrix.data[2][2] = 1 | |
64 else: | 102 else: |
65 raise Exception | 103 raise Exception |
66 return matrix | 104 |