def cart2spher(x, y, z, deg=True): """ Convert cartesian to spherical coordinates. Args: :x, y, z: | tuple of floats, ints or ndarrays | Cartesian coordinates Returns: :theta: | Float, int or ndarray | Angle with positive z-axis. :phi: | Float, int or ndarray | Angle around positive z-axis starting from x-axis. :r: | 1, optional | Float, int or ndarray | radius """ r = np.sqrt(x * x + y * y + z * z) phi = np.arctan2(y, x) phi[phi < 0.] = phi[phi < 0.] + 2 * np.pi zdr = z / r zdr[zdr > 1.] = 1. zdr[zdr < -1.] = -1 theta = np.arccos(zdr) if deg == True: theta = theta * 180 / np.pi phi = phi * 180 / np.pi return theta, phi, r
def get_tpr(self, *args): if len(args) > 0: x, y, z = args else: x, y, z = self.x, self.y, self.z r = np.sqrt(x * x + y * y + z * z) zdr = np.asarray(z / r) zdr[zdr > 1.0] = 1.0 zdr[zdr < -1.0] = -1.0 theta = np.arccos(z / r) phi = np.arctan2(y, x) phi[phi < 0.0] = phi[phi < 0.0] + 2 * np.pi phi[r < self._TINY] = 0.0 theta[r < self._TINY] = 0.0 return theta, phi, r
def angle_v1v2(v1,v2,htype = 'deg'): """ Calculates angle between two vectors. Args: :v1: | ndarray with vector 1 :v2: | ndarray with vector 2 :htype: | 'deg' or 'rad', optional | Requested angle type. Returns: :ang: | ndarray """ denom = magnitude_v(v1)*magnitude_v(v2) denom[denom==0.] = np.nan ang = np.arccos(np.sum(v1*v2,axis=1)/denom) if htype == 'deg': ang = ang*180/np.pi return ang
def rotate(v, vecA=None, vecB=None, rot_axis=None, rot_angle=None, deg=True, norm=False): """ Rotate vector around rotation axis over angle. Args: :v: | vec3 vector. :rot_axis: | None, optional | vec3 vector specifying rotation axis. :rot_angle: | None, optional | float or int rotation angle. :deg: | True, optional | If False, rot_angle is in radians. :vecA:, :vecB: | None, optional | vec3 vectors defining a normal direction (cross(vecA, vecB)) around | which to rotate the vector in :v:. If rot_angle is None: rotation | angle is defined by the in-plane angle between vecA and vecB. :norm: | False, optional | Normalize rotated vector. """ if (vecA is not None) & (vecB is not None): rot_axis = cross(vecA, vecB) # rotation axis if rot_angle is None: costheta = dot(vecA, vecB, norm=True) # rotation angle costheta[costheta > 1] = 1 costheta[costheta < -1] = -1 rot_angle = np.arccos(costheta) elif (rot_angle is not None): if deg == True: rot_angle = np.deg2rad(rot_angle) else: raise Exception('vec3.rotate: insufficient not-None input args.') # normalize rot_axis rot_axis = rot_axis / rot_axis.norm() # Create short-hand variables: u = rot_axis cost = np.cos(rot_angle) sint = np.sin(rot_angle) # Setup rotation matrix: R = np.asarray([[np.zeros(u.x.shape) for j in range(3)] for i in range(3)]) R[0, 0] = cost + u.x * u.x * (1 - cost) R[0, 1] = u.x * u.y * (1 - cost) - u.z * sint R[0, 2] = u.x * u.z * (1 - cost) + u.y * sint R[1, 0] = u.x * u.y * (1 - cost) + u.z * sint R[1, 1] = cost + u.y * u.y * (1 - cost) R[1, 2] = u.y * u.z * (1 - cost) - u.x * sint R[2, 0] = u.z * u.x * (1 - cost) - u.y * sint R[2, 1] = u.z * u.y * (1 - cost) + u.x * sint R[2, 2] = cost + u.z * u.z * (1 - cost) # calculate dot product of matrix M with vector v: v3 = vec3(R[0,0]*v.x + R[0,1]*v.y + R[0,2]*v.z, \ R[1,0]*v.x + R[1,1]*v.y + R[1,2]*v.z, \ R[2,0]*v.x + R[2,1]*v.y + R[2,2]*v.z) if norm == True: v3 = v3 / v3.norm() return v3