Changeset 2412 in lmdz_wrf for trunk


Ignore:
Timestamp:
Mar 24, 2019, 5:37:29 PM (6 years ago)
Author:
lfita
Message:

Adding more functions from AR6-zones script

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/geometry_tools.py

    r2411 r2412  
    1717####### Contents:
    1818# deg_deci: Function to pass from degrees [deg, minute, sec] to decimal angles [rad]
     19# multi_rotate_2D: Function to rotate multiple vectors by a certain angle in the plain
    1920# position_sphere: Function to tranform fom a point in lon, lat deg coordinates to
    2021#   cartesian coordinates over an sphere
     22# rotate_2D: Function to rotate a vector by a certain angle in the plain
     23# rotate_line2D: Function to rotate a line given by 2 pairs of x,y coordinates by a
     24#   certain angle in the plain
     25# rotate_lines2D: Function to rotate multiple lines given by mulitple pars of x,y
     26#   coordinates by a certain angle in the plain
    2127# surface_sphere: Function to provide an sphere as matrix of x,y,z coordinates
    2228# spheric_line: Function to transform a series of locations in lon, lat coordinates
    2329#   to x,y,z over an 3D spaceFunction to provide coordinates of a line  on a 3D space
     30
     31## Shapes/objects
     32# ellipse_polar: Function to determine an ellipse from its center and polar coordinates
    2433
    2534## Plotting
     
    95104
    96105    return coords
     106
     107def rotate_2D(vector, angle):
     108    """ Function to rotate a vector by a certain angle in the plain
     109      vector= vector to rotate [y, x]
     110      angle= angle to rotate [rad]
     111    >>> rotate_2D(np.array([1.,0.]), np.pi/4.)
     112    [ 0.70710678 -0.70710678]
     113    """
     114    fname = 'rotate_2D'
     115
     116    rotmat = np.zeros((2,2), dtype=np.float)
     117
     118    rotmat[0,0] = np.cos(angle)
     119    rotmat[0,1] = -np.sin(angle)
     120    rotmat[1,0] = np.sin(angle)
     121    rotmat[1,1] = np.cos(angle)
     122
     123    rotvector = np.zeros((2), dtype=np.float)
     124
     125    vecv = np.zeros((2), dtype=np.float)
     126
     127    # Unifying vector
     128    modvec = vector[0]**2+vector[1]**2
     129    if modvec != 0:
     130        vecv[0] = vector[1]/modvec
     131        vecv[1] = vector[0]/modvec
     132
     133        rotvec = np.matmul(rotmat, vecv)
     134        rotvec = np.where(np.abs(rotvec) < 1.e-7, 0., rotvec)
     135
     136        rotvector[0] = rotvec[1]*modvec
     137        rotvector[1] = rotvec[0]*modvec
     138
     139    return rotvector
     140
     141def multi_rotate_2D(vectors, angle):
     142    """ Function to rotate multiple vectors by a certain angle in the plain
     143      line= matrix of vectors to rotate
     144      angle= angle to rotate [rad]
     145    >>> square = np.zeros((4,2), dtype=np.float)
     146    >>> square[0,:] = [-0.5,-0.5]
     147    >>> square[1,:] = [0.5,-0.5]
     148    >>> square[2,:] = [0.5,0.5]
     149    >>> square[3,:] = [-0.5,0.5]
     150    >>> multi_rotate_2D(square, np.pi/4.)
     151    [[-0.70710678  0.        ]
     152     [ 0.         -0.70710678]
     153     [ 0.70710678  0.        ]
     154     [ 0.          0.70710678]]
     155    """
     156    fname = 'multi_rotate_2D'
     157
     158    rotvecs = np.zeros(vectors.shape, dtype=np.float)
     159
     160    Nvecs = vectors.shape[0]
     161    for iv in range(Nvecs):
     162        rotvecs[iv,:] = rotate_2D(vectors[iv,:], angle)
     163
     164    return rotvecs
     165
     166def rotate_line2D(line, angle):
     167    """ Function to rotate a line given by 2 pairs of x,y coordinates by a certain
     168          angle in the plain
     169      line= line to rotate as couple of points [[y0,x0], [y1,x1]]
     170      angle= angle to rotate [rad]
     171    >>> rotate_line2D(np.array([[0.,0.], [1.,0.]]), np.pi/4.)
     172    [[ 0.          0.        ]
     173     [0.70710678  -0.70710678]]
     174    """
     175    fname = 'rotate_2D'
     176
     177    rotline = np.zeros((2,2), dtype=np.float)
     178    rotline[0,:] = rotate_2D(line[0,:], angle)
     179    rotline[1,:] = rotate_2D(line[1,:], angle)
     180
     181    return rotline
     182
     183def rotate_lines2D(lines, angle):
     184    """ Function to rotate multiple lines given by mulitple pars of x,y coordinates 
     185          by a certain angle in the plain
     186      line= matrix of N couples of points [N, [y0,x0], [y1,x1]]
     187      angle= angle to rotate [rad]
     188    >>> square = np.zeros((4,2,2), dtype=np.float)
     189    >>> square[0,0,:] = [-0.5,-0.5]
     190    >>> square[0,1,:] = [0.5,-0.5]
     191    >>> square[1,0,:] = [0.5,-0.5]
     192    >>> square[1,1,:] = [0.5,0.5]
     193    >>> square[2,0,:] = [0.5,0.5]
     194    >>> square[2,1,:] = [-0.5,0.5]
     195    >>> square[3,0,:] = [-0.5,0.5]
     196    >>> square[3,1,:] = [-0.5,-0.5]
     197    >>> rotate_lines2D(square, np.pi/4.)
     198    [[[-0.70710678  0.        ]
     199      [ 0.         -0.70710678]]
     200
     201     [[ 0.         -0.70710678]
     202      [ 0.70710678  0.        ]]
     203
     204     [[ 0.70710678  0.        ]
     205      [ 0.          0.70710678]]
     206
     207     [[ 0.          0.70710678]
     208      [-0.70710678  0.        ]]]
     209    """
     210    fname = 'rotate_lines2D'
     211
     212    rotlines = np.zeros(lines.shape, dtype=np.float)
     213
     214    Nlines = lines.shape[0]
     215    for il in range(Nlines):
     216        line = np.zeros((2,2), dtype=np.float)
     217        line[0,:] = lines[il,0,:]
     218        line[1,:] = lines[il,1,:]
     219
     220        rotlines[il,:,:] = rotate_line2D(line, angle)
     221
     222    return rotlines
     223
     224####### ###### ##### #### ### ## #
     225# Shapes/objects
     226
     227def ellipse_polar(c, a, b, Nang=100):
     228    """ Function to determine an ellipse from its center and polar coordinates
     229        FROM: https://en.wikipedia.org/wiki/Ellipse
     230      c= coordinates of the center
     231      a= distance major axis
     232      b= distance minor axis
     233      Nang= number of angles to use
     234    """
     235    fname = 'ellipse_polar'
     236
     237    if np.mod(Nang,2) == 0: Nang=Nang+1
     238 
     239    dtheta = 2*np.pi/(Nang-1)
     240
     241    ellipse = np.zeros((Nang,2), dtype=np.float)
     242    for ia in range(Nang):
     243        theta = dtheta*ia
     244        rad = a*b/np.sqrt( (b*np.cos(theta))**2 + (a*np.sin(theta))**2 )
     245        x = rad*np.cos(theta)
     246        y = rad*np.sin(theta)
     247        ellipse[ia,:] = [y+c[0],x+c[1]]
     248
     249    return ellipse
     250
    97251
    98252####### ####### ##### #### ### ## #
Note: See TracChangeset for help on using the changeset viewer.