def interpolate( self, in_lat, in_lon ): '''Interpolation method of wind at specified position. Uses bilinear aproximation between the vectors. Proportion is linear scaling of angle and linear scaling of length ''' in_lat = norm_lat(in_lat) in_lon = norm_lon(in_lon) lat_ind = in_lat // self.step_la if in_lat == 90: lat_ind -= 1 lon_ind = in_lon // self.step_lo if in_lon == 360: lon_ind = 0 left = lon_ind * self.step_lo right = ( lon_ind + 1 ) * self.step_lo bottom = lat_ind * self.step_la top = ( lat_ind + 1 ) * self.step_la LB = self.wind_grid[bottom][left] LT = self.wind_grid[top][left] RB = self.wind_grid[bottom][norm_lon(right)] RT = self.wind_grid[top][norm_lon(right)] top_vec = self.proport( LT, RT, (in_lon - left) / (right - left) ) bot_vec = self.proport( LB, RB, (in_lon - left) / (right - left) ) return self.proport( bot_vec, top_vec, \ (in_lat - bottom) / (top - bottom) )
def phi_theta( x, y, z ): '''Converts x, y, z tripplet into phi, theta normalizing output on the fly ''' r = sqrt( x*x + y*y + z*z ) phi = norm_lon( atan2( y, x )*ratioPI ) theta = norm_lat( acos( z / r )*ratioPI - 90.0 ) return ( phi, theta )
def interpolate_naive( self, in_lat, in_lon ): '''A bit stupid methon Resulting vector is proportional to how it`s close to \ corner base grid vectors ''' in_lat = norm_lat(in_lat) in_lon = norm_lon(in_lon) lat_ind = in_lat // self.step_la if in_lat == 90: lat_ind -= 1 lon_ind = in_lon // self.step_lo if in_lon == 360: lon_ind = 0 left = lon_ind * self.step_lo right = ( lon_ind + 1 ) * self.step_lo bottom = lat_ind * self.step_la top = ( lat_ind + 1 ) * self.step_la LB = self.wind_grid[bottom][left] LT = self.wind_grid[top][left] RB = self.wind_grid[bottom][norm_lon(right)] RT = self.wind_grid[top][norm_lon(right)] ltx = math.sqrt( \ (in_lat-top)*(in_lat-top) + (in_lon-left)*(in_lon-left) ) lbx = math.sqrt( \ (in_lat-bottom)*(in_lat-bottom) + (in_lon-left)*(in_lon-left) ) rtx = math.sqrt( \ (in_lat-top)*(in_lat-top) + (in_lon-right)*(in_lon-right) ) rbx = math.sqrt( \ (in_lat-bottom)*(in_lat-bottom) + (in_lon-right)*(in_lon-right) ) norma = ltx + lbx + rtx + rbx return ( ((norma-ltx)*LT[0]/norma + (norma-lbx)*LB[0]/norma + \ (norma-rtx)*RT[0]/norma + (norma-rbx)*RB[0]/norma)/3 , \ ((norma-ltx)*LT[1]/norma + (norma-lbx)*LB[1]/norma + \ (norma-rtx)*RT[1]/norma + (norma-rbx)*RB[1]/norma)/3 )
def points_gen( self, psi, units=DEGREES, verbose = True ): '''Genertion of the points randomly distributed with *average* resolution of psi. Arguments: psi (float) -- resolution units (DEGREES/RADIANS) -- how psi is set (default: DEGREES) ''' k = 0.5 / pi p0 = k * self.domain.phi[0] p1 = k * self.domain.phi[1] t0 = 0.5* ( 1 + cos( self.domain.theta[1] ) ) t1 = 0.5* ( 1 + cos( self.domain.theta[0] ) ) N = self.domain.point_count( psi, units ) if verbose: print("points amount to generate " + str(N)) self.points_clear() # arccos method: for j in range( N ): U = random.uniform( p0, p1 ) V = random.uniform( t0, t1 ) phi = 2*pi* U theta = acos( 2*V - 1 ) x,y,z = geocoords.xyz_spherical( theta, phi ) self.points.append( (x,y,z) ) self.points_angular.append( ( norm_lon( phi*ratioPI), \ norm_lat( theta*ratioPI) ) ) return