Skip to content

Commit b03251e

Browse files
authored
Merge pull request #3127 from MrRedstone058/geometry_circle_attributes
Added additional circle attributes
2 parents 0fe6832 + 66e32e0 commit b03251e

File tree

5 files changed

+384
-0
lines changed

5 files changed

+384
-0
lines changed

buildconfig/stubs/pygame/geometry.pyi

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,22 @@ class Circle:
6565
def center(self) -> Tuple[float, float]: ...
6666
@center.setter
6767
def center(self, value: Coordinate) -> None: ...
68+
@property
69+
def top(self) -> Tuple[float, float]: ...
70+
@top.setter
71+
def top(self, value: Coordinate) -> None: ...
72+
@property
73+
def left(self) -> Tuple[float, float]: ...
74+
@left.setter
75+
def left(self, value: Coordinate) -> None: ...
76+
@property
77+
def bottom(self) -> Tuple[float, float]: ...
78+
@bottom.setter
79+
def bottom(self, value: Coordinate) -> None: ...
80+
@property
81+
def right(self) -> Tuple[float, float]: ...
82+
@right.setter
83+
def right(self, value: Coordinate) -> None: ...
6884
@overload
6985
def __init__(self, x: float, y: float, r: float) -> None: ...
7086
@overload

docs/reST/ref/geometry.rst

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,58 @@
142142

143143
.. ## Circle.circumference ##
144144
145+
.. attribute:: top
146+
147+
| :sl:`top coordinate of the circle`
148+
| :sg:`top -> (float, float)`
149+
150+
It's a tuple containing the `x` and `y` coordinates that represent the top
151+
of the circle.
152+
Reassigning it moves the circle to the new position. The radius will not be affected.
153+
154+
.. versionadded:: 2.5.2
155+
156+
.. ## Circle.top ##
157+
158+
.. attribute:: bottom
159+
160+
| :sl:`bottom coordinate of the circle`
161+
| :sg:`bottom -> (float, float)`
162+
163+
It's a tuple containing the `x` and `y` coordinates that represent the bottom
164+
of the circle.
165+
Reassigning it moves the circle to the new position. The radius will not be affected.
166+
167+
.. versionadded:: 2.5.2
168+
169+
.. ## Circle.bottom ##
170+
171+
.. attribute:: left
172+
173+
| :sl:`left coordinate of the circle`
174+
| :sg:`left -> (float, float)`
175+
176+
It's a tuple containing the `x` and `y` coordinates that represent the left
177+
of the circle.
178+
Reassigning it moves the circle to the new position. The radius will not be affected.
179+
180+
.. versionadded:: 2.5.2
181+
182+
.. ## Circle.left ##
183+
184+
.. attribute:: right
185+
186+
| :sl:`right coordinate of the circle`
187+
| :sg:`right -> (float, float)`
188+
189+
It's a tuple containing the `x` and `y` coordinates that represent the right
190+
of the circle.
191+
Reassigning it moves the circle to the new position. The radius will not be affected.
192+
193+
.. versionadded:: 2.5.2
194+
195+
.. ## Circle.right ##
196+
145197
**Circle Methods**
146198

147199
----

src_c/circle.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,106 @@ pg_circle_setdiameter(pgCircleObject *self, PyObject *value, void *closure)
817817
return 0;
818818
}
819819

820+
static PyObject *
821+
pg_circle_gettop(pgCircleObject *self, void *closure)
822+
{
823+
return pg_tuple_couple_from_values_double(self->circle.x,
824+
self->circle.y - self->circle.r);
825+
}
826+
827+
static int
828+
pg_circle_settop(pgCircleObject *self, PyObject *value, void *closure)
829+
{
830+
double x, y;
831+
832+
DEL_ATTR_NOT_SUPPORTED_CHECK_NO_NAME(value);
833+
834+
if (!pg_TwoDoublesFromObj(value, &x, &y)) {
835+
PyErr_SetString(PyExc_TypeError, "Expected a sequence of 2 numbers");
836+
return -1;
837+
}
838+
839+
self->circle.y = y + self->circle.r;
840+
self->circle.x = x;
841+
842+
return 0;
843+
}
844+
845+
static PyObject *
846+
pg_circle_getleft(pgCircleObject *self, void *closure)
847+
{
848+
return pg_tuple_couple_from_values_double(self->circle.x - self->circle.r,
849+
self->circle.y);
850+
}
851+
852+
static int
853+
pg_circle_setleft(pgCircleObject *self, PyObject *value, void *closure)
854+
{
855+
double x, y;
856+
857+
DEL_ATTR_NOT_SUPPORTED_CHECK_NO_NAME(value);
858+
859+
if (!pg_TwoDoublesFromObj(value, &x, &y)) {
860+
PyErr_SetString(PyExc_TypeError, "Expected a sequence of 2 numbers");
861+
return -1;
862+
}
863+
864+
self->circle.x = x + self->circle.r;
865+
self->circle.y = y;
866+
867+
return 0;
868+
}
869+
870+
static PyObject *
871+
pg_circle_getbottom(pgCircleObject *self, void *closure)
872+
{
873+
return pg_tuple_couple_from_values_double(self->circle.x,
874+
self->circle.y + self->circle.r);
875+
}
876+
877+
static int
878+
pg_circle_setbottom(pgCircleObject *self, PyObject *value, void *closure)
879+
{
880+
double x, y;
881+
882+
DEL_ATTR_NOT_SUPPORTED_CHECK_NO_NAME(value);
883+
884+
if (!pg_TwoDoublesFromObj(value, &x, &y)) {
885+
PyErr_SetString(PyExc_TypeError, "Expected a sequence of 2 numbers");
886+
return -1;
887+
}
888+
889+
self->circle.y = y - self->circle.r;
890+
self->circle.x = x;
891+
892+
return 0;
893+
}
894+
895+
static PyObject *
896+
pg_circle_getright(pgCircleObject *self, void *closure)
897+
{
898+
return pg_tuple_couple_from_values_double(self->circle.x + self->circle.r,
899+
self->circle.y);
900+
}
901+
902+
static int
903+
pg_circle_setright(pgCircleObject *self, PyObject *value, void *closure)
904+
{
905+
double x, y;
906+
907+
DEL_ATTR_NOT_SUPPORTED_CHECK_NO_NAME(value);
908+
909+
if (!pg_TwoDoublesFromObj(value, &x, &y)) {
910+
PyErr_SetString(PyExc_TypeError, "Expected a sequence of 2 numbers");
911+
return -1;
912+
}
913+
914+
self->circle.x = x - self->circle.r;
915+
self->circle.y = y;
916+
917+
return 0;
918+
}
919+
820920
static PyObject *
821921
pg_circle_richcompare(PyObject *self, PyObject *other, int op)
822922
{
@@ -859,6 +959,14 @@ static PyGetSetDef pg_circle_getsets[] = {
859959
DOC_CIRCLE_AREA, NULL},
860960
{"circumference", (getter)pg_circle_getcircumference,
861961
(setter)pg_circle_setcircumference, DOC_CIRCLE_CIRCUMFERENCE, NULL},
962+
{"top", (getter)pg_circle_gettop, (setter)pg_circle_settop, DOC_CIRCLE_TOP,
963+
NULL},
964+
{"left", (getter)pg_circle_getleft, (setter)pg_circle_setleft,
965+
DOC_CIRCLE_LEFT, NULL},
966+
{"bottom", (getter)pg_circle_getbottom, (setter)pg_circle_setbottom,
967+
DOC_CIRCLE_BOTTOM, NULL},
968+
{"right", (getter)pg_circle_getright, (setter)pg_circle_setright,
969+
DOC_CIRCLE_RIGHT, NULL},
862970
{NULL, 0, NULL, NULL, NULL}};
863971

864972
static PyTypeObject pgCircle_Type = {

src_c/doc/geometry_doc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#define DOC_CIRCLE_DIAMETER "diameter -> float\ndiameter of the circle"
1010
#define DOC_CIRCLE_AREA "area -> float\narea of the circle"
1111
#define DOC_CIRCLE_CIRCUMFERENCE "circumference -> float\ncircumference of the circle"
12+
#define DOC_CIRCLE_TOP "top -> (float, float)\ntop coordinate of the circle"
13+
#define DOC_CIRCLE_BOTTOM "bottom -> (float, float)\nbottom coordinate of the circle"
14+
#define DOC_CIRCLE_LEFT "left -> (float, float)\nleft coordinate of the circle"
15+
#define DOC_CIRCLE_RIGHT "right -> (float, float)\nright coordinate of the circle"
1216
#define DOC_CIRCLE_COLLIDEPOINT "collidepoint((x, y), /) -> bool\ncollidepoint(x, y, /) -> bool\ncollidepoint(vector2, /) -> bool\ntests if a point is inside the circle"
1317
#define DOC_CIRCLE_COLLIDECIRCLE "collidecircle(circle, /) -> bool\ncollidecircle(x, y, radius, /) -> bool\ncollidecircle((x, y), radius, /) -> bool\ncollidecircle(vector2, radius, /) -> bool\ntests if a circle collides with this circle"
1418
#define DOC_CIRCLE_COLLIDERECT "colliderect(rect, /) -> bool\ncolliderect((x, y, width, height), /) -> bool\ncolliderect(x, y, width, height, /) -> bool\ncolliderect((x, y), (width, height), /) -> bool\ncolliderect(vector2, (width, height), /) -> bool\ntests if a rectangle collides with this circle"

0 commit comments

Comments
 (0)