comparison pytouhou/utils/matrix.pyx @ 523:6e3b3d5d4691

Make matrix a struct.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 18 Dec 2013 17:53:29 +0100
parents 26c082870dcf
children db28538cd399
comparison
equal deleted inserted replaced
522:e8496e5ba056 523:6e3b3d5d4691
15 from libc.math cimport sin, cos 15 from libc.math cimport sin, cos
16 from libc.stdlib cimport malloc, free 16 from libc.stdlib cimport malloc, free
17 from libc.string cimport memcpy 17 from libc.string cimport memcpy
18 18
19 19
20 cdef float[16] identity 20 cdef Matrix identity
21 identity[:] = [1, 0, 0, 0, 21 identity = Matrix(1, 0, 0, 0,
22 0, 1, 0, 0, 22 0, 1, 0, 0,
23 0, 0, 1, 0, 23 0, 0, 1, 0,
24 0, 0, 0, 1] 24 0, 0, 0, 1)
25 25
26 26
27 cdef class Matrix: 27 cdef Matrix *new_matrix(Matrix *data) nogil:
28 def __init__(self, data=None): 28 mat = <Matrix*> malloc(sizeof(Matrix))
29 if data is not None: 29 memcpy(mat, data, sizeof(Matrix))
30 for i in xrange(16): 30 return mat
31 self.data[i] = data[i]
32 else:
33 memcpy(self.data, identity, 16 * sizeof(float))
34 31
35 32
36 def __mul__(Matrix self, Matrix other): 33 cdef Matrix *new_identity() nogil:
37 cdef float *d1, *d2, *d3 34 return new_matrix(&identity)
38
39 out = Matrix()
40 d1 = self.data
41 d2 = other.data
42 d3 = out.data
43 for i in xrange(4):
44 for j in xrange(4):
45 d3[4*i+j] = 0
46 for k in xrange(4):
47 d3[4*i+j] += d1[4*i+k] * d2[4*k+j]
48 return out
49 35
50 36
51 cdef void flip(self) nogil: 37 cdef void mul(Matrix *mat1, Matrix *mat2) nogil:
52 cdef float *data 38 cdef float *d3
53 39
54 data = self.data 40 out = <Matrix*> malloc(sizeof(Matrix))
55 for i in xrange(4): 41 d1 = <float*>mat1
56 data[i] = -data[i] 42 d2 = <float*>mat2
43 d3 = <float*>out
44 for i in xrange(4):
45 for j in xrange(4):
46 d3[4*i+j] = 0
47 for k in xrange(4):
48 d3[4*i+j] += d1[4*i+k] * d2[4*k+j]
49 memcpy(mat1, out, sizeof(Matrix))
50 free(out)
57 51
58 52
59 cdef void scale(self, float x, float y, float z) nogil: 53 cdef void flip(Matrix *mat) nogil:
60 cdef float *data, coordinate[3] 54 data = <float*>mat
61 55 for i in xrange(4):
62 data = self.data 56 data[i] = -data[i]
63 coordinate[0] = x
64 coordinate[1] = y
65 coordinate[2] = z
66
67 for i in xrange(3):
68 for j in xrange(4):
69 data[4*i+j] *= coordinate[i]
70 57
71 58
72 cdef void scale2d(self, float x, float y) nogil: 59 cdef void scale(Matrix *mat, float x, float y, float z) nogil:
73 cdef float *data 60 cdef float coordinate[3]
74 61
75 data = self.data 62 data = <float*>mat
76 for i in xrange(4): 63 coordinate[0] = x
77 data[ i] *= x 64 coordinate[1] = y
78 data[4+i] *= y 65 coordinate[2] = z
66
67 for i in xrange(3):
68 for j in xrange(4):
69 data[4*i+j] *= coordinate[i]
79 70
80 71
81 cdef void translate(self, float x, float y, float z) nogil: 72 cdef void scale2d(Matrix *mat, float x, float y) nogil:
82 cdef float *data, coordinate[3], item[3] 73 data = <float*>mat
83 74 for i in xrange(4):
84 data = self.data 75 data[ i] *= x
85 coordinate[0] = x 76 data[4+i] *= y
86 coordinate[1] = y
87 coordinate[2] = z
88 for i in xrange(3):
89 item[i] = data[12+i] * coordinate[i]
90
91 for i in xrange(3):
92 for j in xrange(4):
93 data[4*i+j] += item[i]
94 77
95 78
96 cdef void rotate_x(self, float angle) nogil: 79 cdef void translate(Matrix *mat, float x, float y, float z) nogil:
97 cdef float cos_a, sin_a 80 cdef float offset[3], item[3]
98 cdef float lines[8], *data
99 81
100 data = self.data 82 offset[0] = x
101 cos_a = cos(angle) 83 offset[1] = y
102 sin_a = sin(angle) 84 offset[2] = z
103 for i in xrange(8): 85
104 lines[i] = data[i+4] 86 data = <float*>mat
105 for i in xrange(4): 87 for i in xrange(3):
106 data[4+i] = cos_a * lines[i] - sin_a * lines[4+i] 88 item[i] = data[12+i] * offset[i]
107 data[8+i] = sin_a * lines[i] + cos_a * lines[4+i] 89
90 for i in xrange(3):
91 for j in xrange(4):
92 data[4*i+j] += item[i]
108 93
109 94
110 cdef void rotate_y(self, float angle) nogil: 95 cdef void translate2d(Matrix *mat, float x, float y) nogil:
111 cdef float cos_a, sin_a 96 translate(mat, x, y, 0)
112 cdef float lines[8], *data
113
114 data = self.data
115 cos_a = cos(angle)
116 sin_a = sin(angle)
117 for i in xrange(4):
118 lines[i] = data[i]
119 lines[i+4] = data[i+8]
120 for i in xrange(4):
121 data[ i] = cos_a * lines[i] + sin_a * lines[4+i]
122 data[8+i] = -sin_a * lines[i] + cos_a * lines[4+i]
123 97
124 98
125 cdef void rotate_z(self, float angle) nogil: 99 cdef void rotate_x(Matrix *mat, float angle) nogil:
126 cdef float cos_a, sin_a 100 cdef float cos_a, sin_a
127 cdef float lines[8], *data 101 cdef float lines[8]
128 102
129 data = self.data 103 data = <float*>mat
130 cos_a = cos(angle) 104 cos_a = cos(angle)
131 sin_a = sin(angle) 105 sin_a = sin(angle)
132 for i in xrange(8): 106 for i in xrange(8):
133 lines[i] = data[i] 107 lines[i] = data[i+4]
134 for i in xrange(4): 108 for i in xrange(4):
135 data[ i] = cos_a * lines[i] - sin_a * lines[4+i] 109 data[4+i] = cos_a * lines[i] - sin_a * lines[4+i]
136 data[4+i] = sin_a * lines[i] + cos_a * lines[4+i] 110 data[8+i] = sin_a * lines[i] + cos_a * lines[4+i]
111
112
113 cdef void rotate_y(Matrix *mat, float angle) nogil:
114 cdef float cos_a, sin_a
115 cdef float lines[8]
116
117 data = <float*>mat
118 cos_a = cos(angle)
119 sin_a = sin(angle)
120 for i in xrange(4):
121 lines[i] = data[i]
122 lines[i+4] = data[i+8]
123 for i in xrange(4):
124 data[ i] = cos_a * lines[i] + sin_a * lines[4+i]
125 data[8+i] = -sin_a * lines[i] + cos_a * lines[4+i]
126
127
128 cdef void rotate_z(Matrix *mat, float angle) nogil:
129 cdef float cos_a, sin_a
130 cdef float lines[8]
131
132 data = <float*>mat
133 cos_a = cos(angle)
134 sin_a = sin(angle)
135 for i in xrange(8):
136 lines[i] = data[i]
137 for i in xrange(4):
138 data[ i] = cos_a * lines[i] - sin_a * lines[4+i]
139 data[4+i] = sin_a * lines[i] + cos_a * lines[4+i]