From 4a47bb0bebd3ac17ae6ff97e579d9456b6e4bf3b Mon Sep 17 00:00:00 2001 From: Bernhard Date: Sun, 21 May 2023 17:16:24 +0200 Subject: [PATCH] introduce short_sagitta parameter to RadiusArc to select between both possible cases --- src/build123d/objects_curve.py | 8 +++++++- tests/test_build_line.py | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/build123d/objects_curve.py b/src/build123d/objects_curve.py index 09f8373..8776758 100644 --- a/src/build123d/objects_curve.py +++ b/src/build123d/objects_curve.py @@ -630,6 +630,8 @@ class RadiusArc(BaseLineObject): start_point (VectorLike): start end_point (VectorLike): end radius (float): radius + short_sagitta (bool): If True selects the short sagitta, else the + long sagitta crossing the center. Defaults to True. mode (Mode, optional): combination mode. Defaults to Mode.ADD. Raises: @@ -643,6 +645,7 @@ class RadiusArc(BaseLineObject): start_point: VectorLike, end_point: VectorLike, radius: float, + short_sagitta: bool = True, mode: Mode = Mode.ADD, ): context: BuildLine = BuildLine._get_context(self) @@ -652,7 +655,10 @@ class RadiusArc(BaseLineObject): # Calculate the sagitta from the radius length = end.sub(start).length / 2.0 try: - sagitta = abs(radius) - sqrt(radius**2 - length**2) + if short_sagitta: + sagitta = abs(radius) - sqrt(radius**2 - length**2) + else: + sagitta = -abs(radius) - sqrt(radius**2 - length**2) except ValueError as exception: raise ValueError( "Arc radius is not large enough to reach the end point." diff --git a/tests/test_build_line.py b/tests/test_build_line.py index 1a9b198..1b9535c 100644 --- a/tests/test_build_line.py +++ b/tests/test_build_line.py @@ -166,6 +166,33 @@ class BuildLineTests(unittest.TestCase): Spline((0, 0), (1, 1), (2, 0)) self.assertTupleAlmostEquals((test.edges()[0] @ 1).to_tuple(), (2, 0, 0), 5) + def test_radius_arc(self): + """Test center arc as arc and circle""" + with BuildSketch() as s: + c = Circle(10) + + e = c.edges()[0] + r = e.radius + p1, p2 = e @ 0.3, e @ 0.9 + + with BuildLine() as l: + arc1 = RadiusArc(p1, p2, r) + self.assertAlmostEqual(arc1.length, 2 * r * pi * 0.4, 6) + self.assertAlmostEqual(arc1.bounding_box().max.X, c.bounding_box().max.X) + + arc2 = RadiusArc(p1, p2, r, short_sagitta=False) + self.assertAlmostEqual(arc2.length, 2 * r * pi * 0.6, 6) + self.assertAlmostEqual(arc2.bounding_box().min.X, c.bounding_box().min.X) + + arc3 = RadiusArc(p1, p2, -r) + self.assertAlmostEqual(arc3.length, 2 * r * pi * 0.4, 6) + self.assertGreater(arc3.bounding_box().min.X, c.bounding_box().min.X) + self.assertLess(arc3.bounding_box().min.X, c.bounding_box().max.X) + + arc4 = RadiusArc(p1, p2, -r, short_sagitta=False) + self.assertAlmostEqual(arc4.length, 2 * r * pi * 0.6, 6) + self.assertGreater(arc4.bounding_box().max.X, c.bounding_box().max.X) + def test_center_arc(self): """Test center arc as arc and circle""" with BuildLine() as arc: