def test_get_rotation_displacement(self): # 180 degrees around z moves both x and y components by the *length* * 2 # Use a tiny value so the cross product is not zero d_0 = (-1, 1e-9, 0) * q.dimensionless d_1 = (1, 0, 0) * q.dimensionless length = 5 * q.m gt = np.array((length * 2, length * 2, 0)) * q.m displ = geom.get_rotation_displacement(d_0, d_1, length) np.testing.assert_almost_equal(gt, displ) # 90 degrees around z moves both x and y components by the *length* * sqrt(2) # and not *length*! d_0 = (1, 0, 0) * q.dimensionless d_1 = (0, 1, 0) * q.dimensionless length = 5 * q.m gt = np.array((length * np.sqrt(2), length * np.sqrt(2), 0)) * q.m displ = geom.get_rotation_displacement(d_0, d_1, length) np.testing.assert_almost_equal(gt, displ)
def get_distance(self, t_0, t_1): """Return the translational and rotational travelled distance in time interval *t_0*, *t_1*. """ if not self.trajectory.bound: raise ValueError("Trajectory not bound") # Place the point for computing the derivative very close dt = (t_1 - t_0) * 1e-7 def move_and_save(abs_time): """Move primitive bodies to time *abs_time* and return their positions. """ primitive = self.primitive_bodies self.clear_transformation() self.move(abs_time) positions = np.zeros((len(primitive), 3)) for i in range(len(primitive)): positions[i] = primitive[i].position.simplified.magnitude return positions self.save_transformation_matrices() p_0 = move_and_save(t_0) p_1 = move_and_save(t_1) if t_0 + dt < self.time: d_0 = move_and_save(t_0 + dt) - p_0 else: d_0 = p_0 - move_and_save(t_0 - dt) if t_1 + dt < self.time: d_1 = move_and_save(t_1 + dt) - p_1 else: d_1 = p_1 - move_and_save(t_1 - dt) self.restore_transformation_matrices() trans = np.abs(p_1 - p_0) * q.m rot = [] for i in range(len(self.primitive_bodies)): rot.append( geom.get_rotation_displacement( d_0[i], d_1[i], self.primitive_bodies[i].furthest_point. simplified.magnitude)) rot = np.array(rot) * q.m return np.max(trans) + np.max(rot)
def get_distance(self, t_0, t_1): """Return the translational and rotational travelled distance in time interval *t_0*, *t_1*. """ if not self.trajectory.bound: raise ValueError('Trajectory not bound') # Place the point for computing the derivative very close dt = (t_1 - t_0) * 1e-7 def move_and_save(abs_time): """Move primitive bodies to time *abs_time* and return their positions. """ primitive = self.primitive_bodies self.clear_transformation() self.move(abs_time) positions = np.zeros((len(primitive), 3)) for i in range(len(primitive)): positions[i] = primitive[i].position.simplified.magnitude return positions self.save_transformation_matrices() p_0 = move_and_save(t_0) p_1 = move_and_save(t_1) if t_0 + dt < self.time: d_0 = move_and_save(t_0 + dt) - p_0 else: d_0 = p_0 - move_and_save(t_0 - dt) if t_1 + dt < self.time: d_1 = move_and_save(t_1 + dt) - p_1 else: d_1 = p_1 - move_and_save(t_1 - dt) self.restore_transformation_matrices() trans = np.abs(p_1 - p_0) * q.m rot = [] for i in range(len(self.primitive_bodies)): rot.append(geom.get_rotation_displacement(d_0[i], d_1[i], self.primitive_bodies[i]. furthest_point.simplified.magnitude)) rot = np.array(rot) * q.m return np.max(trans) + np.max(rot)
def test_get_distances(self): """Compare analytically computed distances with the ones obtained from trajectory.""" points = make_circle(n=128) x, y, z = zip(*points) furthest = 3 * q.mm ps = 10 * q.um tr = Trajectory(points, ps, furthest, velocity=1 * q.mm / q.s) d_points = np.abs(tr.points[:, 0][:, np.newaxis] - tr.points) t = np.linspace(0, 2 * np.pi, tr.points.shape[1]) x, y, z = zip(*make_circle(n=tr.points.shape[1])) dx = -np.sin(t) dy = np.cos(t) dz = z derivatives = np.array(zip(dx, dy, dz)).T.copy() d_derivatives = get_rotation_displacement(derivatives[:, 0], derivatives, furthest) distances = (d_points + d_derivatives).simplified.magnitude np.testing.assert_almost_equal(distances, tr.get_distances())
def moved(self, t_0, t_1, pixel_size, bind=True): """ Return True if the body moves more than *pixel_size* in time interval *t_0*, *t_1*. If *bind* is True bind the trajectory to the specified *pixel_size*, otherwise use the trajectory as-is to compute an estimate. """ if bind or not self.trajectory.bound: self.bind_trajectory(pixel_size) p_0 = self.trajectory.get_point(t_0) p_1 = self.trajectory.get_point(t_1) trans_displacement = np.abs(p_1 - p_0) d_0 = self.trajectory.get_direction(t_0, norm=False) d_1 = self.trajectory.get_direction(t_1, norm=False) rot_displacement = geom.get_rotation_displacement(d_0, d_1, self.furthest_point) total_displacement = trans_displacement + rot_displacement return max(total_displacement) > pixel_size
def moved(self, t_0, t_1, pixel_size, bind=True): """ Return True if the body moves more than *pixel_size* in time interval *t_0*, *t_1*. If *bind* is True bind the trajectory to the specified *pixel_size*, otherwise use the trajectory as-is to compute an estimate. """ if bind or not self.trajectory.bound: self.bind_trajectory(pixel_size) p_0 = self.trajectory.get_point(t_0) p_1 = self.trajectory.get_point(t_1) trans_displacement = np.abs(p_1 - p_0) d_0 = self.trajectory.get_direction(t_0, norm=False) d_1 = self.trajectory.get_direction(t_1, norm=False) rot_displacement = geom.get_rotation_displacement( d_0, d_1, self.furthest_point) total_displacement = trans_displacement + rot_displacement return max(total_displacement) > pixel_size
def test_get_distances(self): """Compare analytically computed distances with the ones obtained from trajectory.""" points = make_circle(n=128) x, y, z = list(zip(*points)) furthest = 3 * q.mm ps = 10 * q.um tr = Trajectory(points, ps, furthest, velocity=1 * q.mm / q.s) d_points = np.abs(tr.points[:, 0][:, np.newaxis] - tr.points) t = np.linspace(0, 2 * np.pi, tr.points.shape[1]) x, y, z = list(zip(*make_circle(n=tr.points.shape[1]))) dx = -np.sin(t) dy = np.cos(t) dz = z derivatives = np.array(list(zip(dx, dy, dz))).T.copy() d_derivatives = get_rotation_displacement(derivatives[:, 0], derivatives, furthest) distances = (d_points + d_derivatives).simplified.magnitude np.testing.assert_almost_equal(distances, tr.get_distances())