From e9924ba6e4cb06f784e90c00eae0cc9c859d8190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20S=C3=A1nchez=20de=20Le=C3=B3n=20Peque?= Date: Thu, 12 Dec 2019 19:38:58 +0100 Subject: [PATCH] Fix plane rotation method The vector defining the rotation is expected to be in local coordinates and therefore needs to be converted to world coordinates before applying the rotation. --- cadquery/occ_impl/geom.py | 2 +- tests/test_cadquery.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/cadquery/occ_impl/geom.py b/cadquery/occ_impl/geom.py index 0c31fe22..d959702a 100644 --- a/cadquery/occ_impl/geom.py +++ b/cadquery/occ_impl/geom.py @@ -619,7 +619,7 @@ class Plane(object): :param rotate: Vector [xDegrees, yDegrees, zDegrees] :return: a copy of this plane rotated as requested. """ - rotate = Vector(rotate) + rotate = Vector(self.toWorldCoords(rotate)) # Convert to radians. rotate = rotate.multiply(math.pi / 180.0) diff --git a/tests/test_cadquery.py b/tests/test_cadquery.py index ddd7cc45..64b85237 100644 --- a/tests/test_cadquery.py +++ b/tests/test_cadquery.py @@ -4,6 +4,9 @@ """ # system modules import math,os.path,time,tempfile +from random import choice +from random import random +from random import randrange # my modules from cadquery import * @@ -246,6 +249,32 @@ class TestCadQuery(BaseTest): self.assertEqual(-0.5, endPoint[1]) self.assertEqual(2.5, endPoint[2]) + def testPlaneRotateZNormal(self): + """ + Rotation of a plane in the Z direction should never alter its normal. + + This test creates random planes, with the normal in a random direction + among positive and negative X, Y and Z. The plane is defined with this + normal and another random perpendicular vector (the X-direction of the + plane). The plane is finally rotated a random angle in the Z-direction + to verify that the resulting plane maintains the same normal. + """ + for _ in range(100): + normal_sign = choice((-1, 1)) + normal_dir = randrange(3) + angle = (random() - 0.5) * 720 + + normal = [0, 0, 0] + normal[normal_dir] = normal_sign + xdir = [random(), random(), random()] + xdir[normal_dir] = 0 + + plane = Plane(origin=(0, 0, 0), xDir=xdir, normal=normal) + rotated = plane.rotated((0, 0, angle)).zDir.toTuple() + self.assertAlmostEqual(rotated[0], normal[0]) + self.assertAlmostEqual(rotated[1], normal[1]) + self.assertAlmostEqual(rotated[2], normal[2]) + def testLoft(self): """ Test making a lofted solid