1
1
cimport cython
2
2
3
3
cdef class Vec2:
4
- cdef double x, y
4
+ cdef py_float x, y
5
5
6
6
7
7
# <TEMPLATE_BEGIN>
8
- from libc.math cimport atan2, sin, cos, sqrt , NAN
8
+ from libc.math cimport atan2l, sinl, cosl, sqrtl , NAN
9
9
10
10
11
11
@ cython.auto_pickle (True )
12
12
@ cython.freelist (1024 )
13
13
@cython.no_gc
14
14
@cython.final
15
15
cdef class Transform2D:
16
- cdef double xx, xy
17
- cdef double yx, yy
18
- cdef double ox, oy
16
+ cdef py_float xx, xy
17
+ cdef py_float yx, yy
18
+ cdef py_float ox, oy
19
19
20
20
21
21
cdef inline void identity(self ) noexcept:
@@ -28,7 +28,7 @@ cdef class Transform2D:
28
28
self .identity()
29
29
30
30
# <OVERLOAD>
31
- cdef void __init__ (self , double xx, double xy, double yx, double yy, double ox, double oy) noexcept:
31
+ cdef void __init__ (self , py_float xx, py_float xy, py_float yx, py_float yy, py_float ox, py_float oy) noexcept:
32
32
self .xx = xx
33
33
self .xy = xy
34
34
self .yx = yx
@@ -61,9 +61,9 @@ cdef class Transform2D:
61
61
return t
62
62
63
63
@staticmethod
64
- def rotating(float rotation , /, Vec2 origin = None ) -> Transform2D:
65
- cdef double c = cos (rotation)
66
- cdef double s = sin (rotation)
64
+ def rotating(py_float rotation , /, Vec2 origin = None ) -> Transform2D:
65
+ cdef py_float c = cosl (rotation)
66
+ cdef py_float s = sinl (rotation)
67
67
cdef Transform2D t = Transform2D.__new__ (Transform2D)
68
68
t.xx = c
69
69
t.xy = s
@@ -109,14 +109,25 @@ cdef class Transform2D:
109
109
self .yx != (< Transform2D> other).yx or self .yy != (< Transform2D> other).yy or \
110
110
self .ox != (< Transform2D> other).ox or self .oy != (< Transform2D> other).oy
111
111
112
- def is_close (self , Transform2D other , /, double rel_tol = DEFAULT_RELATIVE_TOLERANCE, double abs_tol = DEFAULT_ABSOLUTE_TOLERANCE) -> bool:
112
+ def is_close (self , Transform2D other , /, py_float rel_tol = DEFAULT_RELATIVE_TOLERANCE, py_float abs_tol = DEFAULT_ABSOLUTE_TOLERANCE) -> bool:
113
113
return is_close(self.xx , other.xx , rel_tol , abs_tol ) and \
114
114
is_close(self.xy , other.xy , rel_tol , abs_tol ) and \
115
115
is_close(self.yx , other.yx , rel_tol , abs_tol ) and \
116
116
is_close(self.yy , other.yy , rel_tol , abs_tol ) and \
117
117
is_close(self.ox , other.ox , rel_tol , abs_tol ) and \
118
118
is_close(self.oy , other.oy , rel_tol , abs_tol )
119
119
120
+ #TODO: Better hashing
121
+ def __hash__(self ) -> py_int:
122
+ cdef py_int h = 0
123
+ h ^= bitcast_float(self.xx )
124
+ h ^= rotl_ratio(bitcast_float(self.xy ), 1, 6)
125
+ h ^= rotl_ratio(bitcast_float(self.yx ), 2, 6)
126
+ h ^= rotl_ratio(bitcast_float(self.yy ), 3, 6)
127
+ h ^= rotl_ratio(bitcast_float(self.ox ), 4, 6)
128
+ h ^= rotl_ratio(bitcast_float(self.oy ), 5, 6)
129
+ return h
130
+
120
131
@property
121
132
def x(self ) -> Vec2:
122
133
cdef Vec2 vec = Vec2.__new__ (Vec2)
@@ -153,7 +164,7 @@ cdef class Transform2D:
153
164
self.ox = value.x
154
165
self.oy = value.y
155
166
156
- def __getitem__(self , int item ) -> Vec2:
167
+ def __getitem__(self , py_int item ) -> Vec2:
157
168
cdef Vec2 vec = Vec2.__new__ (Vec2)
158
169
159
170
if item == 0:
@@ -170,7 +181,7 @@ cdef class Transform2D:
170
181
171
182
return vec
172
183
173
- def __setitem__(self , int key , Vec2 value ) -> None:
184
+ def __setitem__(self , py_int key , Vec2 value ) -> None:
174
185
if key == 0:
175
186
self.xx = value.x
176
187
self.xy = value.y
@@ -183,19 +194,19 @@ cdef class Transform2D:
183
194
else:
184
195
raise IndexError(key )
185
196
186
- def __len__(self ) -> int :
197
+ def __len__(self ) -> py_int :
187
198
return 3
188
199
189
- cdef inline double tdotx(self , double x , double y ) noexcept:
200
+ cdef inline py_float tdotx(self , py_float x , py_float y ) noexcept:
190
201
return x * self.xx + y * self.yx
191
202
192
- cdef inline double mulx(self , double x , double y ) noexcept:
203
+ cdef inline py_float mulx(self , py_float x , py_float y ) noexcept:
193
204
return self.tdotx(x , y ) + self.ox
194
205
195
- cdef inline double tdoty(self , double x , double y ) noexcept:
206
+ cdef inline py_float tdoty(self , py_float x , py_float y ) noexcept:
196
207
return x * self.xy + y * self.yy
197
208
198
- cdef inline double muly(self , double x , double y ) noexcept:
209
+ cdef inline py_float muly(self , py_float x , py_float y ) noexcept:
199
210
return self.tdoty(x , y ) + self.oy
200
211
201
212
def __mul__(self , Vec2 other ) -> Vec2:
@@ -242,15 +253,15 @@ cdef class Transform2D:
242
253
self.ox = other.mulx(self .ox, self .oy)
243
254
self.oy = other.muly(self .ox, self .oy)
244
255
245
- cdef inline double _determinant(self ) noexcept:
256
+ cdef inline py_float _determinant(self ) noexcept:
246
257
return self.xx * self.yy - self.xy * self.yx
247
258
248
259
@property
249
- def determinant(self ) -> float :
260
+ def determinant(self ) -> py_float :
250
261
return self._determinant()
251
262
252
263
def __invert__(self ) -> Transform2D:
253
- cdef double i_det = 1.0 / self ._determinant()
264
+ cdef py_float i_det = 1.0 / self ._determinant()
254
265
cdef Transform2D t = Transform2D.__new__ (Transform2D)
255
266
t.xx = self .yy * + i_det
256
267
t.xy = self .xy * - i_det
@@ -261,45 +272,45 @@ cdef class Transform2D:
261
272
return t
262
273
263
274
264
- cdef inline double get_rotation(self ) noexcept:
265
- return atan2 (self.xy , self.xx )
275
+ cdef inline py_float get_rotation(self ) noexcept:
276
+ return atan2l (self.xy , self.xx )
266
277
267
- cdef inline void set_rotation(self , double rotation ) noexcept:
268
- cdef double scale_x = self .get_scale_x()
269
- cdef double scale_y = self .get_scale_y()
270
- cdef double c = cos (rotation)
271
- cdef double s = sin (rotation)
278
+ cdef inline void set_rotation(self , py_float rotation ) noexcept:
279
+ cdef py_float scale_x = self .get_scale_x()
280
+ cdef py_float scale_y = self .get_scale_y()
281
+ cdef py_float c = cosl (rotation)
282
+ cdef py_float s = sinl (rotation)
272
283
self.xx = c
273
284
self.xy = s
274
285
self.yx = - s
275
286
self.yy = c
276
287
self.set_scale_x(scale_x )
277
288
self.set_scale_y(scale_y )
278
289
279
- cdef inline double get_scale_x(self ) noexcept:
280
- return sqrt (self.xx * self.xx + self.xy * self.xy )
290
+ cdef inline py_float get_scale_x(self ) noexcept:
291
+ return sqrtl (self.xx * self.xx + self.xy * self.xy )
281
292
282
- cdef inline double get_scale_y(self ) noexcept:
283
- cdef double det = self ._determinant()
284
- cdef double det_sign = 1.0 if det > 0.0 else - 1.0 if det < 0.0 else 0.0 if det == 0.0 else NAN
285
- return sqrt (self.yx * self.yx + self.yy * self.yy ) * det_sign
293
+ cdef inline py_float get_scale_y(self ) noexcept:
294
+ cdef py_float det = self ._determinant()
295
+ cdef py_float det_sign = 1.0 if det > 0.0 else - 1.0 if det < 0.0 else 0.0 if det == 0.0 else NAN
296
+ return sqrtl (self.yx * self.yx + self.yy * self.yy ) * det_sign
286
297
287
- cdef inline void set_scale_x(self , double value ) noexcept:
288
- cdef double m = value / sqrt (self .xx * self .xx + self .xy * self .xy)
298
+ cdef inline void set_scale_x(self , py_float value ) noexcept:
299
+ cdef py_float m = value / sqrtl (self .xx * self .xx + self .xy * self .xy)
289
300
self.xx *= m
290
301
self.xy *= m
291
302
292
- cdef inline void set_scale_y(self , double value ) noexcept:
293
- cdef double m = value / sqrt (self .yx * self .yx + self .yy * self .yy)
303
+ cdef inline void set_scale_y(self , py_float value ) noexcept:
304
+ cdef py_float m = value / sqrtl (self .yx * self .yx + self .yy * self .yy)
294
305
self.yx *= m
295
306
self.yy *= m
296
307
297
308
@property
298
- def rotation(self ) -> float :
309
+ def rotation(self ) -> py_float :
299
310
return self.get_rotation()
300
311
301
312
@rotation.setter
302
- def rotation(self , float value ) -> None:
313
+ def rotation(self , py_float value ) -> None:
303
314
self.set_rotation(value )
304
315
305
316
# @property
@@ -330,11 +341,11 @@ cdef class Transform2D:
330
341
t.translate_ip(translation )
331
342
return t
332
343
333
- def rotate_ip(self , float rotation , /) -> Transform2D:
344
+ def rotate_ip(self , py_float rotation , /) -> Transform2D:
334
345
self.__imul__(Transform2D.rotation(rotation ))
335
346
return self
336
347
337
- def rotated(self , float rotation , /) -> Transform2D:
348
+ def rotated(self , py_float rotation , /) -> Transform2D:
338
349
cdef Transform2D t = self .copy()
339
350
t.rotate_ip(rotation )
340
351
return t
0 commit comments