def move(self, camera, move): rwi = self.interactor view_dir = camera.focal_point - camera.position view_dir /= norm(view_dir) n = np.cross(view_dir, camera.view_up) n /= norm(n) u = camera.view_up[2] v = n[2] w = view_dir[2] anorm = norm([u, v, w]) # Convert angle around z-axis to azimuth, elevation and roll angle. theta = deg2rad(move[0]) elevation = - np.arcsin( (u * w * (1 - np.cos(theta)) - v * anorm * np.sin(theta)) / anorm ** 2) roll = np.arcsin( (u * v * (1 - np.cos(theta)) - w * anorm * np.sin(theta)) / anorm ** 2 / np.cos(elevation)) azimuth = np.arcsin( (v * w * (1 - np.cos(theta)) - u * anorm * np.sin(theta)) / anorm ** 2 / np.cos(elevation)) camera.azimuth(rad2deg(azimuth)) camera.elevation(rad2deg(elevation)) camera.roll(rad2deg(roll)) camera.orthogonalize_view_up() self.elevation += move[1] camera.elevation(self.elevation - mlab.view()[1]) camera.roll(self.roll - self.calc_current_roll(camera)) rwi.render()
def calc_current_roll(self, camera): n = np.cross(camera.focal_point - camera.position, camera.view_up) n /= norm(n) roll = np.arccos(camera.view_up[2] / norm(np.array( [n[2], camera.view_up[2]]))) roll *= -1 * np.sign(n[2]) return rad2deg(roll)