Rotate "lon", "lat" coords (in _degrees_) about the X-axis by "theta"
    degrees.  This effectively simulates rotating a physical stereonet.
    Returns rotated lon, lat coords in _radians_).
514634
def _rotate(lon, lat, theta, axis='x'):
    
    # Convert input to numpy arrays in radians
    lon, lat = np.atleast_1d(lon, lat)
    lon, lat = map(np.radians, [lon, lat])
    theta = np.radians(theta)

    # Convert to cartesian coords for the rotation
    x, y, z = sph2cart(lon, lat)

    lookup = {'x':_rotate_x, 'y':_rotate_y, 'z':_rotate_z}
    X, Y, Z = lookup[axis](x, y, z, theta)

    # Now convert back to spherical coords (longitude and latitude, ignore R)
    lon, lat = cart2sph(X,Y,Z)
    return lon, lat
1089880
def axis_rotation_matrix(axis, theta):
    """"""
    [x, y, z] = axis
    c = np.cos(theta)
    s = np.sin(theta)
    return np.array([
        [x**2 + (1 - x**2) * c, x * y * (1 - c) - z * s, x * z * (1 - c) + y * s],
        [x * y * (1 - c) + z * s, y ** 2 + (1 - y**2) * c, y * z * (1 - c) - x * s],
        [x * z * (1 - c) - y * s, y * z * (1 - c) + x * s, z**2 + (1 - z**2) * c]
    ])
851297
def sky(lon=None,lat=None,size=1):
    
    if lon is None:
        umin,umax = 0,1
    else:
        lon = np.asarray(lon)
        lon = np.radians(lon + 360.*(lon<0))
        if   lon.size==1: umin=umax=lon/(2*np.pi)
        elif lon.size==2: umin,umax=lon/(2*np.pi)
        else: raise Exception('...')
        
    if lat is None:
        vmin,vmax = -1,1
    else:
        lat = np.asarray(lat)
        lat = np.radians(90 - lat)
        if   lat.size==1: vmin=vmax=np.cos(lat)
        elif lat.size==2: vmin,vmax=np.cos(lat)
        else: raise Exception('...')

    phi = 2*np.pi*np.random.uniform(umin,umax,size=size)
    theta = np.arcsin(np.random.uniform(vmin,vmax,size=size))
    return np.degrees(phi),np.degrees(theta)
179152
def _spherical_to_cartesian(cls, coord, center):
        
        r, theta, phi, r_dot, theta_dot, phi_dot = coord
        x = r * cos(phi) * cos(theta)
        y = r * cos(phi) * sin(theta)
        z = r * sin(phi)

        vx = r_dot * x / r - y * theta_dot - z * phi_dot * cos(theta)
        vy = r_dot * y / r + x * theta_dot - z * phi_dot * sin(theta)
        vz = r_dot * z / r + r * phi_dot * cos(phi)

        return np.array([x, y, z, vx, vy, vz], dtype=float)
966806
def pinc(lat):
    
    tanl = np.tan(np.radians(lat))
    inc = np.arctan(2. * tanl)
    return np.degrees(inc)
1037561
def z_angle_rotate(xy, theta):
    
    xy = np.array(xy).T
    theta = np.array(theta).T

    out = np.zeros_like(xy)
    out[...,0] = np.cos(theta)*xy[...,0] - np.sin(theta)*xy[...,1]
    out[...,1] = np.sin(theta)*xy[...,0] + np.cos(theta)*xy[...,1]

    return out.T
719900
public static Geometry rotate(Geometry geom, double theta, Point point) {
        return rotate(geom, theta, point.getX(), point.getY());
    }
1325594
def preRotate(self, theta):
        """"""
        while theta < 0: theta += 360
        while theta >= 360: theta -= 360
        epsilon = 1e-5
        if abs(0 - theta) < epsilon:
            pass

        elif abs(90.0 - theta) < epsilon:
            a = self.a
            b = self.b
            self.a = self.c
            self.b = self.d
            self.c = -a
            self.d = -b

        elif abs(180.0 - theta) < epsilon:
            self.a = -self.a
            self.b = -self.b
            self.c = -self.c
            self.d = -self.d

        elif abs(270.0 - theta) < epsilon:
            a = self.a
            b = self.b
            self.a = -self.c
            self.b = -self.d
            self.c = a
            self.d = b

        else:
            rad = math.radians(theta)
            s = round(math.sin(rad), 12)
            c = round(math.cos(rad), 12)
            a = self.a
            b = self.b
            self.a = c * a + s * self.c
            self.b = c * b + s * self.d
            self.c =-s * a + c * self.c
            self.d =-s * b + c * self.d

        return self
283831
def rotation_matrix(axis, theta):
    
    axis = np.asarray(axis)
    axis = axis / np.linalg.norm(axis)
    a = np.cos(theta / 2)
    b, c, d = -axis * np.sin(theta / 2)
    aa, bb, cc, dd = a * a, b * b, c * c, d * d
    bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
    return np.array([
        [aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
        [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
        [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc],
    ])
193873
def rotate_y(self, angle):
        
        axis_rotation(self.points, angle, inplace=True, axis='y')
223264
def aitoffImageToSphere(x, y):
    
    x = x - 360.*(x>180)
    x = np.asarray(np.radians(x))
    y = np.asarray(np.radians(y))
    z = np.sqrt(1. - (x / 4.)**2 - (y / 2.)**2) # rad
    lon = 2. * np.arctan2((2. * z**2) - 1, (z / 2.) * x)
    lat = np.arcsin( y * z)
    return ((180. - np.degrees(lon)) % 360.), np.degrees(lat)
119006
public static Geometry rotate(Geometry geom, double theta) {
        if (geom != null) {
            Coordinate center = geom.getEnvelopeInternal().centre();
            return rotate(geom, theta, center.x, center.y);
        } else {
            return null;
        }
    }
1014793
def rot1(theta):
    
    return np.array([
        [1, 0, 0],
        [0, np.cos(theta), np.sin(theta)],
        [0, -np.sin(theta), np.cos(theta)]
    ])
572304
def rotate(self, theta_deg, xoff=0, yoff=0):
        
        self.rotate_deg([theta_deg], (xoff, yoff))
1275774
def gps_offset(lat, lon, east, north):
    ''''''
    bearing = math.degrees(math.atan2(east, north))
    distance = math.sqrt(east**2 + north**2)
    return gps_newpos(lat, lon, bearing, distance)
582863
def _rotate(n, x, y, rx, ry):
    
    if ry == 0:
        if rx == 1:
            x = n - 1 - x
            y = n - 1 - y
        return y, x
    return x, y
720765
def axis_rotation(points, angle, inplace=False, deg=True, axis='z'):
    
    axis = axis.lower()

    # Copy original array to if not inplace
    if not inplace:
        points = points.copy()

    # Convert angle to radians
    if deg:
        angle *= np.pi / 180

    if axis == 'x':
        y = points[:, 1] * np.cos(angle) - points[:, 2] * np.sin(angle)
        z = points[:, 1] * np.sin(angle) + points[:, 2] * np.cos(angle)
        points[:, 1] = y
        points[:, 2] = z
    elif axis == 'y':
        x = points[:, 0] * np.cos(angle) + points[:, 2] * np.sin(angle)
        z = - points[:, 0] * np.sin(angle) + points[:, 2] * np.cos(angle)
        points[:, 0] = x
        points[:, 2] = z
    elif axis == 'z':
        x = points[:, 0] * np.cos(angle) - points[:, 1] * np.sin(angle)
        y = points[:, 0] * np.sin(angle) + points[:, 1] * np.cos(angle)
        points[:, 0] = x
        points[:, 1] = y
    else:
        raise Exception('invalid axis.  Must be either "x", "y", or "z"')

    if not inplace:
        return points