def circular_uniform_random_sample(no=[10, 50], radius=10., center=[0., 0., 0.], angles=[0., 0., 0.]): """ Definition to generate sample inside a circle uniformly but randomly. Parameters ---------- no : list Number of samples. radius : float Radius of the circle. center : list Center location of the surface. angles : list Tilt of the surface. Returns ---------- samples : ndarray Samples generated. """ samples = np.empty((0, 3)) rs = np.sqrt(np.random.uniform(0, 1, no[0])) angs = np.random.uniform(0, 2 * np.pi, no[1]) for i in rs: for angle in angs: r = radius * i point = np.array( [float(r * np.cos(angle)), float(r * np.sin(angle)), 0]) samples = np.vstack((samples, point)) samples = rotate_points(samples, angles=angles, offset=center) return samples
def tilt_towards(location,lookat): """ Definition to tilt surface normal of a plane towards a point. Parameters ---------- location : list Center of the plane to be tilted. lookat : list Tilt towards this point. Returns ---------- angles : list Rotation angles in degrees. """ dx = location[0]-lookat[0] dy = location[1]-lookat[1] dz = location[2]-lookat[2] dist = np.sqrt(dx**2+dy**2+dz**2) phi = np.arctan2(dy,dx) theta = np.arccos(dz/dist) angles = [ 0, np.degrees(theta).tolist(), np.degrees(phi).tolist() ] return angles
def distance_between_two_points(point1, point2): """ Definition to calculate distance between two given points. Parameters ---------- point1 : list First point in X,Y,Z. point2 : list Second point in X,Y,Z. Returns ---------- distance : float Distance in between given two points. """ point1 = np.asarray(point1) point2 = np.asarray(point2) if len(point1.shape) == 1 and len(point2.shape) == 1: distance = np.sqrt(np.sum((point1 - point2)**2)) elif len(point1.shape) == 2 or len(point2.shape) == 2: distance = np.sqrt(np.sum((point1 - point2)**2, axis=1)) return distance
def distance_between_point_clouds(points0, points1): """ A definition to find distance between every point in one cloud to other points in the other point cloud. Parameters ---------- points0 : ndarray Mx3 points. points1 : ndarray Nx3 points. Returns ---------- distances : ndarray MxN distances. """ c = points1.reshape((1, points1.shape[0], points1.shape[1])) a = np.repeat(c, points0.shape[0], axis=0) b = points0.reshape((points0.shape[0], 1, points0.shape[1])) b = np.repeat(b, a.shape[1], axis=1) distances = np.sqrt(np.sum((a - b)**2, axis=2)) return distances
def create_ray_from_two_points(x0y0z0, x1y1z1): """ Definition to create a ray from two given points. Note that both inputs must match in shape. Parameters ---------- x0y0z0 : list List that contains X,Y and Z start locations of a ray (3). It can also be a list of points as well (mx3). This is the starting point. x1y1z1 : list List that contains X,Y and Z ending locations of a ray (3). It can also be a list of points as well (mx3). This is the end point. Returns ---------- ray : ndarray Array that contains starting points and cosines of a created ray. """ x0y0z0 = np.asarray(x0y0z0, dtype=np.float) x1y1z1 = np.asarray(x1y1z1, dtype=np.float) if len(x0y0z0.shape) == 1: x0y0z0 = x0y0z0.reshape((1, 3)) if len(x1y1z1.shape) == 1: x1y1z1 = x1y1z1.reshape((1, 3)) xdiff = x1y1z1[:, 0] - x0y0z0[:, 0] ydiff = x1y1z1[:, 1] - x0y0z0[:, 1] zdiff = x1y1z1[:, 2] - x0y0z0[:, 2] s = np.sqrt(xdiff**2 + ydiff**2 + zdiff**2) s[s == 0] = np.NaN cosines = np.zeros((xdiff.shape[0], 3)) cosines[:, 0] = xdiff / s cosines[:, 1] = ydiff / s cosines[:, 2] = zdiff / s ray = np.zeros((xdiff.shape[0], 2, 3), dtype=np.float) ray[:, 0] = x0y0z0 ray[:, 1] = cosines if ray.shape[0] == 1: ray = ray.reshape((2, 3)) return ray
def rayleigh_sommerfeld(field,k,distance,dx,wavelength): """ Definition to compute beam propagation using Rayleigh-Sommerfeld's diffraction formula (Huygens-Fresnel Principle). For more see Section 3.5.2 in Goodman, Joseph W. Introduction to Fourier optics. Roberts and Company Publishers, 2005. Parameters ---------- field : np.complex Complex field (MxN). k : odak.wave.wavenumber Wave number of a wave, see odak.wave.wavenumber for more. distance : float Propagation distance. dx : float Size of one single pixel in the field grid (in meters). wavelength : float Wavelength of the electric field. Returns ======= result : np.complex Final complex field (MxN). """ nv,nu = field.shape x = np.linspace(-nv*dx/2,nv*dx/2,nv) y = np.linspace(-nu*dx/2,nu*dx/2,nu) X,Y = np.meshgrid(x,y) Z = X**2+Y**2 result = np.zeros(field.shape,dtype=np.complex64) direction = int(distance/np.abs(distance)) for i in range(nu): for j in range(nv): if field[i,j] != 0: r01 = np.sqrt(distance**2+(X-X[i,j])**2+(Y-Y[i,j])**2)*direction cosnr01 = np.cos(distance/r01) result += field[i,j]*np.exp(1j*k*r01)/r01*cosnr01 result *= 1./(1j*wavelength) return result