Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions docs/reST/ref/geometry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@
((x, y), radius)
(x, y, radius)

It is important to note that you cannot create degenerate circles, which are circles with
a radius of 0 or less. If you try to create such a circle, the `Circle` object will not be
created and an error will be raised. This is because a circle with a radius of 0 or
less is not a valid geometric object.

The `Circle` class has both virtual and non-virtual attributes. Non-virtual attributes
are attributes that are stored in the `Circle` object itself. Virtual attributes are the
result of calculations that utilize the Circle's non-virtual attributes.
Expand Down Expand Up @@ -91,6 +86,9 @@

.. versionadded:: 2.4.0

.. versionchanged:: 2.5.1 It is allowed to create degenerate circles with radius
equal to ``0``. This also applies to virtual attributes.

.. ## Circle.r ##

.. attribute:: r_sqr
Expand Down
24 changes: 13 additions & 11 deletions src_c/circle.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ pg_circle_init(pgCircleObject *self, PyObject *args, PyObject *kwds)
PyErr_SetString(
PyExc_TypeError,
"Arguments must be a Circle, a sequence of length 3 or 2, or an "
"object with an attribute called 'circle'");
"object with an attribute called 'circle', all with corresponding "
"nonnegative radius argument");
return -1;
}
return 0;
Expand Down Expand Up @@ -494,8 +495,8 @@ pg_circle_setr(pgCircleObject *self, PyObject *value, void *closure)
return -1;
}

if (radius <= 0) {
PyErr_SetString(PyExc_ValueError, "Radius must be positive");
if (radius < 0) {
PyErr_SetString(PyExc_ValueError, "Radius must be nonnegative");
return -1;
}

Expand Down Expand Up @@ -523,9 +524,9 @@ pg_circle_setr_sqr(pgCircleObject *self, PyObject *value, void *closure)
return -1;
}

if (radius_squared <= 0) {
if (radius_squared < 0) {
PyErr_SetString(PyExc_ValueError,
"Invalid radius squared value, must be > 0");
"Invalid radius squared value, must be nonnegative");
return -1;
}

Expand Down Expand Up @@ -570,8 +571,9 @@ pg_circle_setarea(pgCircleObject *self, PyObject *value, void *closure)
return -1;
}

if (area <= 0) {
PyErr_SetString(PyExc_ValueError, "Invalid area value, must be > 0");
if (area < 0) {
PyErr_SetString(PyExc_ValueError,
"Invalid area value, must be nonnegative");
return -1;
}

Expand Down Expand Up @@ -600,9 +602,9 @@ pg_circle_setcircumference(pgCircleObject *self, PyObject *value,
return -1;
}

if (circumference <= 0) {
if (circumference < 0) {
PyErr_SetString(PyExc_ValueError,
"Invalid circumference value, must be > 0");
"Invalid circumference value, must be nonnegative");
return -1;
}

Expand Down Expand Up @@ -630,9 +632,9 @@ pg_circle_setdiameter(pgCircleObject *self, PyObject *value, void *closure)
return -1;
}

if (diameter <= 0) {
if (diameter < 0) {
PyErr_SetString(PyExc_ValueError,
"Invalid diameter value, must be > 0");
"Invalid diameter value, must be nonnegative");
return -1;
}

Expand Down
2 changes: 1 addition & 1 deletion src_c/geometry_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ int
_pg_circle_set_radius(PyObject *value, pgCircleBase *circle)
{
double radius = 0.0;
if (!pg_DoubleFromObj(value, &radius) || radius <= 0.0) {
if (!pg_DoubleFromObj(value, &radius) || radius < 0.0) {
return 0;
}
circle->r = radius;
Expand Down
15 changes: 11 additions & 4 deletions test/geometry_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ def testConstructionTUP_XYR_int(self):
self.assertEqual(2.0, c.y)
self.assertEqual(3.0, c.r)

def testConstruction_zero_radius(self):
c = Circle(1, 2, 0)

self.assertEqual(1.0, c.x)
self.assertEqual(2.0, c.y)
self.assertEqual(0, c.r)

def test_x(self):
"""Ensures changing the x attribute moves the circle and does not change
the circle's radius.
Expand Down Expand Up @@ -183,7 +190,7 @@ def test_r__invalid_value(self):
with self.assertRaises(TypeError):
c.radius = value

for value in (-10.3234, -1, 0, 0.0):
for value in (-10.3234, -1):
with self.assertRaises(ValueError):
c.r = value
with self.assertRaises(ValueError):
Expand Down Expand Up @@ -317,7 +324,7 @@ def test_area_invalid_value(self):
with self.assertRaises(TypeError):
c.area = value

for value in (-10.3234, -1, 0, 0.0):
for value in (-10.3234, -1):
with self.assertRaises(ValueError):
c.area = value

Expand Down Expand Up @@ -352,7 +359,7 @@ def test_circumference_invalid_value(self):
with self.assertRaises(TypeError):
c.circumference = value

for value in (-10.3234, -1, 0, 0.0):
for value in (-10.3234, -1):
with self.assertRaises(ValueError):
c.circumference = value

Expand Down Expand Up @@ -390,7 +397,7 @@ def test_diameter_invalid_value(self):
with self.assertRaises(TypeError):
c.diameter = value

for value in (-10.3234, -1, 0, 0.0):
for value in (-10.3234, -1):
with self.assertRaises(ValueError):
c.diameter = value
with self.assertRaises(ValueError):
Expand Down