def test_to_parent_to_local(self): origin = (np.random.random(3) - 0.5) * 100 other_coordinate_system = Cartesian(origin=origin) axis = (np.random.random(3) - 0.5) * 100 angle = (np.random.random() - 0.5) * 100 other_coordinate_system.rotate_axis_angle(axis, angle) point_global = (np.random.random(3) - 0.5) * 100 point_local = other_coordinate_system.to_local(point_global) point_global2 = other_coordinate_system.to_parent(point_local) np.testing.assert_allclose(point_global2, point_global, atol=np.finfo(float).eps) point_local = (np.random.random(3) - 0.5) * 100 point_global = other_coordinate_system.to_parent(point_local) point_local_2 = other_coordinate_system.to_local(point_global) np.testing.assert_allclose(point_local_2, point_local, atol=np.finfo(float).eps)
def arc_between_two_points(coordinate_system, point1, point2, radius=1, right=True): global_point1 = coordinate_system.to_parent(point1) global_point2 = coordinate_system.to_parent(point2) direction = point2 - point1 distance = np.sqrt(np.dot(direction, direction)) arc_coordinate_system = Cartesian(basis=np.copy(coordinate_system.basis), origin=np.copy(global_point1), name='Arc coordinate_system') r_theta_phi = transforms.cartesian_to_spherical(direction) arc_coordinate_system.rotate_axis_angle([0, 0, 1], r_theta_phi[2]) arc_coordinate_system.rotate_axis_angle([0, 1, 0], r_theta_phi[1] + np.pi/2) x_offset = -distance / 2 y_offset = np.sqrt(radius**2 - x_offset**2) if right: y_offset *= -1 arc_coordinate_system.origin = arc_coordinate_system.to_parent([x_offset, y_offset, 0]) local_point1 = arc_coordinate_system.to_local(global_point1) local_point2 = arc_coordinate_system.to_local(global_point2) start = transforms.cartesian_to_spherical(local_point1)[2] stop = transforms.cartesian_to_spherical(local_point2)[2] if not right: start = 2 * np.pi - start stop = 2 * np.pi - stop path = Arc(coordinate_system=arc_coordinate_system, a=radius, b=radius, start=start, stop=stop, right=right) return path
class Space(object): def __init__(self, name, coordinate_system=None): if coordinate_system is None: self.coordinate_system = Cartesian() elif isinstance(coordinate_system, Cartesian): self.coordinate_system = coordinate_system else: raise ValueError('coordinates system must be instance of Cartesian class') self.name = str(name) self.parent = None self.elements = {} self.points = None def __str__(self): description = 'Space: %s\n' % self.name description += str(self.coordinate_system) return description def to_global_coordinate_system(self, xyz): """ convert local points coordinates xyz to global coordinate system coordinates :param xyz: array of points shaped Nx3 :return: array of points in global coordinates system """ parent_xyz = self.coordinate_system.to_parent(xyz) if self.parent is None: return parent_xyz else: return self.parent.to_global_coordinate_system(parent_xyz) def basis_in_global_coordinate_system(self): """ returns local coordinate system basis in global coordinate system as Cartesian class object :return: local Cartesian coordinate system in global coordinate system """ origin = np.copy(self.coordinate_system.origin) basis = np.copy(self.coordinate_system.basis) if self.parent is not None: basis = self.parent.to_global_coordinate_system(basis + origin) origin = self.parent.to_global_coordinate_system(origin) basis = basis - origin name = self.coordinate_system.name labels = self.coordinate_system.labels coordinate_system = Cartesian(basis=basis, origin=origin, name=name, labels=labels) return coordinate_system def to_local_coordinate_system(self, xyz): """ convert global points coordinates xyz to local coordinate system coordinates :param xyz: array of points shaped Nx3 :return: array of points in local coordinates system """ basis_global = self.basis_in_global_coordinate_system() return basis_global.to_local(xyz) def add_element(self, element): if isinstance(element, Space): if element == self: raise ValueError('Space can not be its own subspace') else: if element.parent is None: element_name = element.name name_counter = 1 name_format = ' %d' while element_name in self.elements.keys(): element_name = element.name + name_format % name_counter name_counter += 1 element.name = element_name self.elements[element.name] = element element.parent = self elif element.parent == self: print('Space ' + element.name + 'is already a subspace of ' + self.name) else: raise ValueError(element.name + ' is subspace of another space: ' + element.parent.name + '. Please delete first.') else: raise ValueError('Only another space could be included as a subspace') def remove_element(self, element): if isinstance(element, Space): if element.parent == self: for key in self.elements.keys(): if self.elements[key] == element: del self.elements[key] element.parent = None else: print(element.name + ' is not a subspace of ' + self.name) else: raise ValueError('Only another space could be detached') def detach_from_parent(self): if self.parent is not None: self.parent.remove_element(self) def print_tree(self, level=0): print('-' * level + ' ' * (level > 0) + self.name) for key in self.elements.keys(): self.elements[key].print_tree(level=level+1)
right_helix = Helix(name='Right Helix', coordinate_system=coordinate_system, radius=2, pitch=0.5, start=0, stop=np.pi * 4, right=True) left_helix = Helix(name='Left Helix', coordinate_system=coordinate_system, radius=2, pitch=0.5, start=0, stop=np.pi * 2, right=False) print('Helix length:', left_helix.length()) right_helix_view = Visual.CurveView(fig=fig, curve=right_helix) right_helix_view.draw() left_helix_view = Visual.CurveView(fig=fig, curve=left_helix) left_helix_view.draw() point1 = np.array([1, 1, 0]) point2 = np.array([2, 2, 0]) points = np.vstack((coordinate_system.to_parent(point1), coordinate_system.to_parent(point2))) mlab.points3d(points[:, 0], points[:, 1], points[:, 2], scale_factor=0.1) shortest_path = line_between_two_points(coordinate_system, point1, point2) shortest_path_view = Visual.CurveView(fig=fig, curve=shortest_path) shortest_path_view.set_color((0.3, 0.75, 0.2), 0.5) shortest_path_view.draw() helix_path = helix_between_two_points(coordinate_system, point1, point2, radius=1, loops=7, right=True) helix_path_view = Visual.CurveView(fig=fig, curve=helix_path) helix_path_view.set_color((1, 1, 0), 0.3) helix_path_view.draw() helix_path_view.set_cs_visible(False) arc_path = arc_between_two_points(coordinate_system, point1, point2, radius=1, right=False) arc_path_view = Visual.CurveView(fig=fig, curve=arc_path)