diff --git a/cadquery/cq.py b/cadquery/cq.py index 488217fa..f448943f 100644 --- a/cadquery/cq.py +++ b/cadquery/cq.py @@ -1344,6 +1344,7 @@ class Workplane(object): angle: float, count: int, fill: bool = True, + rotate=True, ) -> "Workplane": """ Creates an polar array of points and pushes them onto the stack. @@ -1356,15 +1357,23 @@ class Workplane(object): value will fill in the counter-clockwise direction. If fill is false, angle is the angle between elements. :param count: Number of elements in array. ( > 0 ) + :param fill: Interpret the angle as total if True (default: True). + :param rotate: Rorate every item (default: True). """ if count <= 0: raise ValueError("No elements in array") # First element at start angle, convert to cartesian coords - x = radius * math.cos(math.radians(startAngle)) - y = radius * math.sin(math.radians(startAngle)) - points = [Location(Vector(x, y), Vector(0, 0, 1), startAngle)] + x = radius * math.sin(math.radians(startAngle)) + y = radius * math.cos(math.radians(startAngle)) + + if rotate: + loc = Location(Vector(x, y), Vector(0, 0, 1), -startAngle) + else: + loc = Location(Vector(x, y)) + + locs = [loc] # Calculate angle between elements if fill: @@ -1376,14 +1385,19 @@ class Workplane(object): # Add additional elements for i in range(1, count): - phi = math.radians(startAngle + (angle * i)) - x = radius * math.cos(phi) - y = radius * math.sin(phi) - points.append( - Location(Vector(x, y), Vector(0, 0, 1), startAngle + (angle * i)) - ) + phi_deg = startAngle + (angle * i) + phi = math.radians(phi_deg) + x = radius * math.sin(phi) + y = radius * math.cos(phi) - return self.pushPoints(points) + if rotate: + loc = Location(Vector(x, y), Vector(0, 0, 1), -phi_deg) + else: + loc = Location(Vector(x, y)) + + locs.append(loc) + + return self.pushPoints(locs) def pushPoints(self, pntList: Iterable[Union[VectorLike, Location]]) -> "Workplane": """ diff --git a/tests/test_cadquery.py b/tests/test_cadquery.py index 23100716..3bcbb76b 100644 --- a/tests/test_cadquery.py +++ b/tests/test_cadquery.py @@ -969,25 +969,28 @@ class TestCadQuery(BaseTest): s = Workplane("XY").polarArray(radius, 0, 180, 6) self.assertEqual(6, s.size()) + to_x = lambda l: l.wrapped.Transformation().TranslationPart().X() + to_y = lambda l: l.wrapped.Transformation().TranslationPart().Y() + # Test for proper placement when fill == True s = Workplane("XY").polarArray(radius, 0, 180, 3) - self.assertAlmostEqual(0, s.objects[1].x) - self.assertAlmostEqual(radius, s.objects[1].y) + self.assertAlmostEqual(0, to_y(s.objects[1])) + self.assertAlmostEqual(radius, to_x(s.objects[1])) # Test for proper placement when angle to fill is multiple of 360 deg s = Workplane("XY").polarArray(radius, 0, 360, 4) - self.assertAlmostEqual(0, s.objects[1].x) - self.assertAlmostEqual(radius, s.objects[1].y) + self.assertAlmostEqual(0, to_y(s.objects[1])) + self.assertAlmostEqual(radius, to_x(s.objects[1])) # Test for proper placement when fill == False s = Workplane("XY").polarArray(radius, 0, 90, 3, fill=False) - self.assertAlmostEqual(0, s.objects[1].x) - self.assertAlmostEqual(radius, s.objects[1].y) + self.assertAlmostEqual(0, to_y(s.objects[1])) + self.assertAlmostEqual(radius, to_x(s.objects[1])) # Test for proper operation of startAngle s = Workplane("XY").polarArray(radius, 90, 180, 3) - self.assertAlmostEqual(0, s.objects[0].x) - self.assertAlmostEqual(radius, s.objects[0].y) + self.assertAlmostEqual(radius, to_x(s.objects[0])) + self.assertAlmostEqual(0, to_y(s.objects[0])) def testNestedCircle(self): s = (