def get_pan(self, direction): """ Get pan angle in degrees for a given direction. The given direction should be in the same coordinate system as the above and forward directions that were given in initialization. That is, they should not be transformed :param direction: 3-d vector :returns: pan angle in degrees """ # Check input direction = mat.check_3d_vec(direction) # Transform into native coordinates direction = self._transform(direction) direction *= np.array([1, 1, 0]) # Project onto xy plane if mat.norm2(direction) < EPS: # No component in xy plane return 0 direction /= mat.norm2(direction) # Get pan angle forward = np.array([1, 0, 0]) # Forward is positive x direction dot_prod = direction.dot(forward) if abs(dot_prod) > 1: # Small floating point errors can give domain erros in acos dot_prod = mat.sign(dot_prod) pan = math.acos(dot_prod) # x.dot(dir) = cos(pan) pan = min(mat.to_degrees(pan), MAX_PAN_DEGREE) # Determine whether should be in [0, pi] or [0, -pi] y = np.array([0, 1, 0]) pan *= mat.sign(y.dot(direction)) return pan
def _process_inputs(self, mu, kappa, rv): if rv.dimension != self._ndim(mu): raise ValueError("RV and mu must have same number of dimensions") if tools.norm2(mu) < consts.EPS: raise ValueError("mu must have non-zero length") self._n_dimensions = self._ndim(mu) mu /= tools.norm2(mu) self._mu = mu self._cpdf = VonMisesCPdf(kappa, rv)
def _verify_params(self, normal, up, offset): """ Ensure vector parameters passed to init are valid """ self._normal = tools.check_3d_vec(normal) self._normal /= tools.norm2(self._normal) self._up = tools.check_3d_vec(up) self._up /= tools.norm2(self._up) self._offset = tools.check_3d_vec(offset) # Get third coordinate vector self._right = np.cross(self._up, self._normal) self._right /= tools.norm2(self._right)
def _verify_params(self, normal, offset): """ Ensure vector parameters passed to init are valid """ self._normal = tools.check_3d_vec(normal) self._normal /= tools.norm2(self._normal) self._offset = tools.check_3d_vec(offset)
def get_tilt(self, direction): """ :param direction: Direction to find tilt angle for :returns: tilt angle in degrees """ # Noramlize direction = mat.check_3d_vec(direction) if mat.norm2(direction) < EPS: return 0. # No tilt in zero vec... direction /= mat.norm2(direction) # Transform into native coordinates direction = self._transform(direction) # Get tilt angle above = np.array([0, 0, 1.]) # Above in positive z direction dot_prod = -1. * direction.dot(above) if abs(dot_prod) > 1: # Small floating point errors can give domain erros in acos dot_prod = mat.sign(dot_prod) tilt = math.acos(dot_prod) tilt = mat.to_degrees(tilt) - 90 # Now 0 corresponds to x-y plane, -90 to -z return min(tilt, MAX_TILT_DEGREE) # Cannot go above 25 degrees
def _setup_transform(self, forward, above): """ Setup the transformation matrix that will be used to transform given coordinates into the native coordinate system. Note that forward and above should be orthogonal vectors. In the native coordinate system, the forward vector will correspond to the positive x direction and the above vector to the positive z direction. So denote x and z as the unit vectors in those respective directions. Then we take y to be z cross x. Now we want to find transformation matrix R such that given direction d in the search space coordinate system, we can apply R to d and get w - the same direction in the native coordinate system. We assume the search coordinate system are standard i, j, k vectors. This is ok since the forward and above vectors are defined in those coordinates Then the linear transformation matrix for the search coordinate system is the identity matrix. So we now seek to solve I*d = A*w, where A's columns consist of x, y, z. So to get w, we have inv(A)*d = w. Since x, y, z are orthogonal, this is the same as A.T*d = w, and thus R = A.T """ # Check inputs forward = mat.check_3d_vec(forward) above = mat.check_3d_vec(above) if mat.norm2(forward) < EPS or mat.norm2(above) < EPS: raise ValueError("forward and above vectors must not be length 0") if abs(forward.dot(above)) > EPS: raise ValueError("forward and above vectors must be orthogonal") # Normalize vectors x = forward / mat.norm2(forward) z = above / mat.norm2(above) y = np.cross(z, x) y /= mat.norm2(y) # just in case # Make matrix self._trans_mat = np.array([x, y, z])