def test_bounding_box(self): vol = Volume() bb = vol.bounding_box() self.assertAlmostEqual(bb[0][0], 0 ) self.assertAlmostEqual(bb[0][1], 1 ) self.assertAlmostEqual(bb[1][0], 0 ) self.assertAlmostEqual(bb[1][1], 1 ) self.assertAlmostEqual(bb[2][0], 0 ) self.assertAlmostEqual(bb[2][1], 1 ) vol.refine(2) vol.rotate(pi/4, [1,0,0]) vol += (1,0,1) bb = vol.bounding_box() self.assertAlmostEqual(bb[0][0], 1 ) self.assertAlmostEqual(bb[0][1], 2 ) self.assertAlmostEqual(bb[1][0], -sqrt(2)/2 ) self.assertAlmostEqual(bb[1][1], sqrt(2)/2 ) self.assertAlmostEqual(bb[2][0], 1 ) self.assertAlmostEqual(bb[2][1], 1+sqrt(2) )
def test_bounding_box(self): vol = Volume() bb = vol.bounding_box() self.assertAlmostEqual(bb[0][0], 0) self.assertAlmostEqual(bb[0][1], 1) self.assertAlmostEqual(bb[1][0], 0) self.assertAlmostEqual(bb[1][1], 1) self.assertAlmostEqual(bb[2][0], 0) self.assertAlmostEqual(bb[2][1], 1) vol.refine(2) vol.rotate(pi / 4, [1, 0, 0]) vol += (1, 0, 1) bb = vol.bounding_box() self.assertAlmostEqual(bb[0][0], 1) self.assertAlmostEqual(bb[0][1], 2) self.assertAlmostEqual(bb[1][0], -sqrt(2) / 2) self.assertAlmostEqual(bb[1][1], sqrt(2) / 2) self.assertAlmostEqual(bb[2][0], 1) self.assertAlmostEqual(bb[2][1], 1 + sqrt(2))
def revolve(surf, theta=2 * pi, axis=(0, 0, 1)): """ Revolve a volume by sweeping a surface in a rotational fashion around an axis. :param Surface surf: Surface to revolve :param float theta: Angle to revolve, in radians :param array-like axis: Axis of rotation :return: The revolved surface :rtype: Volume """ surf = surf.clone() # clone input surface, throw away old reference surf.set_dimension(3) # add z-components (if not already present) surf.force_rational() # add weight (if not already present) # align axis with the z-axis normal_theta = atan2(axis[1], axis[0]) normal_phi = atan2(sqrt(axis[0]**2 + axis[1]**2), axis[2]) surf.rotate(-normal_theta, [0, 0, 1]) surf.rotate(-normal_phi, [0, 1, 0]) path = CurveFactory.circle_segment(theta=theta) n = len(surf) # number of control points of the surface m = len(path) # number of control points of the sweep cp = np.zeros((m * n, 4)) dt = np.sign(theta) * (path.knots(0)[1] - path.knots(0)[0]) / 2.0 for i in range(m): weight = path[i, -1] cp[i * n:(i + 1) * n, :] = np.reshape( surf.controlpoints.transpose(1, 0, 2), (n, 4)) cp[i * n:(i + 1) * n, 2] *= weight cp[i * n:(i + 1) * n, 3] *= weight surf.rotate(dt) result = Volume(surf.bases[0], surf.bases[1], path.bases[0], cp, True) # rotate it back again result.rotate(normal_phi, [0, 1, 0]) result.rotate(normal_theta, [0, 0, 1]) return result
def revolve(surf, theta=2 * pi, axis=(0,0,1)): """ Revolve a volume by sweeping a surface in a rotational fashion around an axis. :param Surface surf: Surface to revolve :param float theta: Angle to revolve, in radians :param array-like axis: Axis of rotation :return: The revolved surface :rtype: Volume """ surf = surf.clone() # clone input surface, throw away old reference surf.set_dimension(3) # add z-components (if not already present) surf.force_rational() # add weight (if not already present) # align axis with the z-axis normal_theta = atan2(axis[1], axis[0]) normal_phi = atan2(sqrt(axis[0]**2 + axis[1]**2), axis[2]) surf.rotate(-normal_theta, [0,0,1]) surf.rotate(-normal_phi, [0,1,0]) path = CurveFactory.circle_segment(theta=theta) n = len(surf) # number of control points of the surface m = len(path) # number of control points of the sweep cp = np.zeros((m * n, 4)) dt = np.sign(theta)*(path.knots(0)[1] - path.knots(0)[0]) / 2.0 for i in range(m): weight = path[i,-1] cp[i * n:(i + 1) * n, :] = np.reshape(surf.controlpoints.transpose(1, 0, 2), (n, 4)) cp[i * n:(i + 1) * n, 2] *= weight cp[i * n:(i + 1) * n, 3] *= weight surf.rotate(dt) result = Volume(surf.bases[0], surf.bases[1], path.bases[0], cp, True) # rotate it back again result.rotate(normal_phi, [0,1,0]) result.rotate(normal_theta, [0,0,1]) return result