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