def test_zero_angle(self): zero_vec = np.zeros(3) * q.m self.assertEqual(geom.angle(zero_vec, zero_vec), 0 * q.deg) vectors = get_base() for vec in vectors: self.assertEqual(geom.angle(zero_vec, vec), 0 * q.deg)
def _find_next_rotation_time(self, abs_time): if not self.trajectory.bound: raise geom.TrajectoryError("Trajectory not bound") orientation = self.orientation.simplified.magnitude t = np.copy(abs_time.simplified.magnitude) * q.s def compute_rotation_axis(current_time): vec = self.trajectory.get_direction(current_time) rot_ax = np.cross(orientation, vec) return rot_ax rot_ax = compute_rotation_axis(t) vec = self.trajectory.get_direction(t).simplified.magnitude angle = geom.angle(orientation, vec) if np.all(np.isclose(rot_ax, 0)) and not (np.all( np.isclose(vec, orientation)) or self.trajectory.stationary): # Orientation does not coincide with trajectory direction and trajectory is not # stationary. dt = self.get_maximum_dt(self.trajectory.pixel_size) t += dt while t < self.trajectory.time and np.all(np.isclose(rot_ax, 0)): # Orientation and trajectory direction are opposite, the angle between them is 180 # deg rot_ax = compute_rotation_axis(t) t += dt if t >= self.trajectory.time: # Orientation and trajectory direction don't deviate at all from abs_time forward, # just use z axis rot_ax = geom.Z_AX return (rot_ax, angle)
def _find_next_rotation_time(self, abs_time): if not self.trajectory.bound: raise geom.TrajectoryError('Trajectory not bound') orientation = self.orientation.simplified.magnitude t = np.copy(abs_time.simplified.magnitude) * q.s def compute_rotation_axis(current_time): vec = self.trajectory.get_direction(current_time) rot_ax = np.cross(orientation, vec) return rot_ax rot_ax = compute_rotation_axis(t) vec = self.trajectory.get_direction(t).simplified.magnitude angle = geom.angle(orientation, vec) if np.all(np.isclose(rot_ax, 0)) and not (np.all(np.isclose(vec, orientation)) or self.trajectory.stationary): # Orientation does not coincide with trajectory direction and trajectory is not # stationary. dt = self.get_maximum_dt(self.trajectory.pixel_size) t += dt while t < self.trajectory.time and np.all(np.isclose(rot_ax, 0)): # Orientation and trajectory direction are opposite, the angle between them is 180 # deg rot_ax = compute_rotation_axis(t) t += dt if t >= self.trajectory.time: # Orientation and trajectory direction don't deviate at all from abs_time forward, # just use z axis rot_ax = geom.Z_AX return (rot_ax, angle)
def test_orthogonal_angles(self): vectors = get_base() pairs = ( np.array([(x, y) for x in vectors for y in vectors if np.array(x - y).any()]) * vectors.units ) for vec_0, vec_1 in pairs: self.assertEqual(geom.angle(vec_0, vec_1), 90 * q.deg)
def test_angle(self): a = np.zeros((3, 2)) * q.m a[1, 0] = 1 * q.m a[0, 1] = 1 * q.m a[1, 1] = 1 * q.m v = (1, 0, 0) * q.m gt = [np.pi / 2, np.pi / 4] # 1D x 1D self.assertAlmostEqual(gt[0], geom.angle(a[:, 0], v)) # 2D x 1D np.testing.assert_almost_equal(gt, geom.angle(a, v).simplified.magnitude) # It must work also the other way around (vector, matrix) np.testing.assert_almost_equal(gt, geom.angle(v, a).simplified.magnitude) # 2D x 2D array vector-wise np.testing.assert_almost_equal([gt[1], gt[1]], geom.angle(a, a[:, ::-1]).simplified.magnitude)
def test_rotate(self): vec_1 = get_vec_0() normalized = geom.normalize(vec_1) directions = get_directions(q.dimensionless) for direction in directions: rot_axis = np.cross(direction, normalized) * q.dimensionless trans_mat = geom.rotate(geom.angle(direction, normalized), rot_axis) diff = np.sum(normalized - geom.normalize(geom.transform_vector(trans_mat, direction))) self.assertAlmostEqual(diff, 0)
def test_rotate(self): vec_1 = get_vec_0() normalized = geom.normalize(vec_1) directions = get_directions(q.dimensionless) for direction in directions: rot_axis = np.cross(direction, normalized) * q.dimensionless trans_mat = geom.rotate(geom.angle(direction, normalized), rot_axis) diff = np.sum(normalized - geom.normalize( geom.transform_vector(trans_mat, direction))) self.assertAlmostEqual(diff, 0)
def move(self, abs_time, clear=True): """Move to a position of the body in time *abs_time*. If *clear* is true clear the transformation matrix first. """ if clear: self.clear_transformation() abs_time = abs_time.simplified p_0 = self.trajectory.get_point(abs_time).simplified vec = self.trajectory.get_direction(abs_time) # First translate to the point at time abs_time self.translate(p_0) # Then rotate about rotation axis given by trajectory direction # and body orientation. rot_ax = geom.normalize(np.cross(self._orientation, vec)) angle = geom.angle(self._orientation, vec) self.rotate(angle, rot_ax)
def test_orthogonal_angles(self): vectors = get_base() pairs = np.array([(x, y) for x in vectors for y in vectors if np.array(x - y).any()]) * vectors.units for vec_0, vec_1 in pairs: self.assertEqual(geom.angle(vec_0, vec_1), 90 * q.deg)