Mercurial > pygame
annotate src/math.c @ 3194:9fcb7abf3185 default tip
Remove some gcc 4.7.2 compiler warnings
| author | Lenard Lindstrom <len-l@telus.net> |
|---|---|
| date | Tue, 23 Apr 2013 19:53:36 -0700 |
| parents | 42e2bde1a12c |
| children |
| rev | line source |
|---|---|
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1 |
| 1994 | 2 /* |
| 3 pygame - Python Game Library | |
| 4 | |
| 5 This library is free software; you can redistribute it and/or | |
| 6 modify it under the terms of the GNU Library General Public | |
| 7 License as published by the Free Software Foundation; either | |
| 8 version 2 of the License, or (at your option) any later version. | |
| 9 | |
| 10 This library is distributed in the hope that it will be useful, | |
| 11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 Library General Public License for more details. | |
| 14 | |
| 15 You should have received a copy of the GNU Library General Public | |
| 16 License along with this library; if not, write to the Free | |
| 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 18 | |
| 19 */ | |
| 20 | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
21 /* Adjust gcc 4.4 optimization for floating point on x86-32 PCs running Linux. |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
22 * This addresses bug 52: |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
23 * http://pygame.motherhamster.org/bugzilla/show_bug.cgi?id=52 |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
24 */ |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
25 #if defined(__GNUC__) && defined(__linux__) && defined(__i386__) && \ |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
26 __SIZEOF_POINTER__ == 4 && __GNUC__ == 4 && __GNUC_MINOR__ == 4 |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
27 #pragma GCC optimize ("float-store") |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
28 #endif |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
29 |
| 1994 | 30 #define PYGAMEAPI_MATH_INTERNAL |
|
2071
87541598228a
remove distracting "'PyGAME_C_API' defined but not used" gcc warnings from Pygame build
Lenard Lindstrom <len-l@telus.net>
parents:
2035
diff
changeset
|
31 #define NO_PYGAME_C_API |
| 1994 | 32 #include "doc/math_doc.h" |
| 33 #include "pygame.h" | |
| 34 #include "structmember.h" | |
| 35 #include "pgcompat.h" | |
| 36 #include <float.h> | |
| 37 #include <math.h> | |
| 1997 | 38 #include <stddef.h> |
| 2024 | 39 #include <string.h> |
| 1994 | 40 |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
41 /* on some windows platforms math.h doesn't define M_PI */ |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
42 #ifndef M_PI |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
43 #define M_PI 3.14159265358979323846 |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
44 #endif |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
45 |
| 2024 | 46 #define VECTOR_EPSILON (1e-6) |
| 1994 | 47 #define VECTOR_MAX_SIZE (4) |
| 48 #define STRING_BUF_SIZE (100) | |
| 49 #define SWIZZLE_ERR_NO_ERR 0 | |
| 50 #define SWIZZLE_ERR_DOUBLE_IDX 1 | |
| 51 #define SWIZZLE_ERR_EXTRACTION_ERR 2 | |
| 52 | |
| 53 #define OP_ADD 1 | |
| 2024 | 54 /* #define OP_IADD 2 */ |
| 1994 | 55 #define OP_SUB 3 |
| 2024 | 56 /* #define OP_ISUB 4 */ |
| 1994 | 57 #define OP_MUL 5 |
| 2024 | 58 /* #define OP_IMUL 6 */ |
| 1994 | 59 #define OP_DIV 7 |
| 2024 | 60 /* #define OP_IDIV 8 */ |
| 1994 | 61 #define OP_FLOOR_DIV 9 |
| 2024 | 62 /* #define OP_IFLOOR_DIV 10 */ |
| 1994 | 63 #define OP_MOD 11 |
| 2024 | 64 #define OP_INPLACE 16 |
| 1994 | 65 #define OP_ARG_REVERSE 32 |
| 66 #define OP_ARG_UNKNOWN 64 | |
| 67 #define OP_ARG_VECTOR 128 | |
| 68 #define OP_ARG_NUMBER 256 | |
| 69 | |
| 70 static PyTypeObject PyVector2_Type; | |
| 71 static PyTypeObject PyVector3_Type; | |
| 72 static PyTypeObject PyVectorElementwiseProxy_Type; | |
| 73 static PyTypeObject PyVectorIter_Type; | |
| 74 | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
75 #define PyVector2_Check(x) (Py_TYPE(x) == &PyVector2_Type) |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
76 #define PyVector3_Check(x) (Py_TYPE(x) == &PyVector3_Type) |
| 1994 | 77 #define PyVector_Check(x) (PyVector2_Check(x) || PyVector3_Check(x)) |
| 78 #define vector_elementwiseproxy_Check(x) \ | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
79 (Py_TYPE(x) == &PyVectorElementwiseProxy_Type) |
| 1994 | 80 |
| 81 #define DEG2RAD(angle) ((angle) * M_PI / 180.) | |
| 82 #define RAD2DEG(angle) ((angle) * 180. / M_PI) | |
| 83 | |
| 84 typedef struct | |
| 85 { | |
| 86 PyObject_HEAD | |
| 87 double *coords; /* Coordinates */ | |
| 88 unsigned int dim; /* Dimension of the vector */ | |
| 89 double epsilon; /* Small value for comparisons */ | |
| 90 } PyVector; | |
| 91 | |
| 92 typedef struct { | |
| 93 PyObject_HEAD | |
| 94 long it_index; | |
| 95 PyVector *vec; | |
| 96 } vectoriter; | |
| 97 | |
| 98 typedef struct { | |
| 99 PyObject_HEAD | |
| 100 PyVector *vec; | |
| 101 } vector_elementwiseproxy; | |
| 102 | |
| 103 | |
| 104 /* further forward declerations */ | |
| 105 /* generic helper functions */ | |
| 106 static int RealNumber_Check(PyObject *obj); | |
| 107 static double PySequence_GetItem_AsDouble(PyObject *seq, Py_ssize_t index); | |
| 108 static int PySequence_AsVectorCoords(PyObject *seq, double *coords, const size_t size); | |
| 109 static int PyVectorCompatible_Check(PyObject *obj, int dim); | |
| 110 static double _scalar_product(const double *coords1, const double *coords2, int size); | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
111 static int get_double_from_unicode_slice(PyObject *unicode_obj, |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
112 Py_ssize_t idx1, Py_ssize_t idx2, |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
113 double *val); |
| 2024 | 114 static int _vector_find_string_helper(PyObject *str_obj, const char *substr, |
| 115 Py_ssize_t start, Py_ssize_t end); | |
| 116 static int _vector_coords_from_string(PyObject *str, char **delimiter, | |
| 117 double *coords, Py_ssize_t dim); | |
| 1994 | 118 |
| 119 /* generic vector functions */ | |
| 120 static PyObject *PyVector_NEW(int dim); | |
| 121 static void vector_dealloc(PyVector* self); | |
| 122 static PyObject *vector_generic_math(PyObject *o1, PyObject *o2, int op); | |
| 123 static PyObject *vector_add(PyObject *o1, PyObject *o2); | |
| 124 static PyObject *vector_sub(PyObject *o1, PyObject *o2); | |
| 125 static PyObject *vector_mul(PyObject *o1, PyObject *o2); | |
| 126 static PyObject *vector_div(PyVector *self, PyObject *other); | |
| 127 static PyObject *vector_floor_div(PyVector *self, PyObject *other); | |
| 128 static PyObject *vector_inplace_add(PyVector *self, PyObject *other); | |
| 129 static PyObject *vector_inplace_sub(PyVector *self, PyObject *other); | |
| 130 static PyObject *vector_inplace_mul(PyVector *self, PyObject *other); | |
| 131 static PyObject *vector_inplace_div(PyVector *self, PyObject *other); | |
| 132 static PyObject *vector_inplace_floor_div(PyVector *self, PyObject *other); | |
| 133 static PyObject *vector_neg(PyVector *self); | |
| 134 static PyObject *vector_pos(PyVector *self); | |
| 135 static int vector_nonzero(PyVector *self); | |
| 136 static Py_ssize_t vector_len(PyVector *self); | |
| 137 static PyObject *vector_GetItem(PyVector *self, Py_ssize_t index); | |
| 138 static int vector_SetItem(PyVector *self, Py_ssize_t index, PyObject *value); | |
| 139 static PyObject *vector_GetSlice(PyVector *self, Py_ssize_t ilow, Py_ssize_t ihigh); | |
| 140 static int vector_SetSlice(PyVector *self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v); | |
| 141 static PyObject *vector_getx (PyVector *self, void *closure); | |
| 142 static PyObject *vector_gety (PyVector *self, void *closure); | |
| 143 static PyObject *vector_getz (PyVector *self, void *closure); | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
144 #ifdef PYGAME_MATH_VECTOR_HAVE_W |
| 1994 | 145 static PyObject *vector_getw (PyVector *self, void *closure); |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
146 #endif |
| 1994 | 147 static int vector_setx (PyVector *self, PyObject *value, void *closure); |
| 148 static int vector_sety (PyVector *self, PyObject *value, void *closure); | |
| 149 static int vector_setz (PyVector *self, PyObject *value, void *closure); | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
150 #ifdef PYGAME_MATH_VECTOR_HAVE_W |
| 1994 | 151 static int vector_setw (PyVector *self, PyObject *value, void *closure); |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
152 #endif |
| 2024 | 153 static PyObject *vector_richcompare(PyObject *o1, PyObject *o2, int op); |
| 1994 | 154 static PyObject *vector_length(PyVector *self); |
| 155 static PyObject *vector_length_squared(PyVector *self); | |
| 156 static PyObject *vector_normalize(PyVector *self); | |
| 157 static PyObject *vector_normalize_ip(PyVector *self); | |
| 158 static PyObject *vector_dot(PyVector *self, PyObject *other); | |
| 159 static PyObject *vector_scale_to_length(PyVector *self, PyObject *length); | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
160 static PyObject *vector_slerp(PyVector *self, PyObject *args); |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
161 static PyObject *vector_lerp(PyVector *self, PyObject *args); |
| 1994 | 162 static int _vector_reflect_helper(double *dst_coords, const double *src_coords, |
| 163 PyObject *normal, int dim, double epsilon); | |
| 164 static PyObject *vector_reflect(PyVector *self, PyObject *normal); | |
| 165 static PyObject *vector_reflect_ip(PyVector *self, PyObject *normal); | |
| 2024 | 166 static double _vector_distance_helper(PyVector *self, PyObject *other); |
| 1994 | 167 static PyObject *vector_distance_to(PyVector *self, PyObject *other); |
| 168 static PyObject *vector_distance_squared_to(PyVector *self, PyObject *other); | |
| 169 static PyObject *vector_getAttr_swizzle(PyVector *self, PyObject *attr_name); | |
| 170 static int vector_setAttr_swizzle(PyVector *self, PyObject *attr_name, PyObject *val); | |
| 171 static PyObject *vector_elementwise(PyVector *self); | |
| 2024 | 172 static int _vector_check_snprintf_success(int return_code); |
| 1994 | 173 static PyObject *vector_repr(PyVector *self); |
| 174 static PyObject *vector_str(PyVector *self); | |
| 175 /* | |
| 176 static Py_ssize_t vector_readbuffer(PyVector *self, Py_ssize_t segment, void **ptrptr); | |
| 177 static Py_ssize_t vector_writebuffer(PyVector *self, Py_ssize_t segment, void **ptrptr); | |
| 178 static Py_ssize_t vector_segcount(PyVector *self, Py_ssize_t *lenp); | |
| 179 */ | |
| 180 | |
| 181 /* vector2 specific functions */ | |
| 182 static PyObject *vector2_new(PyTypeObject *type, PyObject *args, PyObject *kwds); | |
| 183 static int vector2_init(PyVector *self, PyObject *args, PyObject *kwds); | |
| 2024 | 184 static int _vector2_rotate_helper(double *dst_coords, const double *src_coords, |
| 185 double angle, double epsilon); | |
| 1994 | 186 static PyObject *vector2_rotate(PyVector *self, PyObject *args); |
| 187 static PyObject *vector2_rotate_ip(PyVector *self, PyObject *args); | |
| 188 static PyObject *vector2_cross(PyVector *self, PyObject *other); | |
| 189 static PyObject *vector2_angle_to(PyVector *self, PyObject *other); | |
| 190 static PyObject *vector2_as_polar(PyVector *self); | |
| 191 static PyObject *vector2_from_polar(PyVector *self, PyObject *args); | |
| 192 | |
| 193 /* vector3 specific functions */ | |
| 194 static PyObject *vector3_new(PyTypeObject *type, PyObject *args, PyObject *kwds); | |
| 195 static int vector3_init(PyVector *self, PyObject *args, PyObject *kwds); | |
| 2024 | 196 static int _vector3_rotate_helper(double *dst_coords, const double *src_coords, |
| 197 const double *axis_coords, | |
| 198 double angle, double epsilon); | |
| 1994 | 199 static PyObject *vector3_rotate(PyVector *self, PyObject *args); |
| 200 static PyObject *vector3_rotate_ip(PyVector *self, PyObject *args); | |
| 201 static PyObject *vector3_cross(PyVector *self, PyObject *other); | |
| 202 static PyObject *vector3_angle_to(PyVector *self, PyObject *other); | |
| 203 static PyObject *vector3_as_spherical(PyVector *self); | |
| 204 static PyObject *vector3_from_spherical(PyVector *self, PyObject *args); | |
| 205 | |
| 206 /* vector iterator functions */ | |
| 207 static void vectoriter_dealloc(vectoriter *it); | |
| 208 static PyObject *vectoriter_next(vectoriter *it); | |
| 209 static PyObject *vectoriter_len(vectoriter *it); | |
| 210 static PyObject *vector_iter(PyObject *vec); | |
| 211 | |
| 212 /* elementwiseproxy */ | |
| 213 static void vector_elementwiseproxy_dealloc(vector_elementwiseproxy *it); | |
| 214 static PyObject *vector_elementwiseproxy_richcompare(PyObject *o1, PyObject *o2, int op); | |
| 215 static PyObject *vector_elementwiseproxy_generic_math(PyObject *o1, | |
| 216 PyObject *o2, int op); | |
| 217 static PyObject *vector_elementwiseproxy_add(PyObject *o1, PyObject *o2); | |
| 218 static PyObject *vector_elementwiseproxy_sub(PyObject *o1, PyObject *o2); | |
| 219 static PyObject *vector_elementwiseproxy_mul(PyObject *o1, PyObject *o2); | |
| 220 static PyObject *vector_elementwiseproxy_div(PyObject *o1, PyObject *o2); | |
| 221 static PyObject *vector_elementwiseproxy_floor_div(PyObject *o1, PyObject *o2); | |
| 222 static PyObject *vector_elementwiseproxy_pow(PyObject *baseObj, PyObject *expoObj, PyObject *mod); | |
| 223 static PyObject *vector_elementwiseproxy_mod(PyObject *o1, PyObject *o2); | |
| 224 static PyObject *vector_elementwiseproxy_abs(vector_elementwiseproxy *self); | |
| 225 static PyObject *vector_elementwiseproxy_neg(vector_elementwiseproxy *self); | |
| 226 static PyObject *vector_elementwiseproxy_pos(vector_elementwiseproxy *self); | |
| 227 static int vector_elementwiseproxy_nonzero(vector_elementwiseproxy *self); | |
| 228 static PyObject *vector_elementwise(PyVector *vec); | |
| 229 | |
| 230 | |
| 231 static int swizzling_enabled = 0; | |
| 232 | |
| 233 | |
| 234 /******************************** | |
| 235 * Global helper functions | |
| 236 ********************************/ | |
| 237 | |
| 238 static int | |
| 239 RealNumber_Check(PyObject *obj) | |
| 240 { | |
| 2024 | 241 if (obj && PyNumber_Check(obj) && !PyComplex_Check(obj)) |
| 1994 | 242 return 1; |
| 243 return 0; | |
| 244 } | |
| 245 | |
| 246 static double | |
| 247 PySequence_GetItem_AsDouble(PyObject *seq, Py_ssize_t index) | |
| 248 { | |
| 2024 | 249 PyObject *item; |
| 1994 | 250 double value; |
| 251 | |
| 252 item = PySequence_GetItem(seq, index); | |
| 253 if (item == NULL) { | |
| 254 PyErr_SetString(PyExc_TypeError, "a sequence is expected"); | |
| 255 return -1; | |
| 256 } | |
| 2024 | 257 value = PyFloat_AsDouble(item); |
| 1994 | 258 Py_DECREF(item); |
| 2024 | 259 if (PyErr_Occurred()) |
| 1994 | 260 return -1; |
| 261 return value; | |
| 262 } | |
| 263 | |
| 264 static int | |
| 2024 | 265 PySequence_AsVectorCoords(PyObject *seq, double *const coords, const size_t size) |
| 1994 | 266 { |
| 267 int i; | |
| 268 | |
| 269 if (PyVector_Check(seq)) { | |
| 270 memcpy(coords, ((PyVector *)seq)->coords, sizeof(double) * size); | |
| 271 return 1; | |
| 272 } | |
| 273 if (!PySequence_Check(seq) || PySequence_Length(seq) != size) { | |
| 2024 | 274 PyErr_SetString(PyExc_ValueError, "Sequence has the wrong length."); |
| 1994 | 275 return 0; |
| 276 } | |
| 277 | |
| 278 for (i = 0; i < size; ++i) { | |
| 279 coords[i] = PySequence_GetItem_AsDouble(seq, i); | |
| 280 if (PyErr_Occurred()) { | |
| 281 return 0; | |
| 282 } | |
| 283 } | |
| 284 return 1; | |
| 285 } | |
| 286 | |
| 287 static int | |
| 288 PyVectorCompatible_Check(PyObject *obj, int dim) | |
| 289 { | |
| 290 int i; | |
| 291 PyObject *tmp; | |
| 292 | |
| 293 switch(dim) { | |
| 294 case 2: | |
| 295 if (PyVector2_Check(obj)) { | |
| 296 return 1; | |
| 297 } | |
| 298 break; | |
| 299 case 3: | |
| 300 if (PyVector3_Check(obj)) { | |
| 301 return 1; | |
| 302 } | |
| 303 break; | |
| 304 /* | |
| 305 case 4: | |
| 306 if (PyVector4_Check(obj)) { | |
| 307 return 1; | |
| 308 } | |
| 309 break; | |
| 310 */ | |
| 311 default: | |
| 312 PyErr_SetString(PyExc_SystemError, | |
| 313 "Wrong internal call to PyVectorCompatible_Check."); | |
| 314 return 0; | |
| 315 } | |
| 316 | |
| 317 if (!PySequence_Check(obj) || (PySequence_Length(obj) != dim)) { | |
| 318 return 0; | |
| 319 } | |
| 320 | |
| 321 for (i = 0; i < dim; ++i) { | |
| 322 tmp = PySequence_GetItem(obj, i); | |
| 2024 | 323 if (tmp == NULL || !RealNumber_Check(tmp)) { |
| 324 Py_XDECREF(tmp); | |
| 1994 | 325 return 0; |
| 326 } | |
| 327 Py_DECREF(tmp); | |
| 328 } | |
| 329 return 1; | |
| 330 } | |
| 331 | |
| 332 static double | |
| 333 _scalar_product(const double *coords1, const double *coords2, int size) | |
| 334 { | |
| 335 int i; | |
| 336 double product = 0; | |
| 337 for (i = 0; i < size; ++i) | |
| 338 product += coords1[i] * coords2[i]; | |
| 339 return product; | |
| 340 } | |
| 341 | |
| 342 | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
343 static int |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
344 get_double_from_unicode_slice(PyObject *unicode_obj, |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
345 Py_ssize_t idx1, Py_ssize_t idx2, double *val) |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
346 { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
347 PyObject *float_obj; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
348 PyObject *slice = PySequence_GetSlice (unicode_obj, idx1, idx2); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
349 if (slice == NULL) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
350 PyErr_SetString (PyExc_SystemError, |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
351 "internal error while converting str slice to float"); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
352 return -1; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
353 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
354 #if PY3 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
355 float_obj = PyFloat_FromString (slice); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
356 #else |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
357 float_obj = PyFloat_FromString (slice, NULL); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
358 #endif |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
359 Py_DECREF (slice); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
360 if (float_obj == NULL) |
| 2024 | 361 return 0; |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
362 *val = PyFloat_AsDouble(float_obj); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
363 Py_DECREF (float_obj); |
| 2024 | 364 return 1; |
| 365 } | |
| 366 | |
| 367 static int | |
| 368 _vector_find_string_helper(PyObject *str_obj, const char *substr, | |
| 369 Py_ssize_t start, Py_ssize_t end) | |
| 370 { | |
| 371 /* This is implemented using Python's Unicode C-API rather than | |
| 372 * plain C to handle both char* and wchar_t* especially because | |
| 373 * wchar.h was only added to the standard in 95 and we want to be | |
| 374 * ISO C 90 compatible. | |
| 375 */ | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
376 PyObject *substr_obj; |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
377 #if PY_VERSION_HEX < 0x02060000 |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
378 PyObject *tmp; |
|
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
379 #endif |
| 2024 | 380 Py_ssize_t pos; |
| 381 #if PY_VERSION_HEX >= 0x02060000 | |
| 382 substr_obj = PyUnicode_FromString (substr); | |
| 383 #else | |
| 384 tmp = PyString_FromString (substr); | |
| 385 if (tmp == NULL) { | |
| 386 return -2; | |
| 387 } | |
| 388 substr_obj = PyUnicode_FromObject (tmp); | |
| 389 Py_DECREF (tmp); | |
| 390 #endif | |
| 391 if (substr_obj == NULL) { | |
| 392 return -2; | |
| 393 } | |
| 394 pos = PyUnicode_Find (str_obj, substr_obj, start, end, 1); | |
| 395 Py_DECREF (substr_obj); | |
| 396 return pos; | |
| 397 } | |
| 398 | |
| 399 /* Extracts coords from a str/unicode Object <str>. | |
| 400 * <delimiter> should be an array of <dim>+1 C-Strings of the strings before, | |
| 401 * between and after the coords. | |
| 402 * The extracted numbers will be stored in <coords>. | |
| 403 * return | |
| 404 * 0 on success. | |
| 405 * -1 if conversion was unsuccessful | |
| 406 * -2 if an internal error occured and an exception was set | |
| 407 */ | |
| 408 static int | |
| 409 _vector_coords_from_string(PyObject *str, char **delimiter, | |
| 410 double *coords, Py_ssize_t dim) | |
| 411 { | |
| 412 int error_code; | |
| 413 Py_ssize_t i, start_pos, end_pos, length; | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
414 PyObject *vector_string; |
| 2024 | 415 vector_string = PyUnicode_FromObject (str); |
| 416 if (vector_string == NULL) { | |
| 417 return -2; | |
| 418 } | |
| 419 length = PySequence_Length (vector_string); | |
| 420 /* find the starting point of the first coordinate in the string */ | |
| 421 start_pos = _vector_find_string_helper(vector_string, delimiter[0], | |
| 422 0, length); | |
| 423 if (start_pos < 0) { | |
| 424 return start_pos; | |
| 425 } | |
| 426 start_pos += strlen(delimiter[0]); | |
| 427 for (i = 0; i < dim; i++) { | |
| 428 /* find the end point of the current coordinate in the string */ | |
| 429 end_pos = _vector_find_string_helper(vector_string, | |
| 430 delimiter[i+1], | |
| 431 start_pos, length); | |
| 432 if (end_pos < 0) | |
| 433 return end_pos; | |
| 434 /* try to convert the current coordinate */ | |
| 435 error_code = get_double_from_unicode_slice(vector_string, | |
| 436 start_pos, end_pos, | |
| 437 &coords[i]); | |
| 438 if (error_code < 0) { | |
| 439 return -2; | |
| 440 } | |
| 441 else if (error_code == 0) { | |
| 442 return -1; | |
| 443 } | |
| 444 /* move starting point to the next coordinate */ | |
| 445 start_pos = end_pos + strlen(delimiter[i+1]); | |
| 446 } | |
| 447 return 0; | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
448 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
449 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
450 |
| 1994 | 451 static PyMemberDef vector_members[] = { |
| 452 {"epsilon", T_DOUBLE, offsetof(PyVector, epsilon), 0, | |
| 453 "small value used in comparisons"}, | |
| 454 {NULL} /* Sentinel */ | |
| 455 }; | |
| 456 | |
| 457 | |
| 458 static PyObject* | |
| 459 PyVector_NEW(int dim) | |
| 460 { | |
| 461 PyVector *vec; | |
| 462 switch (dim) { | |
| 463 case 2: | |
| 464 vec = PyObject_New(PyVector, &PyVector2_Type); | |
| 465 break; | |
| 466 case 3: | |
| 467 vec = PyObject_New(PyVector, &PyVector3_Type); | |
| 468 break; | |
| 469 /* | |
| 470 case 4: | |
| 471 vec = PyObject_New(PyVector, &PyVector4_Type); | |
| 472 break; | |
| 473 */ | |
| 474 default: | |
| 475 PyErr_SetString(PyExc_SystemError, | |
| 476 "Wrong internal call to PyVector_NEW.\n"); | |
| 477 return NULL; | |
| 478 } | |
| 479 | |
| 480 if (vec != NULL) { | |
| 481 vec->dim = dim; | |
| 2024 | 482 vec->epsilon = VECTOR_EPSILON; |
| 1994 | 483 vec->coords = PyMem_New(double, dim); |
| 484 if (vec->coords == NULL) { | |
| 485 Py_DECREF(vec); | |
| 486 return PyErr_NoMemory(); | |
| 487 } | |
| 488 } | |
| 489 | |
| 490 return (PyObject *)vec; | |
| 491 } | |
| 492 | |
| 493 static void | |
| 494 vector_dealloc(PyVector* self) | |
| 495 { | |
| 496 PyMem_Del(self->coords); | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
497 Py_TYPE(self)->tp_free((PyObject*)self); |
| 1994 | 498 } |
| 499 | |
| 500 | |
| 501 | |
| 502 | |
| 503 | |
| 504 | |
| 505 /********************************************** | |
| 506 * Generic vector PyNumber emulation routines | |
| 507 **********************************************/ | |
| 508 | |
| 509 static PyObject * | |
| 510 vector_generic_math(PyObject *o1, PyObject *o2, int op) | |
| 511 { | |
| 512 int i, dim; | |
| 513 double *vec_coords; | |
| 2024 | 514 double other_coords[VECTOR_MAX_SIZE]; |
| 1994 | 515 double tmp; |
| 516 PyObject *other; | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
517 PyVector *vec, *ret = NULL; |
| 1994 | 518 if (PyVector_Check(o1)) { |
| 519 vec = (PyVector *)o1; | |
| 520 other = o2; | |
| 521 } | |
| 522 else { | |
| 523 vec = (PyVector *)o2; | |
| 524 other = o1; | |
| 525 op |= OP_ARG_REVERSE; | |
| 526 } | |
| 527 dim = vec->dim; | |
| 528 vec_coords = vec->coords; | |
| 529 | |
| 2024 | 530 if (other == NULL) { |
| 531 PyErr_BadInternalCall(); | |
| 532 return NULL; | |
| 533 } | |
| 534 | |
| 535 if (PyVectorCompatible_Check(other, dim)) { | |
| 1994 | 536 op |= OP_ARG_VECTOR; |
| 2024 | 537 if (!PySequence_AsVectorCoords(other, other_coords, dim)) |
| 538 return NULL; | |
| 539 } | |
| 1994 | 540 else if (RealNumber_Check(other)) |
| 541 op |= OP_ARG_NUMBER; | |
| 542 else | |
| 543 op |= OP_ARG_UNKNOWN; | |
| 544 | |
| 2024 | 545 if (op & OP_INPLACE) |
| 546 ret = vec; | |
| 547 else if (op != (OP_MUL | OP_ARG_VECTOR) && | |
| 548 op != (OP_MUL | OP_ARG_VECTOR | OP_ARG_REVERSE)) { | |
| 549 ret = (PyVector*)PyVector_NEW(dim); | |
| 550 if (ret == NULL) | |
| 551 return NULL; | |
| 552 } | |
| 553 | |
| 1994 | 554 switch (op) { |
| 555 case OP_ADD | OP_ARG_VECTOR: | |
| 556 case OP_ADD | OP_ARG_VECTOR | OP_ARG_REVERSE: | |
| 2024 | 557 case OP_ADD | OP_ARG_VECTOR | OP_INPLACE: |
| 1994 | 558 for (i = 0; i < dim; i++) |
| 2024 | 559 ret->coords[i] = vec_coords[i] + other_coords[i]; |
| 560 break; | |
| 1994 | 561 case OP_SUB | OP_ARG_VECTOR: |
| 2024 | 562 case OP_SUB | OP_ARG_VECTOR | OP_INPLACE: |
| 563 for (i = 0; i < dim; i++) | |
| 564 ret->coords[i] = vec_coords[i] - other_coords[i]; | |
| 565 break; | |
| 1994 | 566 case OP_SUB | OP_ARG_VECTOR | OP_ARG_REVERSE: |
| 567 for (i = 0; i < dim; i++) | |
| 2024 | 568 ret->coords[i] = other_coords[i] - vec_coords[i]; |
| 569 break; | |
| 1994 | 570 case OP_MUL | OP_ARG_VECTOR: |
| 571 case OP_MUL | OP_ARG_VECTOR | OP_ARG_REVERSE: | |
| 572 tmp = 0.; | |
| 573 for (i = 0; i < dim; i++) | |
| 2024 | 574 tmp += vec_coords[i] * other_coords[i]; |
| 575 ret = (PyVector*)PyFloat_FromDouble(tmp); | |
| 576 break; | |
| 1994 | 577 case OP_MUL | OP_ARG_NUMBER: |
| 578 case OP_MUL | OP_ARG_NUMBER | OP_ARG_REVERSE: | |
| 2024 | 579 case OP_MUL | OP_ARG_NUMBER | OP_INPLACE: |
| 1994 | 580 tmp = PyFloat_AsDouble(other); |
| 581 for (i = 0; i < dim; i++) | |
| 582 ret->coords[i] = vec_coords[i] * tmp; | |
| 2024 | 583 break; |
| 584 case OP_DIV | OP_ARG_NUMBER: | |
| 585 case OP_DIV | OP_ARG_NUMBER | OP_INPLACE: | |
| 1994 | 586 tmp = PyFloat_AsDouble(other); |
| 2024 | 587 if (tmp == 0.) { |
| 588 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 589 Py_DECREF(ret); | |
| 590 return NULL; | |
| 591 } | |
| 592 tmp = 1. / tmp; | |
| 1994 | 593 for (i = 0; i < dim; i++) |
| 594 ret->coords[i] = vec_coords[i] * tmp; | |
| 2024 | 595 break; |
| 1994 | 596 case OP_FLOOR_DIV | OP_ARG_NUMBER: |
| 2024 | 597 case OP_FLOOR_DIV | OP_ARG_NUMBER | OP_INPLACE: |
| 598 tmp = PyFloat_AsDouble(other); | |
| 599 if (tmp == 0.) { | |
| 600 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 601 Py_DECREF(ret); | |
| 602 return NULL; | |
| 603 } | |
| 604 tmp = 1. / tmp; | |
| 1994 | 605 for (i = 0; i < dim; i++) |
| 606 ret->coords[i] = floor(vec_coords[i] * tmp); | |
| 2024 | 607 break; |
| 1994 | 608 default: |
| 2024 | 609 if (!(op & OP_INPLACE)) { |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
610 Py_XDECREF(ret); |
| 2024 | 611 } |
| 1994 | 612 Py_INCREF(Py_NotImplemented); |
| 613 return Py_NotImplemented; | |
| 614 } | |
| 2024 | 615 return (PyObject*)ret; |
| 1994 | 616 } |
| 617 | |
| 618 | |
| 619 static PyObject * | |
| 620 vector_add(PyObject *o1, PyObject *o2) | |
| 621 { | |
| 622 return vector_generic_math(o1, o2, OP_ADD); | |
| 623 } | |
| 624 static PyObject * | |
| 625 vector_inplace_add(PyVector *o1, PyObject *o2) | |
| 626 { | |
| 2024 | 627 return vector_generic_math((PyObject*)o1, o2, OP_ADD | OP_INPLACE); |
| 1994 | 628 } |
| 629 static PyObject * | |
| 630 vector_sub(PyObject *o1, PyObject *o2) | |
| 631 { | |
| 632 return vector_generic_math(o1, o2, OP_SUB); | |
| 633 } | |
| 634 static PyObject * | |
| 635 vector_inplace_sub(PyVector *o1, PyObject *o2) | |
| 636 { | |
| 2024 | 637 return vector_generic_math((PyObject*)o1, o2, OP_SUB | OP_INPLACE); |
| 1994 | 638 } |
| 639 static PyObject * | |
| 640 vector_mul(PyObject *o1, PyObject *o2) | |
| 641 { | |
| 642 return vector_generic_math(o1, o2, OP_MUL); | |
| 643 } | |
| 644 static PyObject * | |
| 645 vector_inplace_mul(PyVector *o1, PyObject *o2) | |
| 646 { | |
| 2024 | 647 return vector_generic_math((PyObject*)o1, o2, OP_MUL | OP_INPLACE); |
| 1994 | 648 } |
| 649 static PyObject * | |
| 650 vector_div(PyVector *o1, PyObject *o2) | |
| 651 { | |
| 652 return vector_generic_math((PyObject*)o1, o2, OP_DIV); | |
| 653 } | |
| 654 static PyObject * | |
| 655 vector_inplace_div(PyVector *o1, PyObject *o2) | |
| 656 { | |
| 2024 | 657 return vector_generic_math((PyObject*)o1, o2, OP_DIV | OP_INPLACE); |
| 1994 | 658 } |
| 659 static PyObject * | |
| 660 vector_floor_div(PyVector *o1, PyObject *o2) | |
| 661 { | |
| 662 return vector_generic_math((PyObject*)o1, o2, OP_FLOOR_DIV); | |
| 663 } | |
| 664 static PyObject * | |
| 665 vector_inplace_floor_div(PyVector *o1, PyObject *o2) | |
| 666 { | |
| 2024 | 667 return vector_generic_math((PyObject*)o1, o2, OP_FLOOR_DIV | OP_INPLACE); |
| 1994 | 668 } |
| 669 | |
| 670 static PyObject * | |
| 671 vector_neg(PyVector *self) | |
| 672 { | |
| 673 int i; | |
| 674 PyVector *ret = (PyVector*)PyVector_NEW(self->dim); | |
| 2024 | 675 if (ret != NULL) { |
| 676 for (i = 0; i < self->dim; i++) { | |
| 677 ret->coords[i] = -self->coords[i]; | |
| 678 } | |
| 1994 | 679 } |
| 680 return (PyObject*)ret; | |
| 681 } | |
| 682 | |
| 683 static PyObject * | |
| 684 vector_pos(PyVector *self) | |
| 685 { | |
| 686 PyVector *ret = (PyVector*)PyVector_NEW(self->dim); | |
| 2024 | 687 if (ret != NULL) { |
| 688 memcpy(ret->coords, self->coords, sizeof(ret->coords[0]) * ret->dim); | |
| 689 } | |
| 1994 | 690 return (PyObject*)ret; |
| 691 } | |
| 692 | |
| 693 static int | |
| 694 vector_nonzero(PyVector *self) | |
| 695 { | |
| 696 int i; | |
| 697 for (i = 0; i < self->dim; i++) { | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
698 if (self->coords[i] != 0) { |
| 1994 | 699 return 1; |
| 700 } | |
| 701 } | |
| 702 return 0; | |
| 703 } | |
| 704 | |
| 705 static PyNumberMethods vector_as_number = { | |
| 706 (binaryfunc)vector_add, /* nb_add; __add__ */ | |
| 707 (binaryfunc)vector_sub, /* nb_subtract; __sub__ */ | |
| 708 (binaryfunc)vector_mul, /* nb_multiply; __mul__ */ | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
709 #if !PY3 |
| 1994 | 710 (binaryfunc)vector_div, /* nb_divide; __div__ */ |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
711 #endif |
| 1994 | 712 (binaryfunc)0, /* nb_remainder; __mod__ */ |
| 713 (binaryfunc)0, /* nb_divmod; __divmod__ */ | |
| 714 (ternaryfunc)0, /* nb_power; __pow__ */ | |
| 715 (unaryfunc)vector_neg, /* nb_negative; __neg__ */ | |
| 716 (unaryfunc)vector_pos, /* nb_positive; __pos__ */ | |
| 717 (unaryfunc)0, /* nb_absolute; __abs__ */ | |
| 718 (inquiry)vector_nonzero, /* nb_nonzero; __nonzero__ */ | |
| 719 (unaryfunc)0, /* nb_invert; __invert__ */ | |
| 720 (binaryfunc)0, /* nb_lshift; __lshift__ */ | |
| 721 (binaryfunc)0, /* nb_rshift; __rshift__ */ | |
| 722 (binaryfunc)0, /* nb_and; __and__ */ | |
| 723 (binaryfunc)0, /* nb_xor; __xor__ */ | |
| 724 (binaryfunc)0, /* nb_or; __or__ */ | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
725 #if !PY3 |
| 1994 | 726 (coercion)0, /* nb_coerce; __coerce__ */ |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
727 #endif |
| 1994 | 728 (unaryfunc)0, /* nb_int; __int__ */ |
| 729 (unaryfunc)0, /* nb_long; __long__ */ | |
| 730 (unaryfunc)0, /* nb_float; __float__ */ | |
|
2001
bdc8f02964aa
conditionals for PY3 and PyNumberMethods... too many parts for py3k. hopefully fix error with msvc.
Rene Dudfield <renesd@gmail.com>
parents:
2000
diff
changeset
|
731 #if !PY3 |
| 1994 | 732 (unaryfunc)0, /* nb_oct; __oct__ */ |
| 733 (unaryfunc)0, /* nb_hex; __hex__ */ | |
|
2001
bdc8f02964aa
conditionals for PY3 and PyNumberMethods... too many parts for py3k. hopefully fix error with msvc.
Rene Dudfield <renesd@gmail.com>
parents:
2000
diff
changeset
|
734 #endif |
| 1994 | 735 /* Added in release 2.0 */ |
| 736 (binaryfunc)vector_inplace_add, /* nb_inplace_add; __iadd__ */ | |
| 737 (binaryfunc)vector_inplace_sub, /* nb_inplace_subtract; __isub__ */ | |
| 738 (binaryfunc)vector_inplace_mul, /* nb_inplace_multiply; __imul__ */ | |
|
2001
bdc8f02964aa
conditionals for PY3 and PyNumberMethods... too many parts for py3k. hopefully fix error with msvc.
Rene Dudfield <renesd@gmail.com>
parents:
2000
diff
changeset
|
739 #if !PY3 |
| 1994 | 740 (binaryfunc)vector_inplace_div, /* nb_inplace_divide; __idiv__ */ |
|
2001
bdc8f02964aa
conditionals for PY3 and PyNumberMethods... too many parts for py3k. hopefully fix error with msvc.
Rene Dudfield <renesd@gmail.com>
parents:
2000
diff
changeset
|
741 #endif |
| 1994 | 742 (binaryfunc)0, /* nb_inplace_remainder; __imod__ */ |
| 743 (ternaryfunc)0, /* nb_inplace_power; __pow__ */ | |
| 744 (binaryfunc)0, /* nb_inplace_lshift; __ilshift__ */ | |
| 745 (binaryfunc)0, /* nb_inplace_rshift; __irshift__ */ | |
| 746 (binaryfunc)0, /* nb_inplace_and; __iand__ */ | |
| 747 (binaryfunc)0, /* nb_inplace_xor; __ixor__ */ | |
| 748 (binaryfunc)0, /* nb_inplace_or; __ior__ */ | |
| 749 | |
| 750 /* Added in release 2.2 */ | |
| 751 (binaryfunc)vector_floor_div, /* nb_floor_divide; __floor__ */ | |
| 752 (binaryfunc)vector_div, /* nb_true_divide; __truediv__ */ | |
| 753 (binaryfunc)vector_inplace_floor_div, /* nb_inplace_floor_divide; __ifloor__ */ | |
| 754 (binaryfunc)vector_inplace_div, /* nb_inplace_true_divide; __itruediv__ */ | |
| 755 }; | |
| 756 | |
| 757 | |
| 758 | |
| 759 /************************************************* | |
| 760 * Generic vector PySequence emulation routines | |
| 761 *************************************************/ | |
| 762 | |
| 763 static Py_ssize_t | |
| 764 vector_len(PyVector *self) | |
| 765 { | |
| 766 return (Py_ssize_t)self->dim; | |
| 767 } | |
| 768 | |
| 769 static PyObject * | |
| 770 vector_GetItem(PyVector *self, Py_ssize_t index) | |
| 771 { | |
| 772 if (index < 0 || index >= self->dim) { | |
| 773 PyErr_SetString(PyExc_IndexError, "subscript out of range."); | |
| 774 return NULL; | |
| 775 } | |
| 776 return PyFloat_FromDouble(self->coords[index]); | |
| 777 } | |
| 778 | |
| 779 static int | |
| 780 vector_SetItem(PyVector *self, Py_ssize_t index, PyObject *value) | |
| 781 { | |
| 782 if (index < 0 || index >= self->dim) { | |
| 783 PyErr_SetString(PyExc_IndexError, "subscript out of range."); | |
| 784 return -1; | |
| 785 } | |
| 2024 | 786 if (value == NULL) { |
| 787 PyErr_SetString(PyExc_TypeError, "item deletion is not supported"); | |
| 788 return -1; | |
| 789 } | |
| 790 | |
| 1994 | 791 self->coords[index] = PyFloat_AsDouble(value); |
| 2024 | 792 if (PyErr_Occurred()) |
| 793 return -1; | |
| 1994 | 794 return 0; |
| 795 } | |
| 796 | |
| 797 | |
| 798 static PyObject * | |
| 799 vector_GetSlice(PyVector *self, Py_ssize_t ilow, Py_ssize_t ihigh) | |
| 800 { | |
| 801 /* some code was taken from the CPython source listobject.c */ | |
| 802 PyListObject *slice; | |
| 803 Py_ssize_t i, len; | |
| 804 PyObject **dest; | |
| 805 | |
| 806 /* make sure boundaries are sane */ | |
| 807 if (ilow < 0) | |
| 808 ilow = 0; | |
| 809 else if (ilow > self->dim) | |
| 810 ilow = self->dim; | |
| 811 if (ihigh < ilow) | |
| 812 ihigh = ilow; | |
| 813 else if (ihigh > self->dim) | |
| 814 ihigh = self->dim; | |
| 815 | |
| 816 len = ihigh - ilow; | |
| 817 slice = (PyListObject *) PyList_New(len); | |
| 818 if (slice == NULL) | |
| 819 return NULL; | |
| 820 | |
| 821 dest = slice->ob_item; | |
| 822 for (i = 0; i < len; i++) { | |
| 2024 | 823 dest[i] = PyFloat_FromDouble(self->coords[ilow + i]); |
| 1994 | 824 } |
| 825 return (PyObject *)slice; | |
| 826 } | |
| 827 | |
| 828 static int | |
| 829 vector_SetSlice(PyVector *self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) | |
| 830 { | |
| 831 Py_ssize_t i, len; | |
| 2024 | 832 double new_coords[VECTOR_MAX_SIZE]; |
| 833 | |
| 834 if (v == NULL) { | |
| 835 PyErr_SetString(PyExc_TypeError, | |
| 836 "Vector object doesn't support item deletion"); | |
| 837 return -1; | |
| 838 } | |
| 1994 | 839 |
| 840 if (ilow < 0) | |
| 841 ilow = 0; | |
| 842 else if (ilow > self->dim) | |
| 843 ilow = self->dim; | |
| 844 if (ihigh < ilow) | |
| 845 ihigh = ilow; | |
| 846 else if (ihigh > self->dim) | |
| 847 ihigh = self->dim; | |
| 848 | |
| 849 len = ihigh - ilow; | |
| 2024 | 850 if (!PySequence_AsVectorCoords(v, new_coords, len)) { |
| 1994 | 851 return -1; |
| 852 } | |
| 2024 | 853 |
| 1994 | 854 for (i = 0; i < len; ++i) { |
| 2024 | 855 self->coords[i + ilow] = new_coords[i]; |
| 1994 | 856 } |
| 857 return 0; | |
| 858 } | |
| 859 | |
| 860 | |
| 861 static PySequenceMethods vector_as_sequence = { | |
| 862 (lenfunc)vector_len, /* sq_length; __len__ */ | |
| 863 (binaryfunc)0, /* sq_concat; __add__ */ | |
| 864 (ssizeargfunc)0, /* sq_repeat; __mul__ */ | |
| 865 (ssizeargfunc)vector_GetItem, /* sq_item; __getitem__ */ | |
| 866 (ssizessizeargfunc)vector_GetSlice, /* sq_slice; __getslice__ */ | |
| 867 (ssizeobjargproc)vector_SetItem, /* sq_ass_item; __setitem__ */ | |
| 868 (ssizessizeobjargproc)vector_SetSlice, /* sq_ass_slice; __setslice__ */ | |
| 869 }; | |
| 870 | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
871 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
872 /*************************************************************************** |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
873 * Generic vector PyMapping emulation routines to support extended slicing |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
874 ***************************************************************************/ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
875 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
876 /* Great parts of this function are adapted from python's list_subscript */ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
877 static PyObject* |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
878 vector_subscript (PyVector *self, PyObject *key) |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
879 { |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
880 Py_ssize_t i; |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
881 #if PY_VERSION_HEX >= 0x02050000 |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
882 if (PyIndex_Check (key)) { |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
883 i = PyNumber_AsSsize_t (key, PyExc_IndexError); |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
884 #else |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
885 if (PyInt_Check (key) || PyLong_Check (key)) { |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
886 if (PyInt_Check (key)) |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
887 i = PyInt_AsLong (key); |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
888 else |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
889 i = PyLong_AsLong (key); |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
890 #endif |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
891 if (i == -1 && PyErr_Occurred()) |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
892 return NULL; |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
893 if (i < 0) |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
894 i += self->dim; |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
895 return vector_GetItem (self, i); |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
896 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
897 else if (PySlice_Check (key)) { |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
898 Py_ssize_t start, stop, step, slicelength, cur; |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
899 PyObject *result; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
900 PyObject *it; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
901 PyObject **dest; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
902 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
903 if (PySlice_GetIndicesEx ((PySliceObject*)key, self->dim, |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
904 &start, &stop, &step, &slicelength) < 0) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
905 return NULL; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
906 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
907 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
908 if (slicelength <= 0) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
909 return PyList_New(0); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
910 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
911 else if (step == 1) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
912 return vector_GetSlice (self, start, stop); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
913 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
914 else { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
915 result = PyList_New (slicelength); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
916 if (!result) |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
917 return NULL; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
918 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
919 dest = ((PyListObject *)result)->ob_item; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
920 for (cur = start, i = 0; i < slicelength; cur += step, i++) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
921 it = PyFloat_FromDouble (self->coords[cur]); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
922 if (it == NULL) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
923 Py_DECREF (result); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
924 return NULL; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
925 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
926 dest[i] = it; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
927 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
928 return result; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
929 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
930 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
931 else { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
932 PyErr_Format(PyExc_TypeError, |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
933 "vector indices must be integers, not %.200s", |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
934 key->ob_type->tp_name); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
935 return NULL; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
936 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
937 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
938 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
939 /* Parts of this function are adapted from python's list_ass_subscript */ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
940 static int |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
941 vector_ass_subscript (PyVector *self, PyObject *key, PyObject *value) |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
942 { |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
943 Py_ssize_t i; |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
944 #if PY_VERSION_HEX >= 0x02050000 |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
945 if (PyIndex_Check (key)) { |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
946 i = PyNumber_AsSsize_t (key, PyExc_IndexError); |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
947 #else |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
948 if (PyInt_Check (key) || PyLong_Check (key)) { |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
949 if (PyInt_Check (key)) |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
950 i = PyInt_AsLong (key); |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
951 else |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
952 i = PyLong_AsLong (key); |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
953 #endif |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
954 if (i == -1 && PyErr_Occurred()) |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
955 return -1; |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
956 if (i < 0) |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
957 i += self->dim; |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
958 return vector_SetItem (self, i, value); |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
959 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
960 else if (PySlice_Check (key)) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
961 Py_ssize_t start, stop, step, slicelength; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
962 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
963 if (PySlice_GetIndicesEx ((PySliceObject*)key, self->dim, |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
964 &start, &stop, &step, &slicelength) < 0) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
965 return -1; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
966 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
967 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
968 if (step == 1) |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
969 return vector_SetSlice(self, start, stop, value); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
970 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
971 /* Make sure s[5:2] = [..] inserts at the right place: |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
972 before 5, not before 2. */ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
973 if ((step < 0 && start < stop) || |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
974 (step > 0 && start > stop)) |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
975 stop = start; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
976 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
977 if (value == NULL) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
978 /* delete slice not supported */ |
| 2024 | 979 PyErr_SetString (PyExc_TypeError, |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
980 "Deletion of vector components is not supported."); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
981 return -1; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
982 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
983 else { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
984 /* assign slice */ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
985 double seqitems[VECTOR_MAX_SIZE]; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
986 Py_ssize_t cur, i; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
987 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
988 if (!PySequence_AsVectorCoords (value, seqitems, slicelength)) |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
989 return -1; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
990 for (cur = start, i = 0; i < slicelength; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
991 cur += step, i++) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
992 self->coords[cur] = seqitems[i]; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
993 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
994 return 0; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
995 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
996 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
997 else { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
998 PyErr_Format (PyExc_TypeError, |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
999 "list indices must be integers, not %.200s", |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1000 key->ob_type->tp_name); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1001 return -1; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1002 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1003 } |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1004 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1005 static PyMappingMethods vector_as_mapping = { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1006 (lenfunc)vector_len, /* mp_length */ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1007 (binaryfunc)vector_subscript, /* mp_subscript */ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1008 (objobjargproc)vector_ass_subscript /* mp_ass_subscript */ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1009 }; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1010 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1011 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1012 |
| 2024 | 1013 static int |
| 1014 vector_set_component (PyVector *self, PyObject *value, int component) | |
| 1015 { | |
| 1016 if (value == NULL) { | |
| 1017 PyErr_SetString(PyExc_TypeError, "Cannot delete the x attribute"); | |
| 1018 return -1; | |
| 1019 } | |
| 1020 if (component >= self->dim) { | |
| 1021 PyErr_BadInternalCall(); | |
| 1022 return -1; | |
| 1023 } | |
| 1024 | |
| 1025 self->coords[component] = PyFloat_AsDouble(value); | |
| 1026 if (PyErr_Occurred()) | |
| 1027 return -1; | |
| 1028 return 0; | |
| 1029 } | |
| 1030 | |
| 1994 | 1031 static PyObject* |
| 1032 vector_getx (PyVector *self, void *closure) | |
| 1033 { | |
| 1034 return PyFloat_FromDouble(self->coords[0]); | |
| 1035 } | |
| 1036 | |
| 1037 static int | |
| 1038 vector_setx (PyVector *self, PyObject *value, void *closure) | |
| 1039 { | |
| 2024 | 1040 return vector_set_component (self, value, 0); |
| 1994 | 1041 } |
| 1042 | |
| 1043 static PyObject* | |
| 1044 vector_gety (PyVector *self, void *closure) | |
| 1045 { | |
| 1046 return PyFloat_FromDouble(self->coords[1]); | |
| 1047 } | |
| 1048 | |
| 1049 static int | |
| 1050 vector_sety (PyVector *self, PyObject *value, void *closure) | |
| 1051 { | |
| 2024 | 1052 return vector_set_component (self, value, 1); |
| 1994 | 1053 } |
| 1054 | |
| 1055 static PyObject* | |
| 1056 vector_getz (PyVector *self, void *closure) | |
| 1057 { | |
| 1058 return PyFloat_FromDouble(self->coords[2]); | |
| 1059 } | |
| 1060 | |
| 1061 static int | |
| 1062 vector_setz (PyVector *self, PyObject *value, void *closure) | |
| 1063 { | |
| 2024 | 1064 return vector_set_component (self, value, 2); |
| 1994 | 1065 } |
| 1066 | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
1067 #ifdef PYGAME_MATH_VECTOR_HAVE_W |
| 1994 | 1068 static PyObject* |
| 1069 vector_getw (PyVector *self, void *closure) | |
| 1070 { | |
| 1071 return PyFloat_FromDouble(self->coords[3]); | |
| 1072 } | |
| 1073 | |
| 1074 static int | |
| 1075 vector_setw (PyVector *self, PyObject *value, void *closure) | |
| 1076 { | |
| 2024 | 1077 return vector_set_component (self, value, 3); |
| 1994 | 1078 } |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
1079 #endif |
| 1994 | 1080 |
| 1081 | |
| 1082 | |
| 1083 static PyObject * | |
| 2024 | 1084 vector_richcompare(PyObject *o1, PyObject *o2, int op) |
| 1994 | 1085 { |
| 1086 int i; | |
| 1087 double diff; | |
| 2024 | 1088 double other_coords[VECTOR_MAX_SIZE]; |
| 1089 PyVector *vec; | |
| 1090 PyObject *other; | |
| 1091 | |
| 1092 if (PyVector_Check(o1)) { | |
| 1093 vec = (PyVector*)o1; | |
| 1094 other = o2; | |
| 1095 } | |
| 1096 else { | |
| 1097 vec = (PyVector*)o2; | |
| 1098 other = o1; | |
| 1099 } | |
| 1100 if (!PyVectorCompatible_Check(other, vec->dim)) { | |
| 1994 | 1101 if (op == Py_EQ) |
| 1102 Py_RETURN_FALSE; | |
| 1103 else if (op == Py_NE) | |
| 1104 Py_RETURN_TRUE; | |
| 1105 else { | |
| 1106 Py_INCREF(Py_NotImplemented); | |
| 1107 return Py_NotImplemented; | |
| 1108 } | |
| 1109 } | |
| 1110 | |
| 2024 | 1111 if (!PySequence_AsVectorCoords(other, other_coords, vec->dim)) { |
| 1112 return NULL; | |
| 1113 } | |
| 1114 | |
| 1994 | 1115 switch(op) { |
| 1116 case Py_EQ: | |
| 2024 | 1117 for (i = 0; i < vec->dim; i++) { |
| 1118 diff = vec->coords[i] - other_coords[i]; | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
1119 /* test diff != diff to catch NaN */ |
| 2024 | 1120 if ((diff != diff) || (fabs(diff) >= vec->epsilon)) { |
| 1994 | 1121 Py_RETURN_FALSE; |
| 1122 } | |
| 1123 } | |
| 1124 Py_RETURN_TRUE; | |
| 1125 case Py_NE: | |
| 2024 | 1126 for (i = 0; i < vec->dim; i++) { |
| 1127 diff = vec->coords[i] - other_coords[i]; | |
| 1128 if ((diff != diff) || (fabs(diff) >= vec->epsilon)) { | |
| 1994 | 1129 Py_RETURN_TRUE; |
| 1130 } | |
| 1131 } | |
| 1132 Py_RETURN_FALSE; | |
| 1133 default: | |
| 2024 | 1134 PyErr_SetString(PyExc_TypeError, |
| 1135 "This operation is not supported by vectors"); | |
| 1136 return NULL; | |
| 1994 | 1137 } |
| 1138 } | |
| 1139 | |
| 1140 | |
| 1141 | |
| 1142 | |
| 1143 | |
| 1144 | |
| 1145 | |
| 1146 | |
| 1147 static PyObject * | |
| 1148 vector_length(PyVector *self) | |
| 1149 { | |
| 1150 double length_squared = _scalar_product(self->coords, self->coords, | |
| 1151 self->dim); | |
| 1152 return PyFloat_FromDouble(sqrt(length_squared)); | |
| 1153 } | |
| 1154 | |
| 1155 static PyObject * | |
| 1156 vector_length_squared(PyVector *self) | |
| 1157 { | |
| 1158 double length_squared = _scalar_product(self->coords, self->coords, | |
| 1159 self->dim); | |
| 1160 return PyFloat_FromDouble(length_squared); | |
| 1161 } | |
| 1162 | |
| 1163 static PyObject * | |
| 1164 vector_normalize(PyVector *self) | |
| 1165 { | |
| 1166 PyVector *ret; | |
| 2024 | 1167 |
| 1168 ret = (PyVector*)PyVector_NEW(self->dim); | |
| 1169 if (ret == NULL) { | |
| 1994 | 1170 return NULL; |
| 1171 } | |
| 2024 | 1172 memcpy(ret->coords, self->coords, sizeof(ret->coords[0]) * ret->dim); |
| 1173 | |
| 1174 if (!vector_normalize_ip(ret)) { | |
| 1175 return NULL; | |
| 1176 } | |
| 1177 return (PyObject*)ret; | |
| 1994 | 1178 } |
| 1179 | |
| 1180 static PyObject * | |
| 1181 vector_normalize_ip(PyVector *self) | |
| 1182 { | |
| 1183 int i; | |
| 1184 double length; | |
| 1185 | |
| 1186 length = sqrt(_scalar_product(self->coords, self->coords, self->dim)); | |
| 1187 | |
| 1188 if (length == 0) { | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
1189 PyErr_SetString(PyExc_ValueError, |
| 1994 | 1190 "Can't normalize Vector of length Zero"); |
| 1191 return NULL; | |
| 1192 } | |
| 1193 | |
| 1194 for (i = 0; i < self->dim; ++i) | |
| 1195 self->coords[i] /= length; | |
| 1196 | |
| 1197 Py_RETURN_NONE; | |
| 1198 } | |
| 1199 | |
| 1200 static PyObject * | |
| 1201 vector_is_normalized(PyVector *self) | |
| 1202 { | |
| 1203 double length_squared = _scalar_product(self->coords, self->coords, | |
| 1204 self->dim); | |
| 1205 if (fabs(length_squared - 1) < self->epsilon) | |
| 1206 Py_RETURN_TRUE; | |
| 1207 else | |
| 1208 Py_RETURN_FALSE; | |
| 1209 } | |
| 1210 | |
| 1211 static PyObject * | |
| 1212 vector_dot(PyVector *self, PyObject *other) | |
| 1213 { | |
| 1214 double other_coords[VECTOR_MAX_SIZE]; | |
| 1215 if (!PySequence_AsVectorCoords(other, other_coords, self->dim)) { | |
| 2024 | 1216 PyErr_SetString(PyExc_TypeError, |
| 1217 "Cannot perform dot product with this type."); | |
| 1994 | 1218 return NULL; |
| 1219 } | |
| 1220 return PyFloat_FromDouble(_scalar_product(self->coords, other_coords, | |
| 1221 self->dim)); | |
| 1222 } | |
| 1223 | |
| 1224 static PyObject * | |
| 1225 vector_scale_to_length(PyVector *self, PyObject *length) | |
| 1226 { | |
| 1227 int i; | |
| 1228 double new_length, old_length; | |
| 1229 double fraction; | |
| 1230 | |
| 2024 | 1231 new_length = PyFloat_AsDouble(length); |
| 1232 if (PyErr_Occurred()) { | |
| 1994 | 1233 return NULL; |
| 1234 } | |
| 2024 | 1235 |
| 1236 old_length = sqrt(_scalar_product(self->coords, self->coords, self->dim)); | |
| 1994 | 1237 |
| 1238 if (old_length < self->epsilon) { | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
1239 PyErr_SetString(PyExc_ValueError, "Cannot scale a vector with zero length"); |
| 1994 | 1240 return NULL; |
| 1241 } | |
| 1242 | |
| 1243 fraction = new_length / old_length; | |
| 1244 for (i = 0; i < self->dim; ++i) | |
| 1245 self->coords[i] *= fraction; | |
| 1246 | |
| 1247 Py_RETURN_NONE; | |
| 1248 } | |
| 1249 | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1250 static PyObject * |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1251 vector_slerp(PyVector *self, PyObject *args) |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1252 { |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1253 int i; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1254 PyObject *other; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1255 PyVector *ret; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1256 double other_coords[VECTOR_MAX_SIZE]; |
| 2024 | 1257 double tmp, angle, t, length1, length2, f0, f1, f2; |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1258 |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1259 if (!PyArg_ParseTuple(args, "Od:slerp", &other, &t)) { |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1260 return NULL; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1261 } |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1262 if (!PySequence_AsVectorCoords(other, other_coords, self->dim)) { |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1263 PyErr_SetString(PyExc_TypeError, "Argument 1 must be a vector."); |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1264 return NULL; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1265 } |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1266 if (fabs(t) > 1) { |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1267 PyErr_SetString(PyExc_ValueError, "Argument 2 must be in range [-1, 1]."); |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1268 return NULL; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1269 } |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1270 |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1271 length1 = sqrt(_scalar_product(self->coords, self->coords, self->dim)); |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1272 length2 = sqrt(_scalar_product(other_coords, other_coords, self->dim)); |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1273 if ((length1 < self->epsilon) || (length2 < self->epsilon)) { |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
1274 PyErr_SetString(PyExc_ValueError, |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1275 "can't use slerp with Zero-Vector"); |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1276 return NULL; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1277 } |
| 2024 | 1278 tmp = (_scalar_product(self->coords, other_coords, self->dim) / |
| 1279 (length1 * length2)); | |
| 1280 /* make sure tmp is in the range [-1:1] so acos won't return NaN */ | |
| 1281 tmp = (tmp < -1 ? -1 : (tmp > 1 ? 1: tmp)); | |
| 1282 angle = acos(tmp); | |
| 1283 | |
| 1284 /* if t < 0 we take the long arch of the greate circle to the destiny */ | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1285 if (t < 0) { |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1286 angle -= 2 * M_PI; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1287 t = -t; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1288 } |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1289 if (self->coords[0] * other_coords[1] < self->coords[1] * other_coords[0]) |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1290 angle *= -1; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1291 |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1292 ret = (PyVector*)PyVector_NEW(self->dim); |
| 2024 | 1293 if (ret == NULL) { |
| 1294 return NULL; | |
| 1295 } | |
| 1296 /* special case angle==0 and angle==360 */ | |
| 1297 if ((fabs(angle) < self->epsilon) || | |
| 1298 (fabs(fabs(angle) - 2 * M_PI) < self->epsilon)) { | |
| 1299 /* approximate with lerp, because slerp diverges with 1/sin(angle) */ | |
| 1300 for (i = 0; i < self->dim; ++i) | |
| 1301 ret->coords[i] = self->coords[i] * (1 - t) + other_coords[i] * t; | |
| 1302 } | |
| 1303 /* special case angle==180 and angle==-180 */ | |
| 1304 else if (fabs(fabs(angle) - M_PI) < self->epsilon) { | |
| 1305 PyErr_SetString(PyExc_ValueError, | |
| 1306 "SLERP with 180 degrees is undefined."); | |
| 1307 Py_DECREF(ret); | |
| 1308 return NULL; | |
| 1309 } | |
| 1310 else { | |
| 1311 f0 = ((length2 - length1) * t + length1) / sin(angle); | |
| 1312 f1 = sin(angle * (1-t)) / length1; | |
| 1313 f2 = sin(angle * t) / length2; | |
| 1314 for (i = 0; i < self->dim; ++i) { | |
| 1315 ret->coords[i] = (self->coords[i] * f1 + other_coords[i] * f2) * f0; | |
| 1316 } | |
| 1317 } | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1318 return (PyObject*)ret; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1319 } |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1320 |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1321 static PyObject * |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1322 vector_lerp(PyVector *self, PyObject *args) |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1323 { |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1324 int i; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1325 PyObject *other; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1326 PyVector *ret; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1327 double t; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1328 double other_coords[VECTOR_MAX_SIZE]; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1329 |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1330 if (!PyArg_ParseTuple(args, "Od:Vector.lerp", &other, &t)) { |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1331 return NULL; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1332 } |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1333 if (!PySequence_AsVectorCoords(other, other_coords, self->dim)) { |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1334 PyErr_SetString(PyExc_TypeError, "Expected Vector as argument 1"); |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1335 return NULL; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1336 } |
| 2024 | 1337 if (t < 0 || t > 1) { |
| 1338 PyErr_SetString(PyExc_ValueError, "Argument 2 must be in range [0, 1]"); | |
| 1339 return NULL; | |
| 1340 } | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1341 |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1342 ret = (PyVector*)PyVector_NEW(self->dim); |
| 2024 | 1343 if (ret == NULL) { |
| 1344 return NULL; | |
| 1345 } | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1346 for (i = 0; i < self->dim; ++i) |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1347 ret->coords[i] = self->coords[i] * (1 - t) + other_coords[i] * t; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1348 return (PyObject *)ret; |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1349 } |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
1350 |
| 1994 | 1351 static int |
| 1352 _vector_reflect_helper(double *dst_coords, const double *src_coords, | |
| 1353 PyObject *normal, int dim, double epsilon) | |
| 1354 { | |
| 1355 int i; | |
| 2024 | 1356 double dot_product, norm_length; |
| 1994 | 1357 double norm_coords[VECTOR_MAX_SIZE]; |
| 1358 | |
| 1359 /* normalize the normal */ | |
| 2024 | 1360 if (!PySequence_AsVectorCoords(normal, norm_coords, dim)) |
| 1361 return 0; | |
| 1362 | |
| 1363 norm_length = _scalar_product(norm_coords, norm_coords, dim); | |
| 1364 | |
| 1994 | 1365 if (norm_length < epsilon) { |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
1366 PyErr_SetString(PyExc_ValueError, "Normal must not be of length zero."); |
| 2024 | 1367 return 0; |
| 1994 | 1368 } |
| 1369 if (norm_length != 1) { | |
| 1370 norm_length = sqrt(norm_length); | |
| 1371 for (i = 0; i < dim; ++i) | |
| 1372 norm_coords[i] /= norm_length; | |
| 1373 } | |
| 1374 | |
| 1375 /* calculate the dot_product for the projection */ | |
| 2024 | 1376 dot_product = _scalar_product(src_coords, norm_coords, dim); |
| 1994 | 1377 |
| 1378 for (i = 0; i < dim; ++i) | |
| 1379 dst_coords[i] = src_coords[i] - 2 * norm_coords[i] * dot_product; | |
| 2024 | 1380 return 1; |
| 1994 | 1381 } |
| 1382 | |
| 1383 static PyObject * | |
| 1384 vector_reflect(PyVector *self, PyObject *normal) | |
| 1385 { | |
| 1386 PyVector *ret = (PyVector *)PyVector_NEW(self->dim); | |
| 2024 | 1387 if (ret == NULL) { |
| 1994 | 1388 return NULL; |
| 2024 | 1389 } |
| 1390 | |
| 1391 if (!_vector_reflect_helper(ret->coords, self->coords, | |
| 1392 normal, self->dim, self->epsilon)) { | |
| 1393 return NULL; | |
| 1394 } | |
| 1994 | 1395 return (PyObject *)ret; |
| 1396 } | |
| 1397 | |
| 1398 static PyObject * | |
| 1399 vector_reflect_ip(PyVector *self, PyObject *normal) | |
| 1400 { | |
| 1401 double tmp_coords[VECTOR_MAX_SIZE]; | |
| 1402 | |
| 2024 | 1403 if (!_vector_reflect_helper(tmp_coords, self->coords, |
| 1404 normal, self->dim, self->epsilon)) { | |
| 1994 | 1405 return NULL; |
| 2024 | 1406 } |
| 1994 | 1407 memcpy(self->coords, tmp_coords, self->dim * sizeof(tmp_coords[0])); |
| 1408 Py_RETURN_NONE; | |
| 1409 } | |
| 1410 | |
| 2024 | 1411 static double |
| 1412 _vector_distance_helper(PyVector *self, PyObject *other) | |
| 1413 { | |
| 1414 int i; | |
| 1415 double distance_squared, tmp; | |
| 1416 | |
| 1417 distance_squared = 0; | |
| 1418 for (i = 0; i < self->dim; ++i) { | |
| 1419 tmp = PySequence_GetItem_AsDouble(other, i) - self->coords[i]; | |
| 1420 distance_squared += tmp * tmp; | |
| 1421 } | |
| 1422 /* PySequence_GetItem_AsDouble can fail in which case it will set an Err */ | |
| 1423 if (PyErr_Occurred()) | |
| 1424 return -1; | |
| 1425 | |
| 1426 return distance_squared; | |
| 1427 } | |
| 1428 | |
| 1994 | 1429 static PyObject * |
| 1430 vector_distance_to(PyVector *self, PyObject *other) | |
| 1431 { | |
| 2024 | 1432 double distance_squared = _vector_distance_helper(self, other); |
| 1433 if (distance_squared < 0 && PyErr_Occurred()) | |
| 1434 return NULL; | |
| 1994 | 1435 return PyFloat_FromDouble(sqrt(distance_squared)); |
| 1436 } | |
| 1437 | |
| 1438 static PyObject * | |
| 1439 vector_distance_squared_to(PyVector *self, PyObject *other) | |
| 1440 { | |
| 2024 | 1441 double distance_squared = _vector_distance_helper(self, other); |
| 1442 if (distance_squared < 0 && PyErr_Occurred()) | |
| 1443 return NULL; | |
| 1994 | 1444 return PyFloat_FromDouble(distance_squared); |
| 1445 } | |
| 1446 | |
| 1447 | |
| 2024 | 1448 static int |
| 1449 _vector_check_snprintf_success(int return_code) | |
| 1450 { | |
| 1451 if (return_code < 0) { | |
| 1452 PyErr_SetString(PyExc_SystemError, "internal snprintf call went wrong! Please report this to pygame-users@seul.org"); | |
| 1453 return 0; | |
| 1454 } | |
| 1455 if (return_code >= STRING_BUF_SIZE) { | |
| 1456 PyErr_SetString(PyExc_SystemError, "Internal buffer to small for snprintf! Please report this to pygame-users@seul.org"); | |
| 1457 return 0; | |
| 1458 } | |
| 1459 return 1; | |
| 1460 } | |
| 1994 | 1461 |
| 1462 static PyObject * | |
| 1463 vector_repr(PyVector *self) | |
| 1464 { | |
| 2024 | 1465 int i, tmp; |
| 1994 | 1466 int bufferIdx; |
| 1467 char buffer[2][STRING_BUF_SIZE]; | |
| 1468 | |
| 1469 bufferIdx = 1; | |
| 2024 | 1470 tmp = PyOS_snprintf(buffer[0], STRING_BUF_SIZE, "<Vector%d(", self->dim); |
| 1471 if (!_vector_check_snprintf_success(tmp)) | |
| 1472 return NULL; | |
| 1994 | 1473 for (i = 0; i < self->dim - 1; ++i) { |
| 2024 | 1474 tmp = PyOS_snprintf(buffer[bufferIdx % 2], STRING_BUF_SIZE, "%s%g, ", |
| 1475 buffer[(bufferIdx + 1) % 2], self->coords[i]); | |
| 1994 | 1476 bufferIdx++; |
| 2024 | 1477 if (!_vector_check_snprintf_success(tmp)) |
| 1478 return NULL; | |
| 1994 | 1479 } |
| 2024 | 1480 tmp = PyOS_snprintf(buffer[bufferIdx % 2], STRING_BUF_SIZE, "%s%g)>", |
| 1481 buffer[(bufferIdx + 1) % 2], self->coords[i]); | |
| 1482 if (!_vector_check_snprintf_success(tmp)) | |
| 1483 return NULL; | |
| 2002 | 1484 return Text_FromUTF8(buffer[bufferIdx % 2]); |
| 1994 | 1485 } |
| 1486 | |
| 1487 static PyObject * | |
| 1488 vector_str(PyVector *self) | |
| 1489 { | |
| 2024 | 1490 int i, tmp; |
| 1994 | 1491 int bufferIdx; |
| 1492 char buffer[2][STRING_BUF_SIZE]; | |
| 1493 | |
| 1494 bufferIdx = 1; | |
| 2024 | 1495 tmp = PyOS_snprintf(buffer[0], STRING_BUF_SIZE, "["); |
| 1496 if (!_vector_check_snprintf_success(tmp)) | |
| 1497 return NULL; | |
| 1994 | 1498 for (i = 0; i < self->dim - 1; ++i) { |
| 2024 | 1499 tmp = PyOS_snprintf(buffer[bufferIdx % 2], STRING_BUF_SIZE, "%s%g, ", |
| 1500 buffer[(bufferIdx + 1) % 2], self->coords[i]); | |
| 1994 | 1501 bufferIdx++; |
| 2024 | 1502 if (!_vector_check_snprintf_success(tmp)) |
| 1503 return NULL; | |
| 1994 | 1504 } |
| 2024 | 1505 tmp = PyOS_snprintf(buffer[bufferIdx % 2], STRING_BUF_SIZE, "%s%g]", |
| 1506 buffer[(bufferIdx + 1) % 2], self->coords[i]); | |
| 1507 if (!_vector_check_snprintf_success(tmp)) | |
| 1508 return NULL; | |
| 2002 | 1509 return Text_FromUTF8(buffer[bufferIdx % 2]); |
| 1994 | 1510 } |
| 1511 | |
| 2024 | 1512 |
| 1513 /* This method first tries normal attribute access. If successful we're | |
| 1514 * done. If not we try swizzling. Here we have 3 different outcomes: | |
| 1515 * 1) swizzling works. we return the result as a tuple | |
| 1516 * 2) swizzling fails because it wasn't a valid swizzle. we return the | |
| 1517 * original AttributeError | |
| 1518 * 3) swizzling fails due to some internal error. we return this error. | |
| 1519 */ | |
| 1994 | 1520 static PyObject* |
| 1521 vector_getAttr_swizzle(PyVector *self, PyObject *attr_name) | |
| 1522 { | |
| 2024 | 1523 double *coords; |
| 1524 Py_ssize_t i, idx, len; | |
| 1525 PyObject *err_type, *err_value, *err_traceback; | |
| 1526 PyObject *attr_unicode = NULL; | |
| 1527 Py_UNICODE *attr = NULL; | |
| 1994 | 1528 PyObject *res = PyObject_GenericGetAttr((PyObject*)self, attr_name); |
| 1529 /* if normal lookup failed try to swizzle */ | |
| 1530 if (swizzling_enabled && | |
| 1531 PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_AttributeError)) { | |
| 2024 | 1532 /* fetch the error so it can be restored in case swizzling fails */ |
| 1533 PyErr_Fetch(&err_type, &err_value, &err_traceback); | |
| 1534 len = PySequence_Length(attr_name); | |
| 1535 if (len < 0) | |
| 1536 goto swizzle_failed; | |
| 1537 coords = self->coords; | |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1538 attr_unicode = PyUnicode_FromObject(attr_name); |
| 2024 | 1539 if (attr_unicode == NULL) |
| 1540 goto swizzle_failed; | |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1541 attr = PyUnicode_AsUnicode(attr_unicode); |
| 2024 | 1542 if (attr == NULL) |
| 1543 goto internal_error; | |
| 1994 | 1544 res = (PyObject*)PyTuple_New(len); |
| 2024 | 1545 if (res == NULL) |
| 1546 goto internal_error; | |
| 1994 | 1547 for (i = 0; i < len; i++) { |
| 1548 switch (attr[i]) { | |
| 1549 case 'x': | |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1550 case 'y': |
|
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1551 case 'z': |
|
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1552 idx = attr[i] - 'x'; |
| 1994 | 1553 break; |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1554 case 'w': |
|
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1555 idx = 3; |
| 1994 | 1556 break; |
| 1557 default: | |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1558 goto swizzle_failed; |
| 1994 | 1559 } |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1560 if (idx < self->dim) { |
| 2024 | 1561 if (PyTuple_SetItem(res, i, PyFloat_FromDouble(coords[idx])) != 0) |
| 1562 goto internal_error; | |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1563 } |
|
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1564 else { |
|
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1565 goto swizzle_failed; |
|
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1566 } |
| 1994 | 1567 } |
| 1568 /* swizzling succeeded! clear the error and return result */ | |
| 1569 PyErr_Clear(); | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1570 Py_DECREF(attr_unicode); |
| 1994 | 1571 } |
| 1572 return res; | |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1573 |
| 2024 | 1574 /* swizzling failed! restore the exception from PyObject_GenericGetAttr, |
| 1575 * clean up and return NULL */ | |
| 1576 swizzle_failed: | |
| 1577 PyErr_Restore(err_type, err_value, err_traceback); | |
| 1578 internal_error: | |
|
2013
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1579 Py_XDECREF(res); |
|
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1580 Py_XDECREF(attr_unicode); |
|
3b778c6f8cde
fixed bug in swizzle code (you were only able to get x and y so far).
lorenz
parents:
2011
diff
changeset
|
1581 return NULL; |
| 1994 | 1582 } |
| 1583 | |
| 1584 static int | |
| 1585 vector_setAttr_swizzle(PyVector *self, PyObject *attr_name, PyObject *val) | |
| 1586 { | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1587 Py_UNICODE *attr; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1588 PyObject *attr_unicode; |
| 1994 | 1589 Py_ssize_t len = PySequence_Length(attr_name); |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
1590 double entry[VECTOR_MAX_SIZE]; |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
1591 int entry_was_set[VECTOR_MAX_SIZE]; |
| 1994 | 1592 int swizzle_err = SWIZZLE_ERR_NO_ERR; |
| 1593 int i; | |
| 1594 | |
| 1595 /* if swizzling is disabled always default to generic implementation */ | |
| 1596 if (!swizzling_enabled) | |
| 1597 return PyObject_GenericSetAttr((PyObject*)self, attr_name, val); | |
| 1598 | |
| 1599 /* if swizzling is enabled first try swizzle */ | |
| 1600 for (i = 0; i < self->dim; ++i) | |
| 1601 entry_was_set[i] = 0; | |
| 1602 | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1603 /* handle string and unicode uniformly */ |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1604 attr_unicode = PyUnicode_FromObject(attr_name); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1605 if (attr_unicode == NULL) |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1606 return -1; |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1607 attr = PyUnicode_AsUnicode(attr_unicode); |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
1608 if (attr == NULL) { |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
1609 Py_DECREF (attr_unicode); |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
1610 return -1; |
|
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
1611 } |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1612 |
| 1994 | 1613 for (i = 0; i < len; ++i) { |
| 1614 int idx; | |
| 1615 switch (attr[i]) { | |
| 1616 case 'x': | |
| 1617 case 'y': | |
| 1618 case 'z': | |
| 1619 idx = attr[i] - 'x'; | |
| 1620 break; | |
| 1621 case 'w': | |
| 1622 idx = 3; | |
| 1623 break; | |
| 1624 default: | |
| 1625 /* swizzle failed. attempt generic attribute setting */ | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1626 Py_DECREF(attr_unicode); |
| 1994 | 1627 return PyObject_GenericSetAttr((PyObject*)self, attr_name, val); |
| 1628 } | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1629 if (idx >= self->dim) { |
| 1994 | 1630 /* swizzle failed. attempt generic attribute setting */ |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1631 Py_DECREF(attr_unicode); |
| 1994 | 1632 return PyObject_GenericSetAttr((PyObject*)self, attr_name, val); |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1633 } |
| 1994 | 1634 if (entry_was_set[idx]) |
| 1635 swizzle_err = SWIZZLE_ERR_DOUBLE_IDX; | |
| 1636 if (swizzle_err == SWIZZLE_ERR_NO_ERR) { | |
| 1637 entry_was_set[idx] = 1; | |
| 1638 entry[idx] = PySequence_GetItem_AsDouble(val, i); | |
| 1639 if (PyErr_Occurred()) | |
| 1640 swizzle_err = SWIZZLE_ERR_EXTRACTION_ERR; | |
| 1641 } | |
| 1642 } | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1643 Py_DECREF(attr_unicode); |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1644 |
| 1994 | 1645 switch (swizzle_err) { |
| 1646 case SWIZZLE_ERR_NO_ERR: | |
| 1647 /* swizzle successful */ | |
| 1648 for (i = 0; i < self->dim; ++i) | |
| 1649 if (entry_was_set[i]) | |
| 1650 self->coords[i] = entry[i]; | |
| 1651 return 0; | |
| 1652 case SWIZZLE_ERR_DOUBLE_IDX: | |
| 1653 PyErr_SetString(PyExc_AttributeError, | |
| 1654 "Attribute assignment conflicts with swizzling."); | |
| 1655 return -1; | |
| 1656 case SWIZZLE_ERR_EXTRACTION_ERR: | |
| 1657 /* exception was set by PySequence_GetItem_AsDouble */ | |
| 1658 return -1; | |
| 1659 default: | |
| 1660 /* this should NEVER happen and means a bug in the code */ | |
| 2024 | 1661 PyErr_SetString(PyExc_RuntimeError, "Unhandled error in swizzle code. Please report this bug to pygame-users@seul.org"); |
| 1994 | 1662 return -1; |
| 1663 } | |
| 1664 } | |
| 1665 | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
1666 #if 0 |
| 1994 | 1667 static Py_ssize_t |
| 1668 vector_readbuffer(PyVector *self, Py_ssize_t segment, void **ptrptr) | |
| 1669 { | |
| 1670 if (segment != 0) { | |
| 1671 PyErr_SetString(PyExc_SystemError, | |
| 1672 "accessing non-existent vector segment"); | |
| 1673 return -1; | |
| 1674 } | |
| 1675 *ptrptr = self->coords; | |
| 1676 return self->dim; | |
| 1677 } | |
| 1678 | |
| 1679 static Py_ssize_t | |
| 1680 vector_writebuffer(PyVector *self, Py_ssize_t segment, void **ptrptr) | |
| 1681 { | |
| 1682 if (segment != 0) { | |
| 1683 PyErr_SetString(PyExc_SystemError, | |
| 1684 "accessing non-existent vector segment"); | |
| 1685 return -1; | |
| 1686 } | |
| 1687 *ptrptr = self->coords; | |
| 1688 return self->dim; | |
| 1689 } | |
| 1690 | |
| 1691 static Py_ssize_t | |
| 1692 vector_segcount(PyVector *self, Py_ssize_t *lenp) | |
| 1693 { | |
| 1694 if (lenp) { | |
| 1695 *lenp = self->dim * sizeof(self->coords[0]); | |
| 1696 } | |
| 1697 return 1; | |
| 1698 } | |
| 1699 | |
| 1700 static int | |
| 1701 vector_getbuffer(PyVector *self, Py_buffer *view, int flags) | |
| 1702 { | |
| 1703 int ret; | |
| 1704 void *ptr; | |
| 1705 if (view == NULL) { | |
| 1706 self->ob_exports++; | |
| 1707 return 0; | |
| 1708 } | |
| 1709 ptr = self->coords; | |
| 1710 ret = PyBuffer_FillInfo(view, (PyObject*)self, ptr, Py_SIZE(self), 0, flags); | |
| 1711 if (ret >= 0) { | |
| 1712 obj->ob_exports++; | |
| 1713 } | |
| 1714 return ret; | |
| 1715 } | |
| 1716 | |
| 1717 static void | |
| 1718 vector_releasebuffer(PyVector *self, Py_buffer *view) | |
| 1719 { | |
| 1720 self->ob_exports--; | |
| 1721 } | |
| 1722 | |
| 1723 | |
| 1724 static PyBufferProcs vector_as_buffer = { | |
| 1725 (readbufferproc)vector_readbuffer, | |
| 1726 (writebufferproc)vector_writebuffer, | |
| 1727 (segcountproc)vector_segcount, | |
| 1728 (charbufferproc)0, | |
| 1729 (getbufferproc)vector_getbuffer, | |
| 1730 (releasebufferproc)vector_releasebuffer, | |
| 1731 }; | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
1732 #endif |
| 1994 | 1733 |
| 1734 /********************************************************************* | |
| 1735 * vector2 specific functions | |
| 1736 *********************************************************************/ | |
| 1737 | |
| 1738 | |
| 1739 static PyObject * | |
| 1740 vector2_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 1741 { | |
| 1742 PyVector *vec = (PyVector *)type->tp_alloc(type, 0); | |
| 1743 | |
| 1744 if (vec != NULL) { | |
| 1745 vec->dim = 2; | |
| 2024 | 1746 vec->epsilon = VECTOR_EPSILON; |
| 1994 | 1747 vec->coords = PyMem_New(double, vec->dim); |
| 1748 if (vec->coords == NULL) { | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
1749 Py_TYPE(vec)->tp_free((PyObject*)vec); |
| 1994 | 1750 return NULL; |
| 1751 } | |
| 1752 } | |
| 1753 | |
| 1754 return (PyObject *)vec; | |
| 1755 } | |
| 1756 | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1757 |
| 1994 | 1758 static int |
| 1759 vector2_init(PyVector *self, PyObject *args, PyObject *kwds) | |
| 1760 { | |
| 1997 | 1761 PyObject *xOrSequence=NULL, *y=NULL; |
| 1994 | 1762 static char *kwlist[] = {"x", "y", NULL}; |
| 1763 | |
| 1764 if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OO:Vector2", kwlist, | |
| 1765 &xOrSequence, &y)) | |
| 1766 return -1; | |
| 1767 | |
| 1768 if (xOrSequence) { | |
| 1769 if (RealNumber_Check(xOrSequence)) { | |
| 1770 self->coords[0] = PyFloat_AsDouble(xOrSequence); | |
| 1771 } | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1772 else if (PyVectorCompatible_Check (xOrSequence, self->dim)) { |
| 2024 | 1773 if (!PySequence_AsVectorCoords(xOrSequence, self->coords, 2)) |
| 1774 return -1; | |
| 1775 else | |
| 1776 return 0; | |
| 1994 | 1777 } |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1778 #if PY3 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1779 else if (PyUnicode_Check (xOrSequence)) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1780 #else |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1781 else if (PyUnicode_Check (xOrSequence) || |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1782 PyString_Check (xOrSequence)) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1783 #endif |
| 2024 | 1784 char *delimiter[3] = { "<Vector2(", ", ", ")>" }; |
| 1785 int error_code; | |
| 1786 error_code = _vector_coords_from_string(xOrSequence, delimiter, | |
| 1787 self->coords, self->dim); | |
| 1788 if (error_code == -2) { | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
1789 return -1; |
| 2024 | 1790 } |
| 1791 else if (error_code == -1) { | |
|
2010
d039144f08d3
some compatibility fixes for python version < 2.6 to the math module
lorenz
parents:
2009
diff
changeset
|
1792 goto error; |
| 2024 | 1793 } |
| 1994 | 1794 return 0; |
| 1795 } | |
| 1796 else { | |
| 1797 goto error; | |
| 1798 } | |
| 1799 } | |
| 1800 else { | |
| 1801 self->coords[0] = 0.; | |
| 1802 } | |
| 1803 | |
| 1804 if (y) { | |
| 1805 if (RealNumber_Check(y)) { | |
| 1806 self->coords[1] = PyFloat_AsDouble(y); | |
| 1807 } | |
| 1808 else { | |
| 1809 goto error; | |
| 1810 } | |
| 1811 } | |
| 1812 else { | |
| 1813 self->coords[1] = 0.; | |
| 1814 } | |
| 1815 /* success initialization */ | |
| 1816 return 0; | |
| 1817 error: | |
| 1818 PyErr_SetString(PyExc_ValueError, | |
| 1819 "Vector2 must be initialized with 2 real numbers or a sequence of 2 real numbers"); | |
| 1820 return -1; | |
| 1821 } | |
| 1822 | |
| 2024 | 1823 static int |
| 1824 _vector2_rotate_helper(double *dst_coords, const double *src_coords, | |
| 1825 double angle, double epsilon) | |
| 1994 | 1826 { |
| 1827 /* make sure angle is in range [0, 360) */ | |
| 1828 angle = fmod(angle, 360.); | |
| 1829 if (angle < 0) | |
| 1830 angle += 360.; | |
| 1831 | |
| 1832 /* special-case rotation by 0, 90, 180 and 270 degrees */ | |
| 1833 if (fmod(angle + epsilon, 90.) < 2 * epsilon) { | |
| 1834 switch ((int)((angle + epsilon) / 90)) { | |
| 1835 case 0: /* 0 degrees */ | |
| 1836 dst_coords[0] = src_coords[0]; | |
| 1837 dst_coords[1] = src_coords[1]; | |
| 1838 break; | |
| 1839 case 1: /* 90 degrees */ | |
| 1840 dst_coords[0] = -src_coords[1]; | |
| 1841 dst_coords[1] = src_coords[0]; | |
| 1842 break; | |
| 1843 case 2: /* 180 degrees */ | |
| 1844 dst_coords[0] = -src_coords[0]; | |
| 1845 dst_coords[1] = -src_coords[1]; | |
| 1846 break; | |
| 1847 case 3: /* 270 degrees */ | |
| 1848 dst_coords[0] = src_coords[1]; | |
| 1849 dst_coords[1] = -src_coords[0]; | |
| 1850 break; | |
| 1851 default: | |
| 1852 /* this should NEVER happen and means a bug in the code */ | |
| 2024 | 1853 PyErr_SetString(PyExc_RuntimeError, "Please report this bug in vector2_rotate_helper to the developers at pygame-users@seul.org"); |
| 1854 return 0; | |
| 1994 | 1855 } |
| 1856 } | |
| 1857 else { | |
| 1858 double sinValue, cosValue; | |
| 1859 | |
| 1860 angle = DEG2RAD(angle); | |
| 1861 sinValue = sin(angle); | |
| 1862 cosValue = cos(angle); | |
| 1863 | |
| 1864 dst_coords[0] = cosValue * src_coords[0] - sinValue * src_coords[1]; | |
| 1865 dst_coords[1] = sinValue * src_coords[0] + cosValue * src_coords[1]; | |
| 1866 } | |
| 2024 | 1867 return 1; |
| 1994 | 1868 } |
| 1869 | |
| 1870 static PyObject * | |
| 1871 vector2_rotate(PyVector *self, PyObject *args) | |
| 1872 { | |
| 1873 double angle; | |
| 1874 PyVector *ret; | |
| 1875 | |
| 1876 if (!PyArg_ParseTuple(args, "d:rotate", &angle)) { | |
| 1877 return NULL; | |
| 1878 } | |
| 1879 | |
| 1880 ret = (PyVector*)PyVector_NEW(self->dim); | |
| 2024 | 1881 if (ret == NULL || !_vector2_rotate_helper(ret->coords, self->coords, |
| 1882 angle, self->epsilon)) { | |
| 1883 Py_XDECREF(ret); | |
| 1884 return NULL; | |
| 1885 } | |
| 1994 | 1886 return (PyObject*)ret; |
| 1887 } | |
| 1888 | |
| 1889 static PyObject * | |
| 1890 vector2_rotate_ip(PyVector *self, PyObject *args) | |
| 1891 { | |
| 1892 double angle; | |
| 1893 double tmp[2]; | |
| 1894 | |
| 1895 if (!PyArg_ParseTuple(args, "d:rotate_ip", &angle)) { | |
| 1896 return NULL; | |
| 1897 } | |
| 1898 | |
| 1899 tmp[0] = self->coords[0]; | |
| 1900 tmp[1] = self->coords[1]; | |
| 2024 | 1901 if (!_vector2_rotate_helper(self->coords, tmp, angle, self->epsilon)) { |
| 1902 return NULL; | |
| 1903 } | |
| 1994 | 1904 Py_RETURN_NONE; |
| 1905 } | |
| 1906 | |
| 1907 static PyObject * | |
| 1908 vector2_cross(PyVector *self, PyObject *other) | |
| 1909 { | |
| 2024 | 1910 double other_coords[2]; |
| 1911 | |
| 1994 | 1912 if (!PyVectorCompatible_Check(other, self->dim)) { |
| 1913 PyErr_SetString(PyExc_TypeError, "cannot calculate cross Product"); | |
| 1914 return NULL; | |
| 1915 } | |
| 1916 | |
| 2024 | 1917 if (!PySequence_AsVectorCoords(other, other_coords, 2)) { |
| 1918 return NULL; | |
| 1994 | 1919 } |
| 2024 | 1920 |
| 1921 return PyFloat_FromDouble((self->coords[0] * other_coords[1]) - | |
| 1922 (self->coords[1] * other_coords[0])); | |
| 1994 | 1923 } |
| 1924 | |
| 1925 static PyObject * | |
| 1926 vector2_angle_to(PyVector *self, PyObject *other) | |
| 1927 { | |
| 1928 double angle; | |
| 2024 | 1929 double other_coords[2]; |
| 1930 | |
| 1994 | 1931 if (!PyVectorCompatible_Check(other, self->dim)) { |
| 1932 PyErr_SetString(PyExc_TypeError, "expected an vector."); | |
| 1933 return NULL; | |
| 1934 } | |
| 1935 | |
| 2024 | 1936 if (!PySequence_AsVectorCoords(other, other_coords, 2)) { |
| 1937 return NULL; | |
| 1938 } | |
| 1939 | |
| 1940 angle = (atan2(other_coords[1], other_coords[0]) - | |
| 1994 | 1941 atan2(self->coords[1], self->coords[0])); |
| 1942 return PyFloat_FromDouble(RAD2DEG(angle)); | |
| 1943 } | |
| 1944 | |
| 1945 static PyObject * | |
| 1946 vector2_as_polar(PyVector *self) | |
| 1947 { | |
| 1948 double r, phi; | |
| 1949 r = sqrt(_scalar_product(self->coords, self->coords, self->dim)); | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
1950 phi = RAD2DEG(atan2(self->coords[1], self->coords[0])); |
| 1994 | 1951 return Py_BuildValue("(dd)", r, phi); |
| 1952 } | |
| 1953 | |
| 1954 static PyObject * | |
| 1955 vector2_from_polar(PyVector *self, PyObject *args) | |
| 1956 { | |
| 1957 double r, phi; | |
| 2024 | 1958 if (!PyArg_ParseTuple(args, "(dd):Vector2.from_polar", &r, &phi)) { |
| 1994 | 1959 return NULL; |
| 1960 } | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
1961 phi = DEG2RAD(phi); |
| 1994 | 1962 self->coords[0] = r * cos(phi); |
| 1963 self->coords[1] = r * sin(phi); | |
| 1964 | |
| 1965 Py_RETURN_NONE; | |
| 1966 } | |
| 1967 | |
| 1968 | |
| 1969 static PyMethodDef vector2_methods[] = { | |
| 1970 {"length", (PyCFunction)vector_length, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1971 DOC_VECTOR2LENGTH |
| 1994 | 1972 }, |
| 1973 {"length_squared", (PyCFunction)vector_length_squared, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1974 DOC_VECTOR2LENGTHSQUARED |
| 1994 | 1975 }, |
| 1976 {"rotate", (PyCFunction)vector2_rotate, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1977 DOC_VECTOR2ROTATE |
| 1994 | 1978 }, |
| 1979 {"rotate_ip", (PyCFunction)vector2_rotate_ip, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1980 DOC_VECTOR2ROTATEIP |
| 1994 | 1981 }, |
| 1982 {"slerp", (PyCFunction)vector_slerp, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1983 DOC_VECTOR2SLERP |
| 1994 | 1984 }, |
| 1985 {"lerp", (PyCFunction)vector_lerp, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1986 DOC_VECTOR2LERP |
| 1994 | 1987 }, |
| 1988 {"normalize", (PyCFunction)vector_normalize, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1989 DOC_VECTOR2NORMALIZE |
| 1994 | 1990 }, |
| 1991 {"normalize_ip", (PyCFunction)vector_normalize_ip, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1992 DOC_VECTOR2NORMALIZEIP |
| 1994 | 1993 }, |
| 1994 {"is_normalized", (PyCFunction)vector_is_normalized, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1995 DOC_VECTOR2ISNORMALIZED |
| 1994 | 1996 }, |
| 1997 {"cross", (PyCFunction)vector2_cross, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
1998 DOC_VECTOR2CROSS |
| 1994 | 1999 }, |
| 2000 {"dot", (PyCFunction)vector_dot, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2001 DOC_VECTOR2DOT |
| 1994 | 2002 }, |
| 2003 {"angle_to", (PyCFunction)vector2_angle_to, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2004 DOC_VECTOR2ANGLETO |
| 1994 | 2005 }, |
| 2006 {"scale_to_length", (PyCFunction)vector_scale_to_length, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2007 DOC_VECTOR2SCALETOLENGTH |
| 1994 | 2008 }, |
| 2009 {"reflect", (PyCFunction)vector_reflect, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2010 DOC_VECTOR2REFLECT |
| 1994 | 2011 }, |
| 2012 {"reflect_ip", (PyCFunction)vector_reflect_ip, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2013 DOC_VECTOR2REFLECTIP |
| 1994 | 2014 }, |
| 2015 {"distance_to", (PyCFunction)vector_distance_to, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2016 DOC_VECTOR2DISTANCETO |
| 1994 | 2017 }, |
| 2018 {"distance_squared_to", (PyCFunction)vector_distance_squared_to, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2019 DOC_VECTOR2DISTANCESQUAREDTO |
| 1994 | 2020 }, |
| 2021 {"elementwise", (PyCFunction)vector_elementwise, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2022 DOC_VECTOR2ELEMENTWISE |
| 1994 | 2023 }, |
| 2024 {"as_polar", (PyCFunction)vector2_as_polar, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2025 DOC_VECTOR2ASPOLAR |
| 1994 | 2026 }, |
| 2027 {"from_polar", (PyCFunction)vector2_from_polar, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2028 DOC_VECTOR2FROMPOLAR |
| 1994 | 2029 }, |
| 2030 | |
| 2031 {NULL} /* Sentinel */ | |
| 2032 }; | |
| 2033 | |
| 2034 | |
| 2035 static PyGetSetDef vector2_getsets[] = { | |
| 2036 { "x", (getter)vector_getx, (setter)vector_setx, NULL, NULL }, | |
| 2037 { "y", (getter)vector_gety, (setter)vector_sety, NULL, NULL }, | |
| 2038 { NULL, 0, NULL, NULL, NULL } /* Sentinel */ | |
| 2039 }; | |
| 2040 | |
| 2041 | |
| 2042 /******************************** | |
| 2043 * PyVector2 type definition | |
| 2044 ********************************/ | |
| 2045 | |
| 2046 static PyTypeObject PyVector2_Type = { | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2047 TYPE_HEAD(NULL, 0) |
| 1994 | 2048 "pygame.math.Vector2", /* tp_name */ |
| 2049 sizeof(PyVector), /* tp_basicsize */ | |
| 2050 0, /* tp_itemsize */ | |
| 2051 /* Methods to implement standard operations */ | |
| 2052 (destructor)vector_dealloc, /* tp_dealloc */ | |
| 2053 0, /* tp_print */ | |
| 2054 0, /* tp_getattr */ | |
| 2055 0, /* tp_setattr */ | |
| 2056 0, /* tp_compare */ | |
| 2057 (reprfunc)vector_repr, /* tp_repr */ | |
| 2058 /* Method suites for standard classes */ | |
| 2059 &vector_as_number, /* tp_as_number */ | |
| 2060 &vector_as_sequence, /* tp_as_sequence */ | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2061 &vector_as_mapping, /* tp_as_mapping */ |
| 1994 | 2062 /* More standard operations (here for binary compatibility) */ |
| 2063 0, /* tp_hash */ | |
| 2064 0, /* tp_call */ | |
| 2065 (reprfunc)vector_str, /* tp_str */ | |
| 2066 (getattrofunc)vector_getAttr_swizzle, /* tp_getattro */ | |
| 2067 (setattrofunc)vector_setAttr_swizzle, /* tp_setattro */ | |
| 2068 /* Functions to access object as input/output buffer */ | |
| 2069 0, /* tp_as_buffer */ | |
| 2070 /* Flags to define presence of optional/expanded features */ | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2071 #if PY3 |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2072 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2073 #else |
| 1994 | 2074 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | |
| 2075 Py_TPFLAGS_CHECKTYPES, /* tp_flags */ | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2076 #endif |
| 1994 | 2077 /* Documentation string */ |
| 2078 DOC_PYGAMEMATHVECTOR2, /* tp_doc */ | |
| 2079 | |
| 2080 /* Assigned meaning in release 2.0 */ | |
| 2081 /* call function for all accessible objects */ | |
| 2082 0, /* tp_traverse */ | |
| 2083 /* delete references to contained objects */ | |
| 2084 0, /* tp_clear */ | |
| 2085 | |
| 2086 /* Assigned meaning in release 2.1 */ | |
| 2087 /* rich comparisons */ | |
| 2088 (richcmpfunc)vector_richcompare, /* tp_richcompare */ | |
| 2089 /* weak reference enabler */ | |
| 2090 0, /* tp_weaklistoffset */ | |
| 2091 | |
| 2092 /* Added in release 2.2 */ | |
| 2093 /* Iterators */ | |
| 2094 vector_iter, /* tp_iter */ | |
| 2095 0, /* tp_iternext */ | |
| 2096 /* Attribute descriptor and subclassing stuff */ | |
| 2097 vector2_methods, /* tp_methods */ | |
| 2098 vector_members, /* tp_members */ | |
| 2099 vector2_getsets, /* tp_getset */ | |
| 2100 0, /* tp_base */ | |
| 2101 0, /* tp_dict */ | |
| 2102 0, /* tp_descr_get */ | |
| 2103 0, /* tp_descr_set */ | |
| 2104 0, /* tp_dictoffset */ | |
| 2105 (initproc)vector2_init, /* tp_init */ | |
| 2106 0, /* tp_alloc */ | |
| 2107 (newfunc)vector2_new, /* tp_new */ | |
| 2108 0, /* tp_free */ | |
| 2109 0, /* tp_is_gc */ | |
| 2110 0, /* tp_bases */ | |
| 2111 0, /* tp_mro */ | |
| 2112 0, /* tp_cache */ | |
| 2113 0, /* tp_subclasses */ | |
| 2114 0, /* tp_weaklist */ | |
| 2115 }; | |
| 2116 | |
| 2117 | |
| 2118 | |
| 2119 | |
| 2120 | |
| 2121 | |
| 2122 | |
| 2123 | |
| 2124 | |
| 2125 | |
| 2126 /************************************************************* | |
| 2127 * PyVector3 specific functions | |
| 2128 *************************************************************/ | |
| 2129 | |
| 2130 | |
| 2131 | |
| 2132 static PyObject * | |
| 2133 vector3_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 2134 { | |
| 2135 PyVector *vec = (PyVector *)type->tp_alloc(type, 0); | |
| 2136 | |
| 2137 if (vec != NULL) { | |
| 2138 vec->dim = 3; | |
| 2024 | 2139 vec->epsilon = VECTOR_EPSILON; |
| 1994 | 2140 vec->coords = PyMem_New(double, vec->dim); |
| 2141 if (vec->coords == NULL) { | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2142 Py_TYPE(vec)->tp_free((PyObject*)vec); |
| 1994 | 2143 return NULL; |
| 2144 } | |
| 2145 } | |
| 2146 | |
| 2147 return (PyObject *)vec; | |
| 2148 } | |
| 2149 | |
| 2150 static int | |
| 2151 vector3_init(PyVector *self, PyObject *args, PyObject *kwds) | |
| 2152 { | |
| 2153 PyObject *xOrSequence=NULL, *y=NULL, *z=NULL; | |
| 2154 static char *kwlist[] = {"x", "y", "z", NULL}; | |
| 2155 | |
| 2156 if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOO:Vector3", kwlist, | |
| 2157 &xOrSequence, &y, &z)) | |
| 2158 return -1; | |
| 2159 | |
| 2160 if (xOrSequence) { | |
| 2161 if (RealNumber_Check(xOrSequence)) { | |
| 2162 self->coords[0] = PyFloat_AsDouble(xOrSequence); | |
| 2163 } | |
| 2164 else if (PyVectorCompatible_Check(xOrSequence, self->dim)) { | |
| 2024 | 2165 if (!PySequence_AsVectorCoords(xOrSequence, self->coords, 3)) |
| 2166 return -1; | |
| 2167 else | |
| 2168 return 0; | |
| 1994 | 2169 } |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2170 #if PY3 |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2171 else if (PyUnicode_Check (xOrSequence)) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2172 #else |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2173 else if (PyUnicode_Check (xOrSequence) || |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2174 PyString_Check (xOrSequence)) { |
|
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2175 #endif |
| 2024 | 2176 char *delimiter[4] = { "<Vector3(", ", ", ", ", ")>" }; |
| 2177 int error_code; | |
| 2178 error_code = _vector_coords_from_string(xOrSequence, delimiter, | |
| 2179 self->coords, self->dim); | |
| 2180 if (error_code == -2) { | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2181 return -1; |
| 2024 | 2182 } |
| 2183 else if (error_code == -1) { | |
| 1994 | 2184 goto error; |
| 2024 | 2185 } |
| 1994 | 2186 return 0; |
| 2187 } | |
| 2188 else { | |
| 2189 goto error; | |
| 2190 } | |
| 2191 } | |
| 2192 else { | |
| 2193 self->coords[0] = 0.; | |
| 2194 } | |
| 2195 | |
| 2196 if (y) { | |
| 2197 if (RealNumber_Check(y)) { | |
| 2198 self->coords[1] = PyFloat_AsDouble(y); | |
| 2199 } | |
| 2200 else { | |
| 2201 goto error; | |
| 2202 } | |
| 2203 } | |
| 2204 else { | |
| 2205 self->coords[1] = 0.; | |
| 2206 } | |
| 2207 | |
| 2208 if (z) { | |
| 2209 if (RealNumber_Check(z)) { | |
| 2210 self->coords[2] = PyFloat_AsDouble(z); | |
| 2211 } | |
| 2212 else { | |
| 2213 goto error; | |
| 2214 } | |
| 2215 } | |
| 2216 else { | |
| 2217 self->coords[2] = 0.; | |
| 2218 } | |
| 2219 /* success initialization */ | |
| 2220 return 0; | |
| 2221 error: | |
| 2222 PyErr_SetString(PyExc_ValueError, | |
| 2223 "Vector3 must be initialized with 3 real numbers or a sequence of 3 real numbers"); | |
| 2224 return -1; | |
| 2225 } | |
| 2226 | |
| 2227 | |
| 2024 | 2228 static int |
| 2229 _vector3_rotate_helper(double *dst_coords, const double *src_coords, | |
| 2230 const double *axis_coords, | |
| 2231 double angle, double epsilon) | |
| 1994 | 2232 { |
| 2233 double sinValue, cosValue, cosComplement; | |
| 2234 double normalizationFactor; | |
| 2235 double axisLength2 = 0; | |
| 2236 double axis[3]; | |
| 2237 int i; | |
| 2238 | |
| 2239 /* make sure angle is in range [0, 360) */ | |
| 2240 angle = fmod(angle, 360.); | |
| 2241 if (angle < 0) | |
| 2242 angle += 360.; | |
| 2243 | |
| 2244 for (i = 0; i < 3; ++i) { | |
| 2245 axisLength2 += axis_coords[i] * axis_coords[i]; | |
| 2246 axis[i] = axis_coords[i]; | |
| 2247 } | |
| 2248 | |
| 2024 | 2249 /* Rotation axis may not be Zero */ |
| 2250 if (axisLength2 < epsilon) { | |
| 2251 PyErr_SetString(PyExc_ValueError, "Rotation Axis is to close to Zero"); | |
| 2252 return 0; | |
| 2253 } | |
| 2254 | |
| 1994 | 2255 /* normalize the axis */ |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2256 if (fabs(axisLength2 - 1) > epsilon) { |
| 1994 | 2257 normalizationFactor = 1. / sqrt(axisLength2); |
| 2258 for (i = 0; i < 3; ++i) | |
| 2259 axis[i] *= normalizationFactor; | |
| 2260 } | |
| 2261 | |
| 2262 /* special-case rotation by 0, 90, 180 and 270 degrees */ | |
| 2263 if (fmod(angle + epsilon, 90.) < 2 * epsilon) { | |
| 2264 switch ((int)((angle + epsilon) / 90)) { | |
| 2265 case 0: /* 0 degrees */ | |
| 2266 memcpy(dst_coords, src_coords, 3 * sizeof(src_coords[0])); | |
| 2267 break; | |
| 2268 case 1: /* 90 degrees */ | |
| 2269 dst_coords[0] = (src_coords[0] * (axis[0] * axis[0]) + | |
| 2270 src_coords[1] * (axis[0] * axis[1] - axis[2]) + | |
| 2271 src_coords[2] * (axis[0] * axis[2] + axis[1])); | |
| 2272 dst_coords[1] = (src_coords[0] * (axis[0] * axis[1] + axis[2]) + | |
| 2273 src_coords[1] * (axis[1] * axis[1]) + | |
| 2274 src_coords[2] * (axis[1] * axis[2] - axis[0])); | |
| 2275 dst_coords[2] = (src_coords[0] * (axis[0] * axis[2] - axis[1]) + | |
| 2276 src_coords[1] * (axis[1] * axis[2] + axis[0]) + | |
| 2277 src_coords[2] * (axis[2] * axis[2])); | |
| 2278 break; | |
| 2279 case 2: /* 180 degrees */ | |
| 2280 dst_coords[0] = (src_coords[0] * (-1 + axis[0] * axis[0] * 2) + | |
| 2281 src_coords[1] * (axis[0] * axis[1] * 2) + | |
| 2282 src_coords[2] * (axis[0] * axis[2] * 2)); | |
| 2283 dst_coords[1] = (src_coords[0] * (axis[0] * axis[1] * 2) + | |
| 2284 src_coords[1] * (-1 + axis[1] * axis[1] * 2) + | |
| 2285 src_coords[2] * (axis[1] * axis[2] * 2)); | |
| 2286 dst_coords[2] = (src_coords[0] * (axis[0] * axis[2] * 2) + | |
| 2287 src_coords[1] * (axis[1] * axis[2] * 2) + | |
| 2288 src_coords[2] * (-1 + axis[2] * axis[2] * 2)); | |
| 2289 break; | |
| 2290 case 3: /* 270 degrees */ | |
| 2291 dst_coords[0] = (src_coords[0] * (axis[0] * axis[0]) + | |
| 2292 src_coords[1] * (axis[0] * axis[1] + axis[2]) + | |
| 2293 src_coords[2] * (axis[0] * axis[2] - axis[1])); | |
| 2294 dst_coords[1] = (src_coords[0] * (axis[0] * axis[1] - axis[2]) + | |
| 2295 src_coords[1] * (axis[1] * axis[1]) + | |
| 2296 src_coords[2] * (axis[1] * axis[2] + axis[0])); | |
| 2297 dst_coords[2] = (src_coords[0] * (axis[0] * axis[2] + axis[1]) + | |
| 2298 src_coords[1] * (axis[1] * axis[2] - axis[0]) + | |
| 2299 src_coords[2] * (axis[2] * axis[2])); | |
| 2300 break; | |
| 2024 | 2301 default: |
| 2302 /* this should NEVER happen and means a bug in the code */ | |
| 2303 PyErr_SetString(PyExc_RuntimeError, "Please report this bug in vector3_rotate_helper to the developers at pygame-users@seul.org"); | |
| 2304 return 0; | |
| 1994 | 2305 } |
| 2306 } | |
| 2307 else { | |
| 2308 angle = DEG2RAD(angle); | |
| 2309 sinValue = sin(angle); | |
| 2310 cosValue = cos(angle); | |
| 2311 cosComplement = 1 - cosValue; | |
| 2312 | |
| 2313 dst_coords[0] = (src_coords[0] * (cosValue + axis[0] * axis[0] * cosComplement) + | |
| 2314 src_coords[1] * (axis[0] * axis[1] * cosComplement - axis[2] * sinValue) + | |
| 2315 src_coords[2] * (axis[0] * axis[2] * cosComplement + axis[1] * sinValue)); | |
| 2316 dst_coords[1] = (src_coords[0] * (axis[0] * axis[1] * cosComplement + axis[2] * sinValue) + | |
| 2317 src_coords[1] * (cosValue + axis[1] * axis[1] * cosComplement) + | |
| 2318 src_coords[2] * (axis[1] * axis[2] * cosComplement - axis[0] * sinValue)); | |
| 2319 dst_coords[2] = (src_coords[0] * (axis[0] * axis[2] * cosComplement - axis[1] * sinValue) + | |
| 2320 src_coords[1] * (axis[1] * axis[2] * cosComplement + axis[0] * sinValue) + | |
| 2321 src_coords[2] * (cosValue + axis[2] * axis[2] * cosComplement)); | |
| 2322 } | |
| 2024 | 2323 return 1; |
| 1994 | 2324 } |
| 2325 | |
| 2326 static PyObject * | |
| 2327 vector3_rotate(PyVector *self, PyObject *args) | |
| 2328 { | |
| 2329 PyVector *ret; | |
| 2330 PyObject *axis; | |
| 2331 double axis_coords[3]; | |
| 2332 double angle; | |
| 2333 | |
| 2334 if (!PyArg_ParseTuple(args, "dO:rotate", &angle, &axis)) { | |
| 2335 return NULL; | |
| 2336 } | |
| 2337 if (!PyVectorCompatible_Check(axis, self->dim)) { | |
| 2338 PyErr_SetString(PyExc_TypeError, "axis must be a 3D Vector"); | |
| 2339 return NULL; | |
| 2340 } | |
| 2024 | 2341 if (!PySequence_AsVectorCoords(axis, axis_coords, 3)) { |
| 2342 return NULL; | |
| 2343 } | |
| 1994 | 2344 |
| 2345 ret = (PyVector*)PyVector_NEW(self->dim); | |
| 2024 | 2346 if (ret == NULL || !_vector3_rotate_helper(ret->coords, self->coords, |
| 2347 axis_coords, angle, | |
| 2348 self->epsilon)) { | |
| 2349 Py_XDECREF(ret); | |
| 2350 return NULL; | |
| 2351 } | |
| 1994 | 2352 return (PyObject*)ret; |
| 2353 } | |
| 2354 | |
| 2355 static PyObject * | |
| 2356 vector3_rotate_ip(PyVector *self, PyObject *args) | |
| 2357 { | |
| 2358 PyObject *axis; | |
| 2359 double axis_coords[3]; | |
| 2360 double angle; | |
| 2361 double tmp[3]; | |
| 2362 | |
| 2363 if (!PyArg_ParseTuple(args, "dO:rotate_ip", &angle, &axis)) { | |
| 2364 return NULL; | |
| 2365 } | |
| 2366 if (!PyVectorCompatible_Check(axis, self->dim)) { | |
| 2367 PyErr_SetString(PyExc_TypeError, "axis must be a 3D Vector"); | |
| 2368 return NULL; | |
| 2369 } | |
| 2024 | 2370 if (!PySequence_AsVectorCoords(axis, axis_coords, 3)) { |
| 2371 return NULL; | |
| 2372 } | |
| 2373 | |
| 1994 | 2374 memcpy(tmp, self->coords, 3 * sizeof(self->coords[0])); |
| 2024 | 2375 if (!_vector3_rotate_helper(self->coords, tmp, axis_coords, |
| 2376 angle, self->epsilon)) { | |
| 2377 return NULL; | |
| 2378 } | |
| 1994 | 2379 Py_RETURN_NONE; |
| 2380 } | |
| 2381 | |
| 2382 static PyObject * | |
| 2383 vector3_rotate_x(PyVector *self, PyObject *angleObject) | |
| 2384 { | |
| 2385 PyVector *ret; | |
| 2386 double sinValue, cosValue; | |
| 2387 double angle; | |
| 2388 | |
| 2024 | 2389 angle = DEG2RAD(PyFloat_AsDouble(angleObject)); |
| 2390 if (PyErr_Occurred()) { | |
| 1994 | 2391 return NULL; |
| 2392 } | |
| 2393 sinValue = sin(angle); | |
| 2394 cosValue = cos(angle); | |
| 2395 | |
| 2396 ret = (PyVector*)PyVector_NEW(self->dim); | |
| 2024 | 2397 if (ret == NULL) { |
| 2398 return NULL; | |
| 2399 } | |
| 1994 | 2400 ret->coords[0] = self->coords[0]; |
| 2401 ret->coords[1] = self->coords[1] * cosValue - self->coords[2] * sinValue; | |
| 2402 ret->coords[2] = self->coords[1] * sinValue + self->coords[2] * cosValue; | |
| 2403 return (PyObject*)ret; | |
| 2404 } | |
| 2405 | |
| 2406 static PyObject * | |
| 2407 vector3_rotate_x_ip(PyVector *self, PyObject *angleObject) | |
| 2408 { | |
| 2409 double tmp_coords[3]; | |
| 2410 double sinValue, cosValue; | |
| 2411 double angle; | |
| 2412 | |
| 2024 | 2413 angle = DEG2RAD(PyFloat_AsDouble(angleObject)); |
| 2414 if (PyErr_Occurred()) { | |
| 1994 | 2415 return NULL; |
| 2416 } | |
| 2417 sinValue = sin(angle); | |
| 2418 cosValue = cos(angle); | |
| 2419 memcpy(tmp_coords, self->coords, 3 * sizeof(tmp_coords[0])); | |
| 2420 | |
| 2421 self->coords[1] = tmp_coords[1] * cosValue - tmp_coords[2] * sinValue; | |
| 2422 self->coords[2] = tmp_coords[1] * sinValue + tmp_coords[2] * cosValue; | |
| 1997 | 2423 Py_RETURN_NONE; |
| 1994 | 2424 } |
| 2425 | |
| 2426 static PyObject * | |
| 2427 vector3_rotate_y(PyVector *self, PyObject *angleObject) | |
| 2428 { | |
| 2429 PyVector *ret; | |
| 2430 double sinValue, cosValue; | |
| 2431 double angle; | |
| 2432 | |
| 2024 | 2433 angle = DEG2RAD(PyFloat_AsDouble(angleObject)); |
| 2434 if (PyErr_Occurred()) { | |
| 1994 | 2435 return NULL; |
| 2436 } | |
| 2437 sinValue = sin(angle); | |
| 2438 cosValue = cos(angle); | |
| 2439 | |
| 2440 ret = (PyVector*)PyVector_NEW(self->dim); | |
| 2024 | 2441 if (ret == NULL) { |
| 2442 return NULL; | |
| 2443 } | |
| 1994 | 2444 ret->coords[0] = self->coords[0] * cosValue + self->coords[2] * sinValue; |
| 2445 ret->coords[1] = self->coords[1]; | |
| 2446 ret->coords[2] = -self->coords[0] * sinValue + self->coords[2] * cosValue; | |
| 2447 | |
| 2448 return (PyObject*)ret; | |
| 2449 } | |
| 2450 | |
| 2451 static PyObject * | |
| 2452 vector3_rotate_y_ip(PyVector *self, PyObject *angleObject) | |
| 2453 { | |
| 2454 double tmp_coords[3]; | |
| 2455 double sinValue, cosValue; | |
| 2456 double angle; | |
| 2457 | |
| 2024 | 2458 angle = DEG2RAD(PyFloat_AsDouble(angleObject)); |
| 2459 if (PyErr_Occurred()) { | |
| 1994 | 2460 return NULL; |
| 2461 } | |
| 2462 sinValue = sin(angle); | |
| 2463 cosValue = cos(angle); | |
| 2464 memcpy(tmp_coords, self->coords, 3 * sizeof(tmp_coords[0])); | |
| 2465 | |
| 2466 self->coords[0] = tmp_coords[0] * cosValue + tmp_coords[2] * sinValue; | |
| 2467 self->coords[2] = -tmp_coords[0] * sinValue + tmp_coords[2] * cosValue; | |
| 1997 | 2468 Py_RETURN_NONE; |
| 1994 | 2469 } |
| 2470 | |
| 2471 static PyObject * | |
| 2472 vector3_rotate_z(PyVector *self, PyObject *angleObject) | |
| 2473 { | |
| 2474 PyVector *ret; | |
| 2475 double sinValue, cosValue; | |
| 2476 double angle; | |
| 2477 | |
| 2024 | 2478 angle = DEG2RAD(PyFloat_AsDouble(angleObject)); |
| 2479 if (PyErr_Occurred()) { | |
| 1994 | 2480 return NULL; |
| 2481 } | |
| 2482 sinValue = sin(angle); | |
| 2483 cosValue = cos(angle); | |
| 2484 | |
| 2485 ret = (PyVector*)PyVector_NEW(self->dim); | |
| 2024 | 2486 if (ret == NULL) { |
| 2487 return NULL; | |
| 2488 } | |
| 1994 | 2489 ret->coords[0] = self->coords[0] * cosValue - self->coords[1] * sinValue; |
| 2490 ret->coords[1] = self->coords[0] * sinValue + self->coords[1] * cosValue; | |
| 2491 ret->coords[2] = self->coords[2]; | |
| 2492 | |
| 2493 return (PyObject*)ret; | |
| 2494 } | |
| 2495 | |
| 2496 static PyObject * | |
| 2497 vector3_rotate_z_ip(PyVector *self, PyObject *angleObject) | |
| 2498 { | |
| 2499 double tmp_coords[3]; | |
| 2500 double sinValue, cosValue; | |
| 2501 double angle; | |
| 2502 | |
| 2024 | 2503 angle = DEG2RAD(PyFloat_AsDouble(angleObject)); |
| 2504 if (PyErr_Occurred()) { | |
| 1994 | 2505 return NULL; |
| 2506 } | |
| 2507 sinValue = sin(angle); | |
| 2508 cosValue = cos(angle); | |
| 2509 memcpy(tmp_coords, self->coords, 3 * sizeof(tmp_coords[0])); | |
| 2510 | |
| 2511 self->coords[0] = tmp_coords[0] * cosValue - tmp_coords[1] * sinValue; | |
| 2512 self->coords[1] = tmp_coords[0] * sinValue + tmp_coords[1] * cosValue; | |
| 1997 | 2513 Py_RETURN_NONE; |
| 1994 | 2514 } |
| 2515 | |
| 2516 | |
| 2517 static PyObject * | |
| 2518 vector3_cross(PyVector *self, PyObject *other) | |
| 2519 { | |
| 2520 PyVector *ret; | |
| 2521 double *ret_coords; | |
| 2024 | 2522 double *self_coords; |
| 2523 double *other_coords; | |
| 1994 | 2524 |
| 2525 if (!PyVectorCompatible_Check(other, self->dim)) { | |
| 2526 PyErr_SetString(PyExc_TypeError, "cannot calculate cross Product"); | |
| 2527 return NULL; | |
| 2528 } | |
| 2529 | |
| 2024 | 2530 self_coords = self->coords; |
| 1994 | 2531 if (PyVector_Check(other)) { |
| 2024 | 2532 other_coords = ((PyVector *)other)->coords; |
| 1994 | 2533 } |
| 2534 else { | |
| 2024 | 2535 other_coords = PyMem_New(double, self->dim); |
| 2536 if (!PySequence_AsVectorCoords(other, other_coords, 3)) { | |
| 2537 PyMem_Del(other_coords); | |
| 2538 return NULL; | |
| 2539 } | |
| 1994 | 2540 } |
| 2024 | 2541 |
| 2542 ret = (PyVector*)PyVector_NEW(self->dim); | |
| 2543 if (ret == NULL) { | |
| 2544 if (!PyVector_Check(other)) | |
| 2545 PyMem_Del(other_coords); | |
| 2546 return NULL; | |
| 2547 } | |
| 2548 ret_coords = ret->coords; | |
| 2549 ret_coords[0] = ((self_coords[1] * other_coords[2]) - | |
| 2550 (self_coords[2] * other_coords[1])); | |
| 2551 ret_coords[1] = ((self_coords[2] * other_coords[0]) - | |
| 2552 (self_coords[0] * other_coords[2])); | |
| 2553 ret_coords[2] = ((self_coords[0] * other_coords[1]) - | |
| 2554 (self_coords[1] * other_coords[0])); | |
| 2555 | |
| 2556 if (!PyVector_Check(other)) | |
| 2557 PyMem_Del(other_coords); | |
| 2558 | |
| 1994 | 2559 return (PyObject*)ret; |
| 2560 } | |
| 2561 | |
| 2562 static PyObject * | |
| 2563 vector3_angle_to(PyVector *self, PyObject *other) | |
| 2564 { | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2565 double angle, tmp, squared_length1, squared_length2; |
| 1994 | 2566 double other_coords[VECTOR_MAX_SIZE]; |
| 2567 | |
| 2568 if (!PyVectorCompatible_Check(other, self->dim)) { | |
| 2569 PyErr_SetString(PyExc_TypeError, "expected an vector."); | |
| 2570 return NULL; | |
| 2571 } | |
| 2572 | |
| 2024 | 2573 if (!PySequence_AsVectorCoords(other, other_coords, self->dim)) { |
| 2574 return NULL; | |
| 2575 } | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2576 squared_length1 = _scalar_product(self->coords, self->coords, self->dim); |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2577 squared_length2 = _scalar_product(other_coords, other_coords, self->dim); |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2578 tmp = sqrt(squared_length1 * squared_length2); |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2579 if (tmp == 0) { |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2580 PyErr_SetString(PyExc_ValueError, "angle to zero vector is undefined."); |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2581 return NULL; |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2582 } |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2583 angle = acos(_scalar_product(self->coords, other_coords, self->dim) / tmp); |
| 1994 | 2584 return PyFloat_FromDouble(RAD2DEG(angle)); |
| 2585 } | |
| 2586 | |
| 2587 static PyObject * | |
| 2588 vector3_as_spherical(PyVector *self) | |
| 2589 { | |
| 2590 double r, theta, phi; | |
| 2591 r = sqrt(_scalar_product(self->coords, self->coords, self->dim)); | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2592 if (r == 0.) { |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2593 return Py_BuildValue("(ddd)", 0., 0., 0.); |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2594 } |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2595 theta = RAD2DEG(acos(self->coords[2] / r)); |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2596 phi = RAD2DEG(atan2(self->coords[1], self->coords[0])); |
| 1994 | 2597 return Py_BuildValue("(ddd)", r, theta, phi); |
| 2598 } | |
| 2599 | |
| 2600 static PyObject * | |
| 2601 vector3_from_spherical(PyVector *self, PyObject *args) | |
| 2602 { | |
| 2603 double r, theta, phi; | |
| 2604 | |
| 2024 | 2605 if (!PyArg_ParseTuple(args, "(ddd):vector3_from_spherical", |
| 2606 &r, &theta, &phi)) { | |
| 1994 | 2607 return NULL; |
| 2608 } | |
|
2035
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2609 theta = DEG2RAD(theta); |
|
28685c84e251
as/from_polar/spherical now also use degrees instead of radians
lorenz
parents:
2024
diff
changeset
|
2610 phi = DEG2RAD(phi); |
| 1994 | 2611 self->coords[0] = r * sin(theta) * cos(phi); |
| 2612 self->coords[1] = r * sin(theta) * sin(phi); | |
| 2613 self->coords[2] = r * cos(theta); | |
| 2614 | |
| 2615 Py_RETURN_NONE; | |
| 2616 } | |
| 2617 | |
| 2618 static PyMethodDef vector3_methods[] = { | |
| 2619 {"length", (PyCFunction)vector_length, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2620 DOC_VECTOR3LENGTH |
| 1994 | 2621 }, |
| 2622 {"length_squared", (PyCFunction)vector_length_squared, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2623 DOC_VECTOR3LENGTHSQUARED |
| 1994 | 2624 }, |
| 2625 {"rotate", (PyCFunction)vector3_rotate, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2626 DOC_VECTOR3ROTATE |
| 1994 | 2627 }, |
| 2628 {"rotate_ip", (PyCFunction)vector3_rotate_ip, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2629 DOC_VECTOR3ROTATEIP |
| 1994 | 2630 }, |
| 1997 | 2631 {"rotate_x", (PyCFunction)vector3_rotate_x, METH_O, |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2632 DOC_VECTOR3ROTATEX |
| 1994 | 2633 }, |
| 1997 | 2634 {"rotate_x_ip", (PyCFunction)vector3_rotate_x_ip, METH_O, |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2635 DOC_VECTOR3ROTATEXIP |
| 1994 | 2636 }, |
| 1997 | 2637 {"rotate_y", (PyCFunction)vector3_rotate_y, METH_O, |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2638 DOC_VECTOR3ROTATEY |
| 1994 | 2639 }, |
| 1997 | 2640 {"rotate_y_ip", (PyCFunction)vector3_rotate_y_ip, METH_O, |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2641 DOC_VECTOR3ROTATEYIP |
| 1994 | 2642 }, |
| 1997 | 2643 {"rotate_z", (PyCFunction)vector3_rotate_z, METH_O, |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2644 DOC_VECTOR3ROTATEZ |
| 1994 | 2645 }, |
| 1997 | 2646 {"rotate_z_ip", (PyCFunction)vector3_rotate_z_ip, METH_O, |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2647 DOC_VECTOR3ROTATEZIP |
| 1994 | 2648 }, |
| 2649 {"slerp", (PyCFunction)vector_slerp, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2650 DOC_VECTOR3SLERP |
| 1994 | 2651 }, |
| 2652 {"lerp", (PyCFunction)vector_lerp, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2653 DOC_VECTOR3LERP |
| 1994 | 2654 }, |
| 2655 {"normalize", (PyCFunction)vector_normalize, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2656 DOC_VECTOR3NORMALIZE |
| 1994 | 2657 }, |
| 2658 {"normalize_ip", (PyCFunction)vector_normalize_ip, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2659 DOC_VECTOR3NORMALIZEIP |
| 1994 | 2660 }, |
| 2661 {"is_normalized", (PyCFunction)vector_is_normalized, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2662 DOC_VECTOR3ISNORMALIZED |
| 1994 | 2663 }, |
| 2664 {"cross", (PyCFunction)vector3_cross, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2665 DOC_VECTOR3CROSS |
| 1994 | 2666 }, |
| 2667 {"dot", (PyCFunction)vector_dot, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2668 DOC_VECTOR3DOT |
| 1994 | 2669 }, |
| 2670 {"angle_to", (PyCFunction)vector3_angle_to, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2671 DOC_VECTOR3ANGLETO |
| 1994 | 2672 }, |
| 2673 {"scale_to_length", (PyCFunction)vector_scale_to_length, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2674 DOC_VECTOR3SCALETOLENGTH |
| 1994 | 2675 }, |
| 2676 {"reflect", (PyCFunction)vector_reflect, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2677 DOC_VECTOR3REFLECT |
| 1994 | 2678 }, |
| 2679 {"reflect_ip", (PyCFunction)vector_reflect_ip, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2680 DOC_VECTOR3REFLECTIP |
| 1994 | 2681 }, |
| 2682 {"distance_to", (PyCFunction)vector_distance_to, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2683 DOC_VECTOR3DISTANCETO |
| 1994 | 2684 }, |
| 2685 {"distance_squared_to", (PyCFunction)vector_distance_squared_to, METH_O, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2686 DOC_VECTOR3DISTANCESQUAREDTO |
| 1994 | 2687 }, |
| 2688 {"elementwise", (PyCFunction)vector_elementwise, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2689 DOC_VECTOR3ELEMENTWISE |
| 1994 | 2690 }, |
| 2691 {"as_spherical", (PyCFunction)vector3_as_spherical, METH_NOARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2692 DOC_VECTOR3ASSPHERICAL |
| 1994 | 2693 }, |
| 2694 {"from_spherical", (PyCFunction)vector3_from_spherical, METH_VARARGS, | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2695 DOC_VECTOR3FROMSPHERICAL |
| 1994 | 2696 }, |
| 2697 | |
| 2698 {NULL} /* Sentinel */ | |
| 2699 }; | |
| 2700 | |
| 2701 static PyGetSetDef vector3_getsets[] = { | |
| 2702 { "x", (getter)vector_getx, (setter)vector_setx, NULL, NULL }, | |
| 2703 { "y", (getter)vector_gety, (setter)vector_sety, NULL, NULL }, | |
| 2704 { "z", (getter)vector_getz, (setter)vector_setz, NULL, NULL }, | |
| 2705 { NULL, 0, NULL, NULL, NULL } /* Sentinel */ | |
| 2706 }; | |
| 2707 | |
| 2708 /******************************** | |
| 2709 * PyVector3 type definition | |
| 2710 ********************************/ | |
| 2711 | |
| 2712 static PyTypeObject PyVector3_Type = { | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2713 TYPE_HEAD (NULL, 0) |
| 1994 | 2714 "pygame.math.Vector3", /* tp_name */ |
| 2715 sizeof(PyVector), /* tp_basicsize */ | |
| 2716 0, /* tp_itemsize */ | |
| 2717 /* Methods to implement standard operations */ | |
| 2718 (destructor)vector_dealloc, /* tp_dealloc */ | |
| 2719 0, /* tp_print */ | |
| 2720 0, /* tp_getattr */ | |
| 2721 0, /* tp_setattr */ | |
| 2722 0, /* tp_compare */ | |
| 2723 (reprfunc)vector_repr, /* tp_repr */ | |
| 2724 /* Method suites for standard classes */ | |
| 2725 &vector_as_number, /* tp_as_number */ | |
| 2726 &vector_as_sequence, /* tp_as_sequence */ | |
|
2007
07d8a41f1593
reimplemented Vector2(Vector2().__repr__()) to support unicode (and thus Py3)
lorenz
parents:
2006
diff
changeset
|
2727 &vector_as_mapping, /* tp_as_mapping */ |
| 1994 | 2728 /* More standard operations (here for binary compatibility) */ |
| 2729 0, /* tp_hash */ | |
| 2730 0, /* tp_call */ | |
| 2731 (reprfunc)vector_str, /* tp_str */ | |
| 2732 (getattrofunc)vector_getAttr_swizzle, /* tp_getattro */ | |
| 2733 (setattrofunc)vector_setAttr_swizzle, /* tp_setattro */ | |
| 2734 /* Functions to access object as input/output buffer */ | |
| 2735 0, /* tp_as_buffer */ | |
| 2736 /* Flags to define presence of optional/expanded features */ | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2737 #if PY3 |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2738 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2739 #else |
| 1994 | 2740 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | |
| 2741 Py_TPFLAGS_CHECKTYPES, /* tp_flags */ | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2742 #endif |
| 1994 | 2743 /* Documentation string */ |
| 2744 DOC_PYGAMEMATHVECTOR3, /* tp_doc */ | |
| 2745 | |
| 2746 /* Assigned meaning in release 2.0 */ | |
| 2747 /* call function for all accessible objects */ | |
| 2748 0, /* tp_traverse */ | |
| 2749 /* delete references to contained objects */ | |
| 2750 0, /* tp_clear */ | |
| 2751 | |
| 2752 /* Assigned meaning in release 2.1 */ | |
| 2753 /* rich comparisons */ | |
| 2754 (richcmpfunc)vector_richcompare, /* tp_richcompare */ | |
| 2755 /* weak reference enabler */ | |
| 2756 0, /* tp_weaklistoffset */ | |
| 2757 | |
| 2758 /* Added in release 2.2 */ | |
| 2759 /* Iterators */ | |
| 2760 vector_iter, /* tp_iter */ | |
| 2761 0, /* tp_iternext */ | |
| 2762 /* Attribute descriptor and subclassing stuff */ | |
| 2763 vector3_methods, /* tp_methods */ | |
| 2764 vector_members, /* tp_members */ | |
| 2765 vector3_getsets, /* tp_getset */ | |
| 2766 0, /* tp_base */ | |
| 2767 0, /* tp_dict */ | |
| 2768 0, /* tp_descr_get */ | |
| 2769 0, /* tp_descr_set */ | |
| 2770 0, /* tp_dictoffset */ | |
| 2771 (initproc)vector3_init, /* tp_init */ | |
| 2772 0, /* tp_alloc */ | |
| 2773 (newfunc)vector3_new, /* tp_new */ | |
| 2774 0, /* tp_free */ | |
| 2775 0, /* tp_is_gc */ | |
| 2776 0, /* tp_bases */ | |
| 2777 0, /* tp_mro */ | |
| 2778 0, /* tp_cache */ | |
| 2779 0, /* tp_subclasses */ | |
| 2780 0, /* tp_weaklist */ | |
| 2781 }; | |
| 2782 | |
| 2783 | |
| 2784 | |
| 2785 | |
| 2786 | |
| 2787 | |
| 2788 | |
| 2789 | |
| 2790 | |
| 2791 | |
| 2792 | |
| 2793 | |
| 2794 /******************************************** | |
| 2795 * PyVectorIterator type definition | |
| 2796 ********************************************/ | |
| 2797 | |
| 2798 static void | |
| 2799 vectoriter_dealloc(vectoriter *it) | |
| 2800 { | |
| 2801 Py_XDECREF(it->vec); | |
| 2802 PyObject_Del(it); | |
| 2803 } | |
| 2804 | |
| 2805 static PyObject * | |
| 2806 vectoriter_next(vectoriter *it) | |
| 2807 { | |
| 2808 assert(it != NULL); | |
| 2809 if (it->vec == NULL) | |
| 2810 return NULL; | |
| 2811 assert(PyVector_Check(it->vec)); | |
| 2812 | |
| 2813 if (it->it_index < it->vec->dim) { | |
| 2814 double item = it->vec->coords[it->it_index]; | |
| 2815 ++(it->it_index); | |
| 2816 return PyFloat_FromDouble(item); | |
| 2817 } | |
| 2818 | |
| 2819 Py_DECREF(it->vec); | |
| 2820 it->vec = NULL; | |
| 2821 return NULL; | |
| 2822 } | |
| 2823 | |
| 2824 static PyObject * | |
| 2825 vectoriter_len(vectoriter *it) | |
| 2826 { | |
| 2827 Py_ssize_t len = 0; | |
| 2828 if (it && it->vec) { | |
| 2829 len = it->vec->dim - it->it_index; | |
| 2830 } | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2831 #if PY_VERSION_HEX >= 0x02050000 |
| 1994 | 2832 return PyInt_FromSsize_t(len); |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2833 #else |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2834 return PyInt_FromLong((long unsigned int)len); |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
2835 #endif |
| 1994 | 2836 } |
| 2837 | |
| 2838 static PyMethodDef vectoriter_methods[] = { | |
| 2839 {"__length_hint__", (PyCFunction)vectoriter_len, METH_NOARGS, | |
| 2840 }, | |
| 2841 {NULL, NULL} /* sentinel */ | |
| 2842 }; | |
| 2843 | |
| 2844 static PyTypeObject PyVectorIter_Type = { | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
2845 TYPE_HEAD (NULL, 0) |
| 1994 | 2846 "pygame.math.VectorIterator", /* tp_name */ |
| 2847 sizeof(vectoriter), /* tp_basicsize */ | |
| 2848 0, /* tp_itemsize */ | |
| 2849 (destructor)vectoriter_dealloc, /* tp_dealloc */ | |
| 2850 0, /* tp_print */ | |
| 2851 0, /* tp_getattr */ | |
| 2852 0, /* tp_setattr */ | |
| 2853 0, /* tp_compare */ | |
| 2854 0, /* tp_repr */ | |
| 2855 0, /* tp_as_number */ | |
| 2856 0, /* tp_as_sequence */ | |
| 2857 0, /* tp_as_mapping */ | |
| 2858 0, /* tp_hash */ | |
| 2859 0, /* tp_call */ | |
| 2860 0, /* tp_str */ | |
| 2861 PyObject_GenericGetAttr, /* tp_getattro */ | |
| 2862 0, /* tp_setattro */ | |
| 2863 0, /* tp_as_buffer */ | |
| 2864 Py_TPFLAGS_DEFAULT, /* tp_flags */ | |
| 2865 0, /* tp_doc */ | |
| 2866 0, /* tp_traverse */ | |
| 2867 0, /* tp_clear */ | |
| 2868 0, /* tp_richcompare */ | |
| 2869 0, /* tp_weaklistoffset */ | |
| 2870 PyObject_SelfIter, /* tp_iter */ | |
| 2871 (iternextfunc)vectoriter_next, /* tp_iternext */ | |
| 2872 vectoriter_methods, /* tp_methods */ | |
| 2873 0, /* tp_members */ | |
| 2874 }; | |
| 2875 | |
| 2876 static PyObject * | |
| 2877 vector_iter(PyObject *vec) | |
| 2878 { | |
| 2879 vectoriter *it; | |
| 2880 if (!PyVector_Check(vec)) { | |
| 2881 PyErr_BadInternalCall(); | |
| 2882 return NULL; | |
| 2883 } | |
| 2884 | |
| 2885 it = PyObject_New(vectoriter, &PyVectorIter_Type); | |
| 2886 if (it == NULL) | |
| 2887 return NULL; | |
| 2888 it->it_index = 0; | |
| 2889 Py_INCREF(vec); | |
| 2890 it->vec = (PyVector *)vec; | |
| 2891 return (PyObject *)it; | |
| 2892 } | |
| 2893 | |
| 2894 | |
| 2895 | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
2896 |
|
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
2897 |
| 1994 | 2898 |
| 2899 | |
| 2900 | |
| 2901 | |
| 2902 | |
| 2903 | |
| 2904 | |
| 2905 | |
| 2906 | |
| 2907 /***************************************** | |
| 2908 * elementwiseproxy | |
| 2909 *****************************************/ | |
| 2910 | |
| 2911 | |
| 2912 | |
| 2913 static void | |
| 2914 vector_elementwiseproxy_dealloc(vector_elementwiseproxy *it) | |
| 2915 { | |
| 2916 Py_XDECREF(it->vec); | |
| 2917 PyObject_Del(it); | |
| 2918 } | |
| 2919 | |
| 2920 static PyObject * | |
| 2921 vector_elementwiseproxy_richcompare(PyObject *o1, PyObject *o2, int op) | |
| 2922 { | |
| 2024 | 2923 int i, dim, ret; |
| 2924 double diff, value; | |
| 2925 double *other_coords; | |
| 1994 | 2926 PyVector *vec; |
| 2927 PyObject *other; | |
| 2928 | |
| 2929 if (vector_elementwiseproxy_Check(o1)) { | |
| 2930 vec = ((vector_elementwiseproxy*)o1)->vec; | |
| 2931 other = o2; | |
| 2932 } | |
| 2933 else { | |
| 2934 vec = ((vector_elementwiseproxy*)o2)->vec; | |
| 2935 other = o1; | |
| 2936 /* flip op */ | |
| 2937 if (op == Py_LT) | |
| 2938 op = Py_GE; | |
| 2939 else if (op == Py_LE) | |
| 2940 op = Py_GT; | |
| 2941 else if (op == Py_GT) | |
| 2942 op = Py_LE; | |
| 2943 else if (op == Py_GE) | |
| 2944 op = Py_LT; | |
| 2945 } | |
| 2946 if (vector_elementwiseproxy_Check(other)) | |
| 2024 | 2947 other = (PyObject*)((vector_elementwiseproxy*)other)->vec; |
| 1994 | 2948 dim = vec->dim; |
| 2949 | |
| 2024 | 2950 ret = 1; |
| 1994 | 2951 if (PyVectorCompatible_Check(other, dim)) { |
| 2024 | 2952 other_coords = PyMem_New(double, dim); |
| 2953 if (other_coords == NULL) { | |
| 2954 return NULL; | |
| 2955 } | |
| 2956 if (!PySequence_AsVectorCoords(other, other_coords, dim)) { | |
| 2957 PyMem_Del(other_coords); | |
| 2958 return NULL; | |
| 2959 } | |
| 1994 | 2960 /* use diff == diff to check for NaN */ |
| 2961 /* TODO: how should NaN be handled with LT/LE/GT/GE? */ | |
| 2962 switch (op) { | |
| 2963 case Py_EQ: | |
| 2964 for (i = 0; i < dim; i++) { | |
| 2024 | 2965 diff = vec->coords[i] - other_coords[i]; |
| 1994 | 2966 if ((diff != diff) || (fabs(diff) >= vec->epsilon)) { |
| 2024 | 2967 ret = 0; |
| 2968 break; | |
| 1994 | 2969 } |
| 2970 } | |
| 2024 | 2971 break; |
| 1994 | 2972 case Py_NE: |
| 2973 for (i = 0; i < dim; i++) { | |
| 2024 | 2974 diff = vec->coords[i] - other_coords[i]; |
| 1994 | 2975 if ((diff == diff) && (fabs(diff) < vec->epsilon)) { |
| 2024 | 2976 ret = 0; |
| 2977 break; | |
| 1994 | 2978 } |
| 2979 } | |
| 2024 | 2980 break; |
| 1994 | 2981 case Py_LT: |
| 2982 for (i = 0; i < dim; i++) { | |
| 2024 | 2983 if (vec->coords[i] >= other_coords[i]) { |
| 2984 ret = 0; | |
| 2985 break; | |
| 2986 } | |
| 1994 | 2987 } |
| 2024 | 2988 break; |
| 1994 | 2989 case Py_LE: |
| 2990 for (i = 0; i < dim; i++) { | |
| 2024 | 2991 if (vec->coords[i] > other_coords[i]) { |
| 2992 ret = 0; | |
| 2993 break; | |
| 2994 } | |
| 1994 | 2995 } |
| 2024 | 2996 break; |
| 1994 | 2997 case Py_GT: |
| 2998 for (i = 0; i < dim; i++) { | |
| 2024 | 2999 if (vec->coords[i] <= other_coords[i]) { |
| 3000 ret = 0; | |
| 3001 break; | |
| 3002 } | |
| 1994 | 3003 } |
| 2024 | 3004 break; |
| 1994 | 3005 case Py_GE: |
| 3006 for (i = 0; i < dim; i++) { | |
| 2024 | 3007 if (vec->coords[i] < other_coords[i]) { |
| 3008 ret = 0; | |
| 3009 break; | |
| 3010 } | |
| 1994 | 3011 } |
| 2024 | 3012 break; |
| 3013 default: | |
| 3014 PyMem_Del(other_coords); | |
| 3015 PyErr_BadInternalCall(); | |
| 3016 return NULL; | |
| 1994 | 3017 } |
| 2024 | 3018 PyMem_Del(other_coords); |
| 1994 | 3019 } |
| 3020 else if (RealNumber_Check(other)) { | |
| 2024 | 3021 /* the following PyFloat_AsDouble call should never fail because |
| 3022 then RealNumber_Check should have returned false */ | |
| 3023 value = PyFloat_AsDouble(other); | |
| 1994 | 3024 switch (op) { |
| 3025 case Py_EQ: | |
| 3026 for (i = 0; i < dim; i++) { | |
| 3027 diff = vec->coords[i] - value; | |
| 3028 if (diff != diff || fabs(diff) >= vec->epsilon) { | |
| 2024 | 3029 ret = 0; |
| 3030 break; | |
| 1994 | 3031 } |
| 3032 } | |
| 2024 | 3033 break; |
| 1994 | 3034 case Py_NE: |
| 3035 for (i = 0; i < dim; i++) { | |
| 3036 diff = vec->coords[i] - value; | |
| 3037 if (diff == diff && fabs(diff) < vec->epsilon) { | |
| 2024 | 3038 ret = 0; |
| 3039 break; | |
| 1994 | 3040 } |
| 3041 } | |
| 2024 | 3042 break; |
| 1994 | 3043 case Py_LT: |
| 3044 for (i = 0; i < dim; i++) { | |
| 2024 | 3045 if (vec->coords[i] >= value) { |
| 3046 ret = 0; | |
| 3047 break; | |
| 3048 } | |
| 1994 | 3049 } |
| 2024 | 3050 break; |
| 1994 | 3051 case Py_LE: |
| 3052 for (i = 0; i < dim; i++) { | |
| 2024 | 3053 if (vec->coords[i] > value) { |
| 3054 ret = 0; | |
| 3055 break; | |
| 3056 } | |
| 1994 | 3057 } |
| 2024 | 3058 break; |
| 1994 | 3059 case Py_GT: |
| 3060 for (i = 0; i < dim; i++) { | |
| 2024 | 3061 if (vec->coords[i] <= value) { |
| 3062 ret = 0; | |
| 3063 break; | |
| 3064 } | |
| 1994 | 3065 } |
| 2024 | 3066 break; |
| 1994 | 3067 case Py_GE: |
| 3068 for (i = 0; i < dim; i++) { | |
| 2024 | 3069 if (vec->coords[i] < value) { |
| 3070 ret = 0; | |
| 3071 break; | |
| 3072 } | |
| 1994 | 3073 } |
| 2024 | 3074 break; |
| 3075 default: | |
| 3076 PyErr_BadInternalCall(); | |
| 3077 return NULL; | |
| 1994 | 3078 } |
| 3079 } | |
| 2024 | 3080 else { |
| 3081 Py_INCREF(Py_NotImplemented); | |
| 3082 return Py_NotImplemented; | |
| 3083 } | |
| 3084 | |
| 3085 return PyBool_FromLong(ret); | |
| 1994 | 3086 } |
| 3087 | |
| 3088 | |
| 3089 | |
| 3090 | |
| 3091 /******************************************************* | |
| 3092 * vector_elementwiseproxy PyNumber emulation routines | |
| 3093 *******************************************************/ | |
| 3094 | |
| 3095 static PyObject * | |
| 3096 vector_elementwiseproxy_generic_math(PyObject *o1, PyObject *o2, int op) | |
| 3097 { | |
| 3098 int i, dim; | |
|
2085
186fbcb20a63
math module and gcc: remove distracting compiler warnings and address bug 52 at Bugzilla
Lenard Lindstrom <len-l@telus.net>
parents:
2071
diff
changeset
|
3099 double mod, other_value = 0.0; |
| 2024 | 3100 double other_coords[VECTOR_MAX_SIZE]; |
| 1994 | 3101 PyObject *other; |
| 3102 PyVector *vec, *ret; | |
| 3103 if (vector_elementwiseproxy_Check(o1)) { | |
| 3104 vec = ((vector_elementwiseproxy*)o1)->vec; | |
| 3105 other = o2; | |
| 3106 } | |
| 3107 else { | |
| 3108 other = o1; | |
| 3109 vec = ((vector_elementwiseproxy*)o2)->vec; | |
| 3110 op |= OP_ARG_REVERSE; | |
| 3111 } | |
| 3112 | |
| 3113 dim = vec->dim; | |
| 3114 | |
| 2024 | 3115 if (vector_elementwiseproxy_Check(other)) |
| 1994 | 3116 other = (PyObject*)((vector_elementwiseproxy*)other)->vec; |
| 2024 | 3117 |
| 3118 if (PyVectorCompatible_Check(other, dim)) { | |
| 1994 | 3119 op |= OP_ARG_VECTOR; |
| 2024 | 3120 if (!PySequence_AsVectorCoords(other, other_coords, dim)) |
| 3121 return NULL; | |
| 1994 | 3122 } |
| 2024 | 3123 else if (RealNumber_Check(other)) { |
| 1994 | 3124 op |= OP_ARG_NUMBER; |
| 2024 | 3125 other_value = PyFloat_AsDouble(other); |
| 3126 } | |
| 1994 | 3127 else |
| 3128 op |= OP_ARG_UNKNOWN; | |
| 3129 | |
| 2024 | 3130 ret = (PyVector*)PyVector_NEW(dim); |
| 3131 if (ret == NULL) { | |
| 3132 return NULL; | |
| 3133 } | |
| 3134 | |
| 3135 /* only handle special elementwise cases. | |
| 3136 * all others cases will be handled by the default clause */ | |
| 1994 | 3137 switch (op) { |
| 3138 case OP_ADD | OP_ARG_NUMBER: | |
| 3139 case OP_ADD | OP_ARG_NUMBER | OP_ARG_REVERSE: | |
| 3140 for (i = 0; i < dim; i++) | |
| 2024 | 3141 ret->coords[i] = vec->coords[i] + other_value; |
| 3142 break; | |
| 1994 | 3143 case OP_SUB | OP_ARG_NUMBER: |
| 3144 for (i = 0; i < dim; i++) | |
| 2024 | 3145 ret->coords[i] = vec->coords[i] - other_value; |
| 3146 break; | |
| 1994 | 3147 case OP_SUB | OP_ARG_NUMBER | OP_ARG_REVERSE: |
| 3148 for (i = 0; i < dim; i++) | |
| 2024 | 3149 ret->coords[i] = other_value - vec->coords[i]; |
| 3150 break; | |
| 1994 | 3151 case OP_MUL | OP_ARG_VECTOR: |
| 3152 case OP_MUL | OP_ARG_VECTOR | OP_ARG_REVERSE: | |
| 2024 | 3153 for (i = 0; i < vec->dim; i++) |
| 3154 ret->coords[i] = vec->coords[i] * other_coords[i]; | |
| 3155 break; | |
| 1994 | 3156 case OP_DIV | OP_ARG_VECTOR: |
| 3157 for (i = 0; i < vec->dim; i++) { | |
| 2024 | 3158 if (other_coords[i] == 0) { |
| 3159 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3160 Py_DECREF(ret); | |
| 3161 return NULL; | |
| 3162 } | |
| 3163 ret->coords[i] = vec->coords[i] / other_coords[i]; | |
| 1994 | 3164 } |
| 2024 | 3165 break; |
| 1994 | 3166 case OP_DIV | OP_ARG_VECTOR | OP_ARG_REVERSE: |
| 3167 for (i = 0; i < vec->dim; i++) { | |
| 2024 | 3168 if (vec->coords[i] == 0) { |
| 3169 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3170 Py_DECREF(ret); | |
| 3171 return NULL; | |
| 3172 } | |
| 3173 ret->coords[i] = other_coords[i] / vec->coords[i]; | |
| 1994 | 3174 } |
| 2024 | 3175 break; |
| 1994 | 3176 case OP_DIV | OP_ARG_NUMBER | OP_ARG_REVERSE: |
| 2024 | 3177 for (i = 0; i < vec->dim; i++) { |
| 3178 if (vec->coords[i] == 0) { | |
| 3179 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3180 Py_DECREF(ret); | |
| 3181 return NULL; | |
| 3182 } | |
| 3183 ret->coords[i] = other_value / vec->coords[i]; | |
| 3184 } | |
| 3185 break; | |
| 1994 | 3186 case OP_FLOOR_DIV | OP_ARG_VECTOR: |
| 3187 for (i = 0; i < vec->dim; i++) { | |
| 2024 | 3188 if (other_coords[i] == 0) { |
| 3189 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3190 Py_DECREF(ret); | |
| 3191 return NULL; | |
| 3192 } | |
| 3193 ret->coords[i] = floor(vec->coords[i] / other_coords[i]); | |
| 1994 | 3194 } |
| 2024 | 3195 break; |
| 1994 | 3196 case OP_FLOOR_DIV | OP_ARG_VECTOR | OP_ARG_REVERSE: |
| 3197 for (i = 0; i < vec->dim; i++) { | |
| 2024 | 3198 if (vec->coords[i] == 0) { |
| 3199 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3200 Py_DECREF(ret); | |
| 3201 return NULL; | |
| 3202 } | |
| 3203 ret->coords[i] = floor(other_coords[i] / vec->coords[i]); | |
| 1994 | 3204 } |
| 2024 | 3205 break; |
| 1994 | 3206 case OP_FLOOR_DIV | OP_ARG_NUMBER | OP_ARG_REVERSE: |
| 2024 | 3207 for (i = 0; i < vec->dim; i++) { |
| 3208 if (vec->coords[i] == 0) { | |
| 3209 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3210 Py_DECREF(ret); | |
| 3211 return NULL; | |
| 3212 } | |
| 3213 ret->coords[i] = floor(other_value / vec->coords[i]); | |
| 3214 } | |
| 3215 break; | |
| 1994 | 3216 case OP_MOD | OP_ARG_VECTOR: |
| 3217 for (i = 0; i < vec->dim; i++) { | |
| 2024 | 3218 if (other_coords[i] == 0) { |
| 3219 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3220 Py_DECREF(ret); | |
| 3221 return NULL; | |
| 3222 } | |
| 3223 mod = fmod(vec->coords[i], other_coords[i]); | |
| 1994 | 3224 /* note: checking mod*value < 0 is incorrect -- underflows to |
| 3225 0 if value < sqrt(smallest nonzero double) */ | |
| 2024 | 3226 if (mod && ((other_coords[i] < 0) != (mod < 0))) { |
| 3227 mod += other_coords[i]; | |
| 1994 | 3228 } |
| 3229 ret->coords[i] = mod; | |
| 3230 } | |
| 2024 | 3231 break; |
| 1994 | 3232 case OP_MOD | OP_ARG_VECTOR | OP_ARG_REVERSE: |
| 3233 for (i = 0; i < vec->dim; i++) { | |
| 2024 | 3234 if (vec->coords[i] == 0) { |
| 3235 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3236 Py_DECREF(ret); | |
| 3237 return NULL; | |
| 3238 } | |
| 3239 mod = fmod(other_coords[i], vec->coords[i]); | |
| 1994 | 3240 /* note: see above */ |
| 3241 if (mod && ((vec->coords[i] < 0) != (mod < 0))) { | |
| 3242 mod += vec->coords[i]; | |
| 3243 } | |
| 3244 ret->coords[i] = mod; | |
| 3245 } | |
| 2024 | 3246 break; |
| 1994 | 3247 case OP_MOD | OP_ARG_NUMBER: |
| 2024 | 3248 if (other_value == 0) { |
| 3249 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3250 Py_DECREF(ret); | |
| 3251 return NULL; | |
| 3252 } | |
| 1994 | 3253 for (i = 0; i < vec->dim; i++) { |
| 2024 | 3254 mod = fmod(vec->coords[i], other_value); |
| 1994 | 3255 /* note: see above */ |
| 2024 | 3256 if (mod && ((other_value < 0) != (mod < 0))) { |
| 3257 mod += other_value; | |
| 1994 | 3258 } |
| 3259 ret->coords[i] = mod; | |
| 3260 } | |
| 2024 | 3261 break; |
| 1994 | 3262 case OP_MOD | OP_ARG_NUMBER | OP_ARG_REVERSE: |
| 3263 for (i = 0; i < vec->dim; i++) { | |
| 2024 | 3264 if (vec->coords[i] == 0) { |
| 3265 PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); | |
| 3266 Py_DECREF(ret); | |
| 3267 return NULL; | |
| 3268 } | |
| 3269 mod = fmod(other_value, vec->coords[i]); | |
| 1994 | 3270 /* note: see above */ |
| 3271 if (mod && ((vec->coords[i] < 0) != (mod < 0))) { | |
| 3272 mod += vec->coords[i]; | |
| 3273 } | |
| 3274 ret->coords[i] = mod; | |
| 3275 } | |
| 2024 | 3276 break; |
| 1994 | 3277 default: |
| 2024 | 3278 Py_DECREF(ret); |
| 3279 return vector_generic_math((PyObject*)vec, other, op); | |
| 1994 | 3280 } |
| 2024 | 3281 return (PyObject*)ret; |
| 1994 | 3282 } |
| 3283 | |
| 3284 static PyObject * | |
| 3285 vector_elementwiseproxy_add(PyObject *o1, PyObject *o2) | |
| 3286 { | |
| 3287 return vector_elementwiseproxy_generic_math(o1, o2, OP_ADD); | |
| 3288 } | |
| 3289 static PyObject * | |
| 3290 vector_elementwiseproxy_sub(PyObject *o1, PyObject *o2) | |
| 3291 { | |
| 3292 return vector_elementwiseproxy_generic_math(o1, o2, OP_SUB); | |
| 3293 } | |
| 3294 static PyObject * | |
| 3295 vector_elementwiseproxy_mul(PyObject *o1, PyObject *o2) | |
| 3296 { | |
| 3297 return vector_elementwiseproxy_generic_math(o1, o2, OP_MUL); | |
| 3298 } | |
| 3299 static PyObject * | |
| 3300 vector_elementwiseproxy_div(PyObject *o1, PyObject *o2) | |
| 3301 { | |
| 3302 return vector_elementwiseproxy_generic_math(o1, o2, OP_DIV); | |
| 3303 } | |
| 3304 static PyObject * | |
| 3305 vector_elementwiseproxy_floor_div(PyObject *o1, PyObject *o2) | |
| 3306 { | |
| 3307 return vector_elementwiseproxy_generic_math(o1, o2, OP_FLOOR_DIV); | |
| 3308 } | |
| 3309 static PyObject * | |
| 3310 vector_elementwiseproxy_mod(PyObject *o1, PyObject *o2) | |
| 3311 { | |
| 3312 return vector_elementwiseproxy_generic_math(o1, o2, OP_MOD); | |
| 3313 } | |
| 3314 | |
| 3315 static PyObject * | |
| 3316 vector_elementwiseproxy_pow(PyObject *baseObj, PyObject *expoObj, PyObject *mod) | |
| 3317 { | |
| 3318 int i, dim; | |
| 2024 | 3319 double *tmp; |
| 3320 PyObject *bases[VECTOR_MAX_SIZE]; | |
| 3321 PyObject *expos[VECTOR_MAX_SIZE]; | |
| 3322 PyObject *ret, *result; | |
| 1994 | 3323 if (mod != Py_None) { |
| 3324 PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not " | |
| 2024 | 3325 "supported for vectors"); |
| 1994 | 3326 return NULL; |
| 3327 } | |
| 3328 | |
| 3329 if (vector_elementwiseproxy_Check(baseObj)) { | |
| 3330 dim = ((vector_elementwiseproxy*)baseObj)->vec->dim; | |
| 2024 | 3331 tmp = ((vector_elementwiseproxy*)baseObj)->vec->coords; |
| 3332 for (i = 0; i < dim; ++i) | |
| 3333 bases[i] = PyFloat_FromDouble(tmp[i]); | |
| 1994 | 3334 if (vector_elementwiseproxy_Check(expoObj)) { |
| 2024 | 3335 tmp = ((vector_elementwiseproxy*)expoObj)->vec->coords; |
| 3336 for (i = 0; i < dim; ++i) | |
| 3337 expos[i] = PyFloat_FromDouble(tmp[i]); | |
| 1994 | 3338 } |
| 3339 else if (PyVectorCompatible_Check(expoObj, dim)) { | |
| 2024 | 3340 for (i = 0; i < dim; ++i) |
| 3341 expos[i] = PySequence_ITEM(expoObj, i); | |
| 1994 | 3342 } |
| 3343 else if (RealNumber_Check(expoObj)) { | |
| 2024 | 3344 /* INCREF so that we can unify the clean up code */ |
| 3345 for (i = 0; i < dim; i++) { | |
| 3346 expos[i] = expoObj; | |
| 3347 Py_INCREF(expoObj); | |
| 3348 } | |
| 1994 | 3349 } |
| 2024 | 3350 else { |
| 3351 Py_INCREF(Py_NotImplemented); | |
| 3352 ret = Py_NotImplemented; | |
| 3353 goto clean_up; | |
| 3354 } | |
| 1994 | 3355 } |
| 3356 else { | |
| 3357 dim = ((vector_elementwiseproxy*)expoObj)->vec->dim; | |
| 2024 | 3358 tmp = ((vector_elementwiseproxy*)expoObj)->vec->coords; |
| 3359 for (i = 0; i < dim; ++i) | |
| 3360 expos[i] = PyFloat_FromDouble(tmp[i]); | |
| 1994 | 3361 if (PyVectorCompatible_Check(baseObj, dim)) { |
| 2024 | 3362 for (i = 0; i < dim; ++i) |
| 3363 bases[i] = PySequence_ITEM(baseObj, i); | |
| 1994 | 3364 } |
| 3365 else if (RealNumber_Check(baseObj)) { | |
| 2024 | 3366 /* INCREF so that we can unify the clean up code */ |
| 3367 for (i = 0; i < dim; i++) { | |
| 3368 bases[i] = baseObj; | |
| 3369 Py_INCREF(baseObj); | |
| 3370 } | |
| 3371 } | |
| 3372 else { | |
| 3373 Py_INCREF(Py_NotImplemented); | |
| 3374 ret = Py_NotImplemented; | |
| 3375 goto clean_up; | |
| 1994 | 3376 } |
| 2024 | 3377 } |
| 3378 if (PyErr_Occurred()) { | |
| 3379 ret = NULL; | |
| 3380 goto clean_up; | |
| 1994 | 3381 } |
| 3382 | |
| 2024 | 3383 ret = PyVector_NEW(dim); |
|
2008
f9fe1fb021b3
better error checking and support for Py3 in math.Vector.elementwise.pow()
lorenz
parents:
2007
diff
changeset
|
3384 if (ret == NULL) |
| 2024 | 3385 goto clean_up; |
| 3386 /* there are many special cases so we let python do the work for us */ | |
| 1994 | 3387 for (i = 0; i < dim; i++) { |
| 2024 | 3388 result = PyNumber_Power(bases[i], expos[i], Py_None); |
| 3389 if (result == NULL || !RealNumber_Check(result)) { | |
| 3390 /* raising a negative number to a fractional power returns a | |
| 3391 * complex in python-3.x. we do not allow this. */ | |
| 3392 if (!PyErr_Occurred()) { | |
|
2008
f9fe1fb021b3
better error checking and support for Py3 in math.Vector.elementwise.pow()
lorenz
parents:
2007
diff
changeset
|
3393 PyErr_SetString(PyExc_ValueError, "negative number " |
|
f9fe1fb021b3
better error checking and support for Py3 in math.Vector.elementwise.pow()
lorenz
parents:
2007
diff
changeset
|
3394 "cannot be raised to a fractional power"); |
| 2024 | 3395 } |
| 3396 Py_XDECREF(result); | |
| 3397 Py_DECREF(ret); | |
| 3398 ret = NULL; | |
| 3399 goto clean_up; | |
|
2008
f9fe1fb021b3
better error checking and support for Py3 in math.Vector.elementwise.pow()
lorenz
parents:
2007
diff
changeset
|
3400 } |
| 2024 | 3401 ((PyVector*)ret)->coords[i] = PyFloat_AsDouble(result); |
| 1994 | 3402 Py_DECREF(result); |
| 3403 } | |
| 2024 | 3404 clean_up: |
| 3405 for (i = 0; i < dim; ++i) { | |
| 3406 Py_XDECREF(bases[i]); | |
| 3407 Py_XDECREF(expos[i]); | |
| 3408 } | |
| 3409 return ret; | |
| 1994 | 3410 } |
| 3411 | |
| 3412 | |
| 3413 static PyObject * | |
| 3414 vector_elementwiseproxy_abs(vector_elementwiseproxy *self) | |
| 3415 { | |
| 3416 int i; | |
| 3417 PyVector *ret = (PyVector*)PyVector_NEW(self->vec->dim); | |
| 2024 | 3418 if (ret != NULL) { |
| 3419 for (i = 0; i < self->vec->dim; i++) { | |
| 3420 ret->coords[i] = fabs(self->vec->coords[i]); | |
| 3421 } | |
| 1994 | 3422 } |
| 3423 return (PyObject*)ret; | |
| 3424 } | |
| 3425 | |
| 3426 static PyObject * | |
| 3427 vector_elementwiseproxy_neg(vector_elementwiseproxy *self) | |
| 3428 { | |
| 2024 | 3429 return vector_neg(self->vec); |
| 1994 | 3430 } |
| 3431 | |
| 3432 static PyObject * | |
| 3433 vector_elementwiseproxy_pos(vector_elementwiseproxy *self) | |
| 3434 { | |
| 2024 | 3435 return vector_pos(self->vec); |
| 1994 | 3436 } |
| 3437 | |
| 3438 static int | |
| 3439 vector_elementwiseproxy_nonzero(vector_elementwiseproxy *self) | |
| 3440 { | |
| 2024 | 3441 return vector_nonzero(self->vec); |
| 1994 | 3442 } |
| 3443 | |
| 3444 static PyNumberMethods vector_elementwiseproxy_as_number = { | |
| 3445 (binaryfunc)vector_elementwiseproxy_add, /* nb_add; __add__ */ | |
| 3446 (binaryfunc)vector_elementwiseproxy_sub, /* nb_subtract; __sub__ */ | |
| 3447 (binaryfunc)vector_elementwiseproxy_mul, /* nb_multiply; __mul__ */ | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
3448 #if !PY3 |
| 1994 | 3449 (binaryfunc)vector_elementwiseproxy_div, /* nb_divide; __div__ */ |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
3450 #endif |
| 1994 | 3451 (binaryfunc)vector_elementwiseproxy_mod, /* nb_remainder; __mod__ */ |
| 3452 (binaryfunc)0, /* nb_divmod; __divmod__ */ | |
| 3453 (ternaryfunc)vector_elementwiseproxy_pow, /* nb_power; __pow__ */ | |
| 3454 (unaryfunc)vector_elementwiseproxy_neg, /* nb_negative; __neg__ */ | |
| 3455 (unaryfunc)vector_elementwiseproxy_pos, /* nb_positive; __pos__ */ | |
| 3456 (unaryfunc)vector_elementwiseproxy_abs, /* nb_absolute; __abs__ */ | |
| 3457 (inquiry)vector_elementwiseproxy_nonzero, /* nb_nonzero; __nonzero__ */ | |
| 3458 (unaryfunc)0, /* nb_invert; __invert__ */ | |
| 3459 (binaryfunc)0, /* nb_lshift; __lshift__ */ | |
| 3460 (binaryfunc)0, /* nb_rshift; __rshift__ */ | |
| 3461 (binaryfunc)0, /* nb_and; __and__ */ | |
| 3462 (binaryfunc)0, /* nb_xor; __xor__ */ | |
| 3463 (binaryfunc)0, /* nb_or; __or__ */ | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
3464 #if !PY3 |
| 1994 | 3465 (coercion)0, /* nb_coerce; __coerce__ */ |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
3466 #endif |
| 1994 | 3467 (unaryfunc)0, /* nb_int; __int__ */ |
| 3468 (unaryfunc)0, /* nb_long; __long__ */ | |
| 3469 (unaryfunc)0, /* nb_float; __float__ */ | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
3470 #if !PY3 |
| 1994 | 3471 (unaryfunc)0, /* nb_oct; __oct__ */ |
| 3472 (unaryfunc)0, /* nb_hex; __hex__ */ | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
3473 #endif |
| 1994 | 3474 /* Added in release 2.0 */ |
| 3475 (binaryfunc)0, /* nb_inplace_add; __iadd__ */ | |
| 3476 (binaryfunc)0, /* nb_inplace_subtract; __isub__ */ | |
| 3477 (binaryfunc)0, /* nb_inplace_multiply; __imul__ */ | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
3478 #if !PY3 |
| 1994 | 3479 (binaryfunc)0, /* nb_inplace_divide; __idiv__ */ |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
3480 #endif |
| 1994 | 3481 (binaryfunc)0, /* nb_inplace_remainder; __imod__ */ |
| 3482 (ternaryfunc)0, /* nb_inplace_power; __pow__ */ | |
| 3483 (binaryfunc)0, /* nb_inplace_lshift; __ilshift__ */ | |
| 3484 (binaryfunc)0, /* nb_inplace_rshift; __irshift__ */ | |
| 3485 (binaryfunc)0, /* nb_inplace_and; __iand__ */ | |
| 3486 (binaryfunc)0, /* nb_inplace_xor; __ixor__ */ | |
| 3487 (binaryfunc)0, /* nb_inplace_or; __ior__ */ | |
| 3488 | |
| 3489 /* Added in release 2.2 */ | |
| 3490 (binaryfunc)vector_elementwiseproxy_floor_div, /* nb_floor_divide; __floor__ */ | |
| 3491 (binaryfunc)vector_elementwiseproxy_div, /* nb_true_divide; __truediv__ */ | |
| 3492 (binaryfunc)0, /* nb_inplace_floor_divide; __ifloor__ */ | |
| 3493 (binaryfunc)0, /* nb_inplace_true_divide; __itruediv__ */ | |
| 3494 }; | |
| 3495 | |
| 3496 | |
| 3497 | |
| 3498 | |
| 3499 static PyTypeObject PyVectorElementwiseProxy_Type = { | |
|
2004
8c57b44e60a8
some more Py3k fixes. compiles but test don't pass yet.
lorenz
parents:
2002
diff
changeset
|
3500 TYPE_HEAD (NULL, 0) |
| 1994 | 3501 "pygame.math.VectorElementwiseProxy", /* tp_name */ |
| 3502 sizeof(vector_elementwiseproxy), /* tp_basicsize */ | |
| 3503 0, /* tp_itemsize */ | |
| 3504 /* Methods to implement standard operations */ | |
| 3505 (destructor)vector_elementwiseproxy_dealloc, /* tp_dealloc */ | |
| 3506 0, /* tp_print */ | |
| 3507 0, /* tp_getattr */ | |
| 3508 0, /* tp_setattr */ | |
| 3509 0, /* tp_compare */ | |
| 3510 (reprfunc)0, /* tp_repr */ | |
| 3511 /* Method suites for standard classes */ | |
| 3512 &vector_elementwiseproxy_as_number, /* tp_as_number */ | |
| 3513 0, /* tp_as_sequence */ | |
| 3514 0, /* tp_as_mapping */ | |
| 3515 /* More standard operations (here for binary compatibility) */ | |
| 3516 0, /* tp_hash */ | |
| 3517 0, /* tp_call */ | |
| 3518 (reprfunc)0, /* tp_str */ | |
| 3519 (getattrofunc)0, /* tp_getattro */ | |
| 3520 (setattrofunc)0, /* tp_setattro */ | |
| 3521 /* Functions to access object as input/output buffer */ | |
| 3522 0, /* tp_as_buffer */ | |
| 3523 /* Flags to define presence of optional/expanded features */ | |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
3524 #if PY3 |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
3525 Py_TPFLAGS_DEFAULT, |
|
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
3526 #else |
| 1994 | 3527 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ |
|
1999
bf7e84f0e55e
some changes to math.c to hopefully appease the mighty windows build-bots
lorenz
parents:
1997
diff
changeset
|
3528 #endif |
| 1994 | 3529 /* Documentation string */ |
| 3530 0, /* tp_doc */ | |
| 3531 | |
| 3532 /* Assigned meaning in release 2.0 */ | |
| 3533 /* call function for all accessible objects */ | |
| 3534 0, /* tp_traverse */ | |
| 3535 /* delete references to contained objects */ | |
| 3536 0, /* tp_clear */ | |
| 3537 | |
| 3538 /* Assigned meaning in release 2.1 */ | |
| 3539 /* rich comparisons */ | |
| 3540 (richcmpfunc)vector_elementwiseproxy_richcompare, /* tp_richcompare */ | |
| 3541 /* weak reference enabler */ | |
| 3542 0, /* tp_weaklistoffset */ | |
| 3543 | |
| 3544 /* Added in release 2.2 */ | |
| 3545 /* Iterators */ | |
| 3546 0, /* tp_iter */ | |
| 3547 0, /* tp_iternext */ | |
| 3548 /* Attribute descriptor and subclassing stuff */ | |
| 3549 0, /* tp_methods */ | |
| 3550 0, /* tp_members */ | |
| 3551 0, /* tp_getset */ | |
| 3552 0, /* tp_base */ | |
| 3553 0, /* tp_dict */ | |
| 3554 0, /* tp_descr_get */ | |
| 3555 0, /* tp_descr_set */ | |
| 3556 0, /* tp_dictoffset */ | |
| 3557 (initproc)0, /* tp_init */ | |
| 3558 0, /* tp_alloc */ | |
| 3559 (newfunc)0, /* tp_new */ | |
| 3560 0, /* tp_free */ | |
| 3561 0, /* tp_is_gc */ | |
| 3562 0, /* tp_bases */ | |
| 3563 0, /* tp_mro */ | |
| 3564 0, /* tp_cache */ | |
| 3565 0, /* tp_subclasses */ | |
| 3566 0, /* tp_weaklist */ | |
| 3567 }; | |
| 3568 | |
| 3569 | |
| 3570 | |
| 3571 static PyObject * | |
| 3572 vector_elementwise(PyVector *vec) | |
| 3573 { | |
| 3574 vector_elementwiseproxy *proxy; | |
| 3575 if (!PyVector_Check(vec)) { | |
| 3576 PyErr_BadInternalCall(); | |
| 3577 return NULL; | |
| 3578 } | |
| 3579 | |
| 3580 proxy = PyObject_New(vector_elementwiseproxy, | |
| 3581 &PyVectorElementwiseProxy_Type); | |
| 3582 if (proxy == NULL) | |
| 3583 return NULL; | |
| 3584 Py_INCREF(vec); | |
| 3585 proxy->vec = (PyVector *)vec; | |
| 3586 return (PyObject *)proxy; | |
| 3587 } | |
| 3588 | |
| 3589 | |
| 3590 | |
| 3591 | |
| 3592 | |
| 3593 | |
| 3594 | |
| 3595 static PyObject * | |
| 3596 math_enable_swizzling(PyVector *self) | |
| 3597 { | |
| 3598 swizzling_enabled = 1; | |
| 3599 Py_RETURN_NONE; | |
| 3600 } | |
| 3601 | |
| 3602 static PyObject * | |
| 3603 math_disable_swizzling(PyVector *self) | |
| 3604 { | |
| 3605 swizzling_enabled = 0; | |
| 3606 Py_RETURN_NONE; | |
| 3607 } | |
| 3608 | |
| 3609 static PyMethodDef _math_methods[] = | |
| 3610 { | |
| 3611 {"enable_swizzling", (PyCFunction)math_enable_swizzling, METH_NOARGS, | |
| 3612 "enables swizzling." | |
| 3613 }, | |
| 3614 {"disable_swizzling", (PyCFunction)math_disable_swizzling, METH_NOARGS, | |
| 3615 "disables swizzling." | |
| 3616 }, | |
| 3617 {NULL, NULL, 0, NULL} | |
| 3618 }; | |
| 3619 | |
| 3620 | |
| 3621 /**************************** | |
| 3622 * Module init function | |
| 3623 ****************************/ | |
| 3624 | |
| 3625 MODINIT_DEFINE (math) | |
| 3626 { | |
| 3627 PyObject *module, *apiobj; | |
| 3628 static void *c_api[PYGAMEAPI_MATH_NUMSLOTS]; | |
| 3629 | |
| 3630 #if PY3 | |
| 3631 static struct PyModuleDef _module = { | |
| 3632 PyModuleDef_HEAD_INIT, | |
| 3633 "math", | |
| 3634 DOC_PYGAMEMATH, | |
| 3635 -1, | |
| 3636 _math_methods, | |
| 3637 NULL, NULL, NULL, NULL | |
| 3638 }; | |
| 3639 #endif | |
| 3640 | |
| 3641 /* initialize the extension types */ | |
| 3642 if ((PyType_Ready(&PyVector2_Type) < 0) || | |
| 3643 (PyType_Ready(&PyVector3_Type) < 0) || | |
| 3644 (PyType_Ready(&PyVectorIter_Type) < 0) || | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
3645 (PyType_Ready(&PyVectorElementwiseProxy_Type) < 0) /*|| |
| 1994 | 3646 (PyType_Ready(&PyVector4_Type) < 0)*/) { |
| 3647 MODINIT_ERROR; | |
| 3648 } | |
| 3649 | |
| 3650 /* initialize the module */ | |
| 3651 #if PY3 | |
| 3652 module = PyModule_Create (&_module); | |
| 3653 #else | |
| 3654 module = Py_InitModule3 (MODPREFIX "math", _math_methods, DOC_PYGAMEMATH); | |
| 3655 #endif | |
| 3656 | |
| 3657 if (module == NULL) { | |
| 3658 MODINIT_ERROR; | |
| 3659 } | |
| 3660 | |
| 3661 /* add extension types to module */ | |
| 3662 Py_INCREF(&PyVector2_Type); | |
| 3663 Py_INCREF(&PyVector3_Type); | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
3664 Py_INCREF(&PyVectorIter_Type); |
| 1994 | 3665 Py_INCREF(&PyVectorElementwiseProxy_Type); |
| 2024 | 3666 /* |
| 3667 Py_INCREF(&PyVector4_Type); | |
| 3668 */ | |
| 1994 | 3669 if ((PyModule_AddObject(module, "Vector2", (PyObject *)&PyVector2_Type) != 0) || |
| 3670 (PyModule_AddObject(module, "Vector3", (PyObject *)&PyVector3_Type) != 0) || | |
| 3671 (PyModule_AddObject(module, "VectorElementwiseProxy", (PyObject *)&PyVectorElementwiseProxy_Type) != 0) || | |
|
2006
6a532cb218dd
removed iterator versions of vector.slerp() and .lerp() in favour of a parametrized version.
lorenz
parents:
2005
diff
changeset
|
3672 (PyModule_AddObject(module, "VectorIterator", (PyObject *)&PyVectorIter_Type) != 0) /*|| |
| 1994 | 3673 (PyModule_AddObject(module, "Vector4", (PyObject *)&PyVector4_Type) != 0)*/) { |
| 3674 Py_DECREF(&PyVector2_Type); | |
| 3675 Py_DECREF(&PyVector3_Type); | |
| 3676 Py_DECREF(&PyVectorElementwiseProxy_Type); | |
| 3677 Py_DECREF(&PyVectorIter_Type); | |
| 2024 | 3678 /* |
| 3679 Py_DECREF(&PyVector4_Type); | |
| 3680 */ | |
| 1994 | 3681 DECREF_MOD (module); |
| 3682 MODINIT_ERROR; | |
| 3683 } | |
| 3684 | |
| 3685 /* export the C api */ | |
| 3686 c_api[0] = &PyVector2_Type; | |
| 3687 c_api[1] = &PyVector3_Type; | |
| 2024 | 3688 /* |
| 3689 c_api[2] = &PyVector4_Type; | |
| 3690 c_api[3] = PyVector_NEW; | |
| 3691 c_api[4] = PyVectorCompatible_Check; | |
| 3692 */ | |
|
2120
42e2bde1a12c
Use capsule objects in preference to cobject objects. This allows Pygame to build an run from Python 3.2, which has to cobjects.
Lenard Lindstrom <len-l@telus.net>
parents:
2085
diff
changeset
|
3693 apiobj = encapsulate_api(c_api, "math"); |
| 1994 | 3694 if (apiobj == NULL) { |
| 3695 DECREF_MOD (module); | |
| 3696 MODINIT_ERROR; | |
| 3697 } | |
| 3698 | |
| 3699 if (PyModule_AddObject(module, PYGAMEAPI_LOCAL_ENTRY, apiobj) != 0) { | |
| 3700 Py_DECREF (apiobj); | |
| 3701 DECREF_MOD (module); | |
| 3702 MODINIT_ERROR; | |
| 3703 } | |
| 3704 | |
| 3705 MODINIT_RETURN (module); | |
| 3706 } |
