|
1 | 1 | #include "include/pygame.h" |
2 | 2 | #include "include/geometry.h" |
3 | 3 | #include "include/collisions.h" |
4 | | -#include "include/methods.h" |
5 | 4 |
|
6 | 5 | #include <limits.h> |
7 | 6 | #include <math.h> |
@@ -210,29 +209,55 @@ pg_line_copy(pgLineObject *self, PyObject *_null) |
210 | 209 | } |
211 | 210 |
|
212 | 211 | static PyObject * |
213 | | -pg_line_raycast(pgLineObject *self, PyObject *sequence) |
| 212 | +pg_line_raycast(pgLineObject *self, PyObject* const* args, Py_ssize_t nargs) |
214 | 213 | { |
215 | | - PyObject *list = PyList_New(1); |
| 214 | + PyObject **farr; |
| 215 | + Py_ssize_t loop; |
216 | 216 |
|
217 | | - if (list == NULL) { |
218 | | - return NULL; |
| 217 | + if (nargs != 1) { |
| 218 | + return RAISE(PyExc_TypeError, "raycast() takes exactly 1 argument"); |
| 219 | + } |
| 220 | + if (!PySequence_FAST_CHECK(args[0])) { |
| 221 | + return RAISE(PyExc_TypeError, |
| 222 | + "raycast() first argument must be a sequence"); |
| 223 | + } |
| 224 | + |
| 225 | + Py_ssize_t length = PySequence_Fast_GET_SIZE(args[0]); |
| 226 | + |
| 227 | + if (length == 0) { |
| 228 | + Py_RETURN_NONE; |
219 | 229 | } |
220 | 230 |
|
221 | | - PyList_SET_ITEM(list, 0, (PyObject *)self); |
| 231 | + farr = PySequence_Fast_ITEMS(args[0]); |
| 232 | + |
| 233 | + pgLineBase other_line; |
222 | 234 |
|
223 | | - PyObject *args[2] = { |
224 | | - list, |
225 | | - sequence, |
226 | | - }; |
227 | | - PyObject *delete_list = |
228 | | - pg_geometry_raycast(NULL, (PyObject *const *)args, 2); |
229 | | - PyObject *ret = PyList_GET_ITEM(delete_list, 0); |
230 | | - Py_INCREF(ret); |
| 235 | + double record = DBL_MAX; |
| 236 | + double closest_x = 0, closest_y = 0; |
| 237 | + double x = 0, y = 0; |
231 | 238 |
|
232 | | - Py_DECREF(delete_list); |
233 | | - Py_DECREF(list); |
| 239 | + for (loop = 0; loop < length; loop++) { |
| 240 | + if (!pgLine_FromObject(farr[loop], &other_line)) { |
| 241 | + return RAISE( |
| 242 | + PyExc_TypeError, |
| 243 | + "raycast() first argument must be a sequence of Line or " |
| 244 | + "LineLike objects"); |
| 245 | + } |
| 246 | + |
| 247 | + if (pgIntersection_LineLine(&(self->line), &other_line, &x, &y)) { |
| 248 | + double xxyy = sqrt(x * x + y * y); |
| 249 | + if (xxyy < record) { |
| 250 | + record = xxyy; |
| 251 | + closest_x = x; |
| 252 | + closest_y = y; |
| 253 | + } |
| 254 | + } |
| 255 | + } |
234 | 256 |
|
235 | | - return ret; |
| 257 | + if (record == DBL_MAX) { |
| 258 | + Py_RETURN_NONE; |
| 259 | + } |
| 260 | + return Py_BuildValue("(dd)", closest_x, closest_y); |
236 | 261 | } |
237 | 262 |
|
238 | 263 | static PyObject * |
@@ -307,7 +332,7 @@ pg_line_update(pgLineObject *self, PyObject *const *args, Py_ssize_t nargs) |
307 | 332 | static struct PyMethodDef pg_line_methods[] = { |
308 | 333 | {"__copy__", (PyCFunction)pg_line_copy, METH_NOARGS, NULL}, |
309 | 334 | {"copy", (PyCFunction)pg_line_copy, METH_NOARGS, NULL}, |
310 | | - {"raycast", (PyCFunction)pg_line_raycast, METH_O, NULL}, |
| 335 | + {"raycast", (PyCFunction)pg_line_raycast, METH_FASTCALL, NULL}, |
311 | 336 | {"collideline", (PyCFunction)pg_line_collideline, METH_FASTCALL, NULL}, |
312 | 337 | {"collidepoint", (PyCFunction)pg_line_collidepoint, METH_FASTCALL, NULL}, |
313 | 338 | {"collidecircle", (PyCFunction)pg_line_collidecircle, METH_FASTCALL, NULL}, |
|
0 commit comments