From ef712fc49d824a20c1d799a970964d23026ad709 Mon Sep 17 00:00:00 2001 From: andrefmello91 Date: Wed, 4 Feb 2026 16:41:16 -0400 Subject: [PATCH 1/5] Use point.buffer to create the circular polygon --- structuralcodes/geometry/_circular.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/structuralcodes/geometry/_circular.py b/structuralcodes/geometry/_circular.py index 6f5b4764..63db7bc9 100644 --- a/structuralcodes/geometry/_circular.py +++ b/structuralcodes/geometry/_circular.py @@ -10,21 +10,18 @@ import numpy as np from numpy.typing import ArrayLike -from shapely import Polygon +from shapely import Point from structuralcodes.core.base import Material from ._geometry import SurfaceGeometry -def _create_circle(radius, npoints=20, origin: t.Optional[ArrayLike] = None): +def _create_circle(radius, origin: t.Optional[ArrayLike] = None): """Create a circle with a given radius.""" origin = origin if origin is not None else (0.0, 0.0) - phi = np.linspace(0, 2 * np.pi, npoints + 1) - x = radius * np.cos(phi) + origin[0] - y = radius * np.sin(phi) + origin[1] - points = np.transpose(np.array([x, y])) - return Polygon(points) + pt = Point(origin) + return pt.buffer(radius) class CircularGeometry(SurfaceGeometry): @@ -38,7 +35,6 @@ def __init__( self, diameter: float, material: Material, - n_points: int = 20, concrete: bool = False, origin: t.Optional[ArrayLike] = None, name: t.Optional[str] = None, @@ -49,8 +45,6 @@ def __init__( Arguments: diameter (float): The diameter of the geometry. material (Material): A Material class applied to the geometry. - n_points (int): The number of points used to discretize the - circle as a shapely `Polygon` (default = 20). concrete (bool): Flag to indicate if the geometry is concrete. origin (Optional(ArrayLike)): The center point of the circle. (0.0, 0.0) is used as default. @@ -72,7 +66,7 @@ def __init__( origin = origin if origin is not None else (0.0, 0.0) # Create the shapely polygon polygon = _create_circle( - radius=self._radius, npoints=n_points, origin=origin + radius=self._radius, origin=origin ) # Pass everything to the base class super().__init__( From 056bdd30686560b0c42bd87f2bf4fcc9fa124ee4 Mon Sep 17 00:00:00 2001 From: andrefmello91 Date: Wed, 4 Feb 2026 16:55:00 -0400 Subject: [PATCH 2/5] Updated tests for circular geometry --- tests/test_geometry/test_circular.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/test_geometry/test_circular.py b/tests/test_geometry/test_circular.py index 4e9b546d..122c771a 100644 --- a/tests/test_geometry/test_circular.py +++ b/tests/test_geometry/test_circular.py @@ -13,15 +13,13 @@ # Test create a circular geometry @pytest.mark.parametrize( - 'diameter, n_points', - [(100, 20), (200, 20), (300, 20), (300, 30), (400, 40), (500, 24)], + 'diameter', + [100, 200, 300, 400, 500], ) -def test_create_circular_geometry(diameter, n_points): +def test_create_circular_geometry(diameter): """Test creating a CircularGeometry.""" mat = ElasticMaterial(E=300000, density=2450) - circle = CircularGeometry(diameter, mat, n_points) - - assert len(circle.polygon.exterior.coords) == n_points + 2 + circle = CircularGeometry(diameter, mat) assert math.isclose(circle.diameter, diameter) assert math.isclose(circle.radius, diameter / 2.0) From f5515b3d2c4e95910eaa181651036e5280a906a0 Mon Sep 17 00:00:00 2001 From: andrefmello91 Date: Wed, 4 Feb 2026 17:02:01 -0400 Subject: [PATCH 3/5] Removed unneeded numpy import --- structuralcodes/geometry/_circular.py | 1 - 1 file changed, 1 deletion(-) diff --git a/structuralcodes/geometry/_circular.py b/structuralcodes/geometry/_circular.py index 63db7bc9..12a61bb4 100644 --- a/structuralcodes/geometry/_circular.py +++ b/structuralcodes/geometry/_circular.py @@ -8,7 +8,6 @@ import typing as t -import numpy as np from numpy.typing import ArrayLike from shapely import Point From 0185b49c94a508c5e10663de6ef217f1494d7c5b Mon Sep 17 00:00:00 2001 From: andrefmello91 Date: Tue, 17 Feb 2026 12:30:17 -0400 Subject: [PATCH 4/5] Use npoints to set the number of segments for creating a circular geometry --- structuralcodes/geometry/_circular.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/structuralcodes/geometry/_circular.py b/structuralcodes/geometry/_circular.py index 12a61bb4..8d4c644c 100644 --- a/structuralcodes/geometry/_circular.py +++ b/structuralcodes/geometry/_circular.py @@ -16,11 +16,12 @@ from ._geometry import SurfaceGeometry -def _create_circle(radius, origin: t.Optional[ArrayLike] = None): +def _create_circle(radius, npoints:int = 20, origin: t.Optional[ArrayLike] = None): """Create a circle with a given radius.""" origin = origin if origin is not None else (0.0, 0.0) pt = Point(origin) - return pt.buffer(radius) + quad_segs = 4 * round(npoints / 4) # Round to the nearest multiple of 4 + return pt.buffer(radius, quad_segs=quad_segs) class CircularGeometry(SurfaceGeometry): @@ -34,6 +35,7 @@ def __init__( self, diameter: float, material: Material, + n_points: int = 20, concrete: bool = False, origin: t.Optional[ArrayLike] = None, name: t.Optional[str] = None, @@ -44,6 +46,8 @@ def __init__( Arguments: diameter (float): The diameter of the geometry. material (Material): A Material class applied to the geometry. + n_points (int): The number of points used to discretize the + circle as a shapely `Polygon` (default = 20). concrete (bool): Flag to indicate if the geometry is concrete. origin (Optional(ArrayLike)): The center point of the circle. (0.0, 0.0) is used as default. @@ -65,7 +69,7 @@ def __init__( origin = origin if origin is not None else (0.0, 0.0) # Create the shapely polygon polygon = _create_circle( - radius=self._radius, origin=origin + radius=self._radius, npoints=n_points, origin=origin ) # Pass everything to the base class super().__init__( From 2f4aa36ec6237a8b931adf3d70429a6907635d91 Mon Sep 17 00:00:00 2001 From: Morten Engen Date: Wed, 18 Feb 2026 07:40:48 +0100 Subject: [PATCH 5/5] Format code and describe multiple of 4 in docstring --- structuralcodes/geometry/_circular.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/structuralcodes/geometry/_circular.py b/structuralcodes/geometry/_circular.py index 8d4c644c..b6228421 100644 --- a/structuralcodes/geometry/_circular.py +++ b/structuralcodes/geometry/_circular.py @@ -16,11 +16,13 @@ from ._geometry import SurfaceGeometry -def _create_circle(radius, npoints:int = 20, origin: t.Optional[ArrayLike] = None): +def _create_circle( + radius, npoints: int = 20, origin: t.Optional[ArrayLike] = None +): """Create a circle with a given radius.""" origin = origin if origin is not None else (0.0, 0.0) pt = Point(origin) - quad_segs = 4 * round(npoints / 4) # Round to the nearest multiple of 4 + quad_segs = 4 * round(npoints / 4) # Round to the nearest multiple of 4 return pt.buffer(radius, quad_segs=quad_segs) @@ -47,7 +49,8 @@ def __init__( diameter (float): The diameter of the geometry. material (Material): A Material class applied to the geometry. n_points (int): The number of points used to discretize the - circle as a shapely `Polygon` (default = 20). + circle as a shapely `Polygon` (default = 20). Note that the + number of points is rounded to the nearest multiple of 4. concrete (bool): Flag to indicate if the geometry is concrete. origin (Optional(ArrayLike)): The center point of the circle. (0.0, 0.0) is used as default.