From f032a65f526577b95e00f7e331ed4f5ea1ce274f Mon Sep 17 00:00:00 2001 From: itzpr3d4t0r <103119829+itzpr3d4t0r@users.noreply.github.com> Date: Mon, 27 May 2024 14:42:49 +0200 Subject: [PATCH] made _pg_circle_collideswith PG_FORCEINLINE --- src_c/circle.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/src_c/circle.c b/src_c/circle.c index 87374c5..58c9e68 100644 --- a/src_c/circle.c +++ b/src_c/circle.c @@ -320,7 +320,7 @@ pg_circle_colliderect(pgCircleObject *self, PyObject *const *args, return PyBool_FromLong(pgCollision_RectCircle(&temp, &self->circle)); } -static int +static PG_FORCEINLINE int _pg_circle_collideswith(pgCircleBase *scirc, PyObject *arg) { if (pgCircle_Check(arg)) { @@ -732,6 +732,99 @@ pg_circle_collidelistall(pgCircleObject *self, PyObject *arg) return ret; } +static void +_pg_rotate_circle_helper(pgCircleBase *circle, double angle, double rx, + double ry) +{ + if (angle == 0.0 || fmod(angle, 360.0) == 0.0) { + return; + } + + double x = circle->x - rx; + double y = circle->y - ry; + + const double angle_rad = DEG_TO_RAD(angle); + + double cos_theta = cos(angle_rad); + double sin_theta = sin(angle_rad); + + circle->x = rx + x * cos_theta - y * sin_theta; + circle->y = ry + x * sin_theta + y * cos_theta; +} + +static PyObject * +pg_circle_rotate(pgCircleObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + if (!nargs || nargs > 2) { + return RAISE(PyExc_TypeError, "rotate requires 1 or 2 arguments"); + } + + pgCircleBase *circle = &self->circle; + double angle, rx, ry; + + rx = circle->x; + ry = circle->y; + + if (!pg_DoubleFromObj(args[0], &angle)) { + return RAISE(PyExc_TypeError, + "Invalid angle argument, must be numeric"); + } + + if (nargs != 2) { + return _pg_circle_subtype_new(Py_TYPE(self), circle); + } + + if (!pg_TwoDoublesFromObj(args[1], &rx, &ry)) { + return RAISE(PyExc_TypeError, + "Invalid rotation point argument, must be a sequence of " + "2 numbers"); + } + + PyObject *circle_obj = _pg_circle_subtype_new(Py_TYPE(self), circle); + if (!circle_obj) { + return NULL; + } + + _pg_rotate_circle_helper(&pgCircle_AsCircle(circle_obj), angle, rx, ry); + + return circle_obj; +} + +static PyObject * +pg_circle_rotate_ip(pgCircleObject *self, PyObject *const *args, + Py_ssize_t nargs) +{ + if (!nargs || nargs > 2) { + return RAISE(PyExc_TypeError, "rotate requires 1 or 2 arguments"); + } + + pgCircleBase *circle = &self->circle; + double angle, rx, ry; + + rx = circle->x; + ry = circle->y; + + if (!pg_DoubleFromObj(args[0], &angle)) { + return RAISE(PyExc_TypeError, + "Invalid angle argument, must be numeric"); + } + + if (nargs != 2) { + /* just return None */ + Py_RETURN_NONE; + } + + if (!pg_TwoDoublesFromObj(args[1], &rx, &ry)) { + return RAISE(PyExc_TypeError, + "Invalid rotation point argument, must be a sequence " + "of 2 numbers"); + } + + _pg_rotate_circle_helper(circle, angle, rx, ry); + + Py_RETURN_NONE; +} + static struct PyMethodDef pg_circle_methods[] = { {"collidecircle", (PyCFunction)pg_circle_collidecircle, METH_FASTCALL, NULL},