def __contains__(self, point): """ Point x in ellipsoid A <=> x^T A x <= 1. """ x = point - self.centre aux = np.dot(x, np.dot(self.mtx, x)) return aux <= 1.0
def setup_orientation(self): """ Sets rot_axis, the direction vector of rotation axis defining the orientation in space, and rot_angle, the rotation angle around the rotation axis according to self.conf. Also update the intersector. """ AnyObject.setup_orientation(self) self.mtx = np.dot(self.rot_mtx.T, np.dot(self.mtx0, self.rot_mtx)) self.rot_mtx_hc = gm.make_rotation_matrix_hc(self.rot_mtx) self.intersector.set_data(mtx=self.mtx)
def setup_orientation(self): """ If `direction` (orientation of the long axis of an object in space) is set in `self.conf`, compute the corresponding `rot_axis` (the direction vector of rotation axis) and `rot_angle` (the rotation angle around the rotation axis), that map the unrotated object (with `direction0` orientation) to the rotated one. From `rot_axis` and `rot_angle` form the rotation matrix `rot_mtx`, so that: - `direction = dot(rot_mtx.T, direction0)` - `direction0 = dot(rot_mtx, direction)` If `direction` is not set in `self.conf`, use `rot_axis` and `rot_angle` from `self.conf`, and compute the `direction` using the above relation. """ if hasattr(self.conf, 'direction'): nn = np.linalg.norm self.direction = evaluate(self.conf.direction, shape=(3,)) rd = np.dot(self.direction0, self.direction) self.rot_angle = np.arccos(rd / (nn(self.direction) * nn(self.direction0))) direction = self.direction while 1: self.rot_axis = np.cross(self.direction0, direction) ra = np.linalg.norm(self.rot_axis) if ra > 1e-5: break direction = evaluate('random', shape=(3,)) self.rot_axis /= ra else: self.rot_axis = evaluate(self.conf.rot_axis, shape=(3,)) self.rot_angle = evaluate(self.conf.rot_angle) self.rot_mtx = gm.make_axis_rotation_matrix(self.rot_axis, self.rot_angle) if not hasattr(self.conf, 'direction'): self.direction = np.dot(self.rot_mtx.T, self.direction0)
def setup_orientation(self): """ If `direction` (orientation of the long axis of an object in space) is set in `self.conf`, compute the corresponding `rot_axis` (the direction vector of rotation axis) and `rot_angle` (the rotation angle around the rotation axis), that map the unrotated object (with `direction0` orientation) to the rotated one. From `rot_axis` and `rot_angle` form the rotation matrix `rot_mtx`, so that: - `direction = dot(rot_mtx.T, direction0)` - `direction0 = dot(rot_mtx, direction)` If `direction` is not set in `self.conf`, use `rot_axis` and `rot_angle` from `self.conf`, and compute the `direction` using the above relation. """ if hasattr(self.conf, 'direction'): nn = np.linalg.norm self.direction = evaluate(self.conf.direction, shape=(3, )) rd = np.dot(self.direction0, self.direction) self.rot_angle = np.arccos( rd / (nn(self.direction) * nn(self.direction0))) direction = self.direction while 1: self.rot_axis = np.cross(self.direction0, direction) ra = np.linalg.norm(self.rot_axis) if ra > 1e-5: break direction = evaluate('random', shape=(3, )) self.rot_axis /= ra else: self.rot_axis = evaluate(self.conf.rot_axis, shape=(3, )) self.rot_angle = evaluate(self.conf.rot_angle) self.rot_mtx = gm.make_axis_rotation_matrix(self.rot_axis, self.rot_angle) if not hasattr(self.conf, 'direction'): self.direction = np.dot(self.rot_mtx.T, self.direction0)
def __contains__(self, point): """ Point x in cylinder. """ x = point - self.centre aux = np.dot(self.rot_mtx, x) r = np.sqrt(aux[0]**2 + aux[1]**2) val = (np.abs(aux[2]) <= self.height) & (r <= self.radius) return val
def _get_matrix_hc(self): """ Get the matrix describing the circumscribed ellipsoid in homogenous coordinates. It incorporates both the rotation and translation. Returns ------- mtx_hc : 4 x 4 array The matrix describing the circumscribed ellipsoid in homogenous coordinates. """ M0 = np.zeros((4, 4), dtype=np.float64) M0[:3,:3] = self.mtx0 M0[3, 3] = -1 M1 = np.dot(self.rot_mtx_hc.T, np.dot(M0, self.rot_mtx_hc)) T = gm.make_translation_matrix_hc(-self.centre) mtx_hc = np.dot(T.T, np.dot(M1, T)) return mtx_hc
def _get_matrix_hc(self): """ Get the matrix describing the circumscribed ellipsoid in homogenous coordinates. It incorporates both the rotation and translation. Returns ------- mtx_hc : 4 x 4 array The matrix describing the circumscribed ellipsoid in homogenous coordinates. """ M0 = np.zeros((4, 4), dtype=np.float64) M0[:3, :3] = self.mtx0 M0[3, 3] = -1 M1 = np.dot(self.rot_mtx_hc.T, np.dot(M0, self.rot_mtx_hc)) T = gm.make_translation_matrix_hc(-self.centre) mtx_hc = np.dot(T.T, np.dot(M1, T)) return mtx_hc
def contains(self, points): """ Point x in cylinder. Works for array of points. Parameters ---------- points : (n_point, 3) array The points to be tested for inclusion. """ points = np.array(points, ndmin=2, dtype=np.float64) x = points.T - self.centre[:,np.newaxis] aux = np.dot(self.rot_mtx, x) r = np.sqrt(aux[0,:]**2 + aux[1,:]**2) mask = (np.abs(aux[2,:]) <= (0.5 * self.height)) & (r <= self.radius) return mask
def contains(self, points): """ Point x in ellipsoid A <=> x^T A x <= 1. Works for array of points. Parameters: points : (n_point, 3) array """ points = np.array(points, ndmin=2, dtype=np.float64) x = points.T - self.centre[:, np.newaxis] aux = np.sum(x * np.dot(self.mtx, x), axis=0) mask = np.where(aux <= 1.0, True, False) ## x2 = np.r_[points.T, np.ones((1,points.shape[0]))] ## aux2 = np.sum(x2 * np.dot(self.mtx_hc, x2), axis = 0) ## mask2 = np.where(aux2 <= 0.0, True, False) ## print np.alltrue(mask == mask2) return mask
def contains(self, points): """ Point x in ellipsoid A <=> x^T A x <= 1. Works for array of points. Parameters: points : (n_point, 3) array """ points = np.array(points, ndmin=2, dtype=np.float64) x = points.T - self.centre[:,np.newaxis] aux = np.sum(x * np.dot(self.mtx, x), axis = 0) mask = np.where(aux <= 1.0, True, False) ## x2 = np.r_[points.T, np.ones((1,points.shape[0]))] ## aux2 = np.sum(x2 * np.dot(self.mtx_hc, x2), axis = 0) ## mask2 = np.where(aux2 <= 0.0, True, False) ## print np.alltrue(mask == mask2) return mask
def intersects(self, other): """Test if two ellipsoids self and other intersect. Returns ------- flag : int - 0 -> the ellipsoids are disjoint - 1 -> touch in a single surface point - 2 -> have common inner points """ A, B = self.mtx_hc, other.mtx_hc eigs = eig(np.dot(-inv(A), B), left=False, right=False).real roots = np.sort(eigs) ## print A, B, roots if roots[2] > 0: if roots[2] != roots[3]: return 0 else: return 1 else: return 2