def setZ(self, Z): if float(Z) != self._Z_angle: self._angle = ((float(Z) % 360) - (self._Z_angle % 360)) % 360 self._Z_angle = float(Z) #rotation = Quaternion.fromAngleAxis(math.radians( self._angle ), Vector.Unit_Z) rotation = Quaternion() rotation.setByAngleAxis(math.radians(self._angle), Vector.Unit_Z) # Save the current positions of the node, as we want to rotate around their current centres self._saved_node_positions = [] for node in Selection.getAllSelectedObjects(): self._saved_node_positions.append((node, node.getPosition())) node._rotationZ = self._Z_angle # Rate-limit the angle change notification # This is done to prevent the UI from being flooded with property change notifications, # which in turn would trigger constant repaints. new_time = time.monotonic() if not self._angle_update_time or new_time - self._angle_update_time > 0.1: self._angle_update_time = new_time # Rotate around the saved centeres of all selected nodes op = GroupedOperation() for node, position in self._saved_node_positions: op.addOperation( RotateOperation(node, rotation, rotate_around_point=position)) op.push() self._angle = 0 self.propertyChanged.emit()
def test_toMatrix(self): q1 = Quaternion() q1.setByAngleAxis(math.pi / 2, Vector.Unit_Z) m1 = q1.toMatrix() m2 = Matrix() m2.setByRotationAxis(math.pi / 2, Vector.Unit_Z) self.assertTrue(Float.fuzzyCompare(m1.at(0, 0), m2.at(0, 0), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(0, 1), m2.at(0, 1), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(0, 2), m2.at(0, 2), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(0, 3), m2.at(0, 3), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(1, 0), m2.at(1, 0), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(1, 1), m2.at(1, 1), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(1, 2), m2.at(1, 2), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(1, 3), m2.at(1, 3), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(2, 0), m2.at(2, 0), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(2, 1), m2.at(2, 1), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(2, 2), m2.at(2, 2), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(2, 3), m2.at(2, 3), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(3, 0), m2.at(3, 0), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(3, 1), m2.at(3, 1), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(3, 2), m2.at(3, 2), 1e-6)) self.assertTrue(Float.fuzzyCompare(m1.at(3, 3), m2.at(3, 3), 1e-6))
def test_setByAxis(self): q = Quaternion() q.setByAngleAxis(math.pi / 2, Vector.Unit_Z) self.assertEqual(q.x, 0.0) self.assertEqual(q.y, 0.0) self.assertTrue(Float.fuzzyCompare(q.z, math.sqrt(2.0) / 2.0, 1e-6)) self.assertTrue(Float.fuzzyCompare(q.w, math.sqrt(2.0) / 2.0, 1e-6))
def test_rotateVector(self): q1 = Quaternion() q1.setByAngleAxis(math.pi / 2, Vector.Unit_Z) v = Vector(0, 1, 0) v = q1.rotate(v) self.assertTrue(Float.fuzzyCompare(v.x, -1.0, 1e-6)) self.assertTrue(Float.fuzzyCompare(v.y, 0.0, 1e-6)) self.assertTrue(Float.fuzzyCompare(v.z, 0.0, 1e-6))
def test_invert(self): q1 = Quaternion() q1.setByAngleAxis(math.pi, Vector.Unit_Z) q1.invert() q2 = Quaternion() q2.setByAngleAxis(math.pi, -Vector.Unit_Z) self.assertEqual(q1, q2)
def test_fromMatrix(self): m = Matrix() m.setByRotationAxis(math.pi / 2, Vector.Unit_Z) q1 = Quaternion.fromMatrix(m) q2 = Quaternion() q2.setByAngleAxis(math.pi / 2, Vector.Unit_Z) self.assertTrue(Float.fuzzyCompare(q1.x, q2.x, 1e-6)) self.assertTrue(Float.fuzzyCompare(q1.y, q2.y, 1e-6)) self.assertTrue(Float.fuzzyCompare(q1.z, q2.z, 1e-6)) self.assertTrue(Float.fuzzyCompare(q1.w, q2.w, 1e-6))
def test_slerp(self): q1 = Quaternion() q1.setByAngleAxis(0, Vector.Unit_Z) q2 = Quaternion() q2.setByAngleAxis(math.pi / 2, Vector.Unit_Z) c = Quaternion(0.0, 0.0, 0.0, 1.0) self.assertEqual(c, Quaternion.slerp(q1, q2, 0.0)) c = Quaternion(0.0, 0.0, 0.19509033858776093, 0.9807853102684021) self.assertEqual(c, Quaternion.slerp(q1, q2, 0.25)) c = Quaternion(0.0, 0.0, 0.38268348574638367, 0.9238795638084412) self.assertEqual(c, Quaternion.slerp(q1, q2, 0.5)) c = Quaternion(0.0, 0.0, 0.5555703043937683, 0.8314696550369263) self.assertEqual(c, Quaternion.slerp(q1, q2, 0.75)) c = Quaternion(0.0, 0.0, 0.7071068286895752, 0.7071068286895752) self.assertEqual(c, Quaternion.slerp(q1, q2, 1.0))
def test_multiply(self): q1 = Quaternion() q1.setByAngleAxis(math.pi / 2, Vector.Unit_Z) q2 = Quaternion() q2.setByAngleAxis(math.pi / 2, Vector.Unit_Z) q3 = q1 * q2 q4 = Quaternion() q4.setByAngleAxis(math.pi, Vector.Unit_Z) self.assertEqual(q3, q4)