def fill_ray_tree(tree: Tree, surfaces: list, deep: int): ray_ = tree.value # index of nearest surface and intersection point index, i_point = _not_sequence_modeling(ray_, surfaces) reflect_ray = None refract_ray = None exit = False # if intersection is if i_point == None: tree.left = None tree.right = None exit = True # i_point = ray_.calc_point_of_ray(ray_const_length) # _append_point_to_path(ray_, ray_._Ray__path_of_ray, i_point) if deep < 0: return if exit: return # check total internal refraction if rc.is_total_inturnal_refraction(ray_, surfaces[index]): reflect_ray = Ray.reflect(ray_, surfaces[index]) tree.left = Tree(reflect_ray) else: refract_ray = Ray.refract(ray_, surfaces[index]) tree.right = Tree(refract_ray) reflect_ray = Ray.reflect(ray_, surfaces[index]) tree.left = Tree(reflect_ray) point, norm, t = ARay.find_norm_vec_and_point(ray_.dir, ray_.start, surfaces[index]) n1, n2 = surfaces[index].get_refractive_indexes(ray_.start) # , n1, n2 rc.set_brightness(type_polarization, ray_, refract_ray, reflect_ray, norm, n1, n2) # следующая итерация рекурсии if tree.left is not None: fill_ray_tree(tree.left, surfaces, deep - 1) else: tree.left = Tree(None) if tree.right is not None: fill_ray_tree(tree.right, surfaces, deep - 1) else: tree.right = Tree(None)
def main(): start = time.time() half_angle = 18 is_isosceles = True lenght_of_side_ribs = 3 is_closed = False refr_coef_inside = 1.69 refr_coef_outsid = 1 axicon = axic.create_axicon(half_angle, is_isosceles, lenght_of_side_ribs, is_closed, refr_coef_inside, refr_coef_outsid) is_single = False type_polarization = 'p' ray = Ray([-2, 0.2], [1, 0]) ray_index = 1 if is_single else [1, 3] from_refr_coef = 1.696 to_refr_coef = 1.697 step = 0.000_000_1 if is_single: single_calculate_frenel_coeff(type_polarization, axicon, ray, ray_index, from_refr_coef, to_refr_coef, step, start) else: multiple_calculate_frenel_coeff(type_polarization, axicon, ray, ray_index, from_refr_coef, to_refr_coef, step, start)
def main(): center = [1, 2, 1] abc = [1, 1, 1] ray: Ray = Ray([0, 0, 0], [1, 1, 1]) ellipse1 = Ellipse(center=center, ellipse_coefficients=abc, type_surface=Ellipse.types.REFRACTING, n1=1, n2=1.33) plane = Plane([1, 1, 1], [0, 1, 1], type_surface=Ellipse.types.REFRACTING, n1=1, n2=1.33) # way_point_of_ray = mctrl.model_path(ray, [ellipse1], is_have_ray_in_infinity=True) way_point_of_ray2 = mctrl.model_path(ray, [plane], is_have_ray_in_infinity=True) fig = plt.figure() ax = Axes3D(fig) ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') # ellipse(ax, ellipse1.abc, ellipse1.center) # line(ax, way_point_of_ray[0], way_point_of_ray[1], way_point_of_ray[2], "g") line(ax, way_point_of_ray2[0], way_point_of_ray2[1], way_point_of_ray2[2], "g") plot_plane(ax, plane) plt.show()
def is_total_inturnal_refraction(ray: Ray, surface: Surface) -> bool: # list, list, float point, nrm, t_1 = ARay.find_norm_vec_and_point(ray.dir, ray.start, surface, None) if len(point) == 0 and len(nrm) == 0 and t_1 is None: return False ray.t1 = t_1[0] # ШАГ-3 преломляем луч n1, n2 = surface.get_refractive_indexes(ray.start) # calc the formula of refraction v1 = np.dot(n1, ray.dir) v1n = np.dot(v1, nrm) expression = 1 + (n2**2 - n1**2) / (v1n**2) return expression < 0
def _not_sequence_modeling(ray: Ray, surfaces: List[Surface]): min_p = 100000000000000 # index of nearest surface and intersection point index = -1 for i in range(len(surfaces)): t = surfaces[i].ray_surface_intersection(ray.dir, ray.start) if len(t) != 0: t = t[0] else: continue if t < min_p: min_p = t index = i if index != -1: return index, ray.calc_point_of_ray(min_p) else: return index, None
def func_of_reading_surf_ray_from_strings(strings, dimension): d = dimension rays = [] surfaces = [] for s in strings: nums = np.fromstring(s[3:], dtype=float, count=-1, sep=' ') # p = plane s = sphere e = ellipse if s[0] == 'r': rays.append(Ray(nums[:d], nums[d:2 * d])) else: surface = None if s[0] == 'p': if s[1] == 't': surface = Plane(nums[:d], nums[d:2 * d], Surface.types.REFRACTING, nums[len(nums) - 2], nums[len(nums) - 1]) else: surface = Plane(nums[:d], nums[d:2 * d]) elif s[0] == 's': if s[1] == 't': surface = Sphere(nums[:d], nums[d], Surface.types.REFRACTING, nums[len(nums) - 2], nums[len(nums) - 1]) else: surface = Sphere(nums[:d], nums[d]) elif s[0] == 'e': if s[1] == 't': surface = Ellipse(nums[:d], nums[d:2 * d], Surface.types.REFRACTING, nums[len(nums) - 2], nums[len(nums) - 1]) else: surface = Ellipse(nums[:d], nums[d:2 * d]) if (surface != None): print('\tSUCCESS ' + str(surface)) surfaces.append(surface) return rays, surfaces
def set_amplitude(type_polarisation: str, fall_ray: Ray, refract_ray: Ray, reflect_ray: Ray, norm_vec: list): # , n1: float, n2: float): if (fall_ray is None) or (refract_ray is None and reflect_ray is None): return if (refract_ray is None) and (reflect_ray is not None): reflect_ray.A = fall_ray.A return if (refract_ray is not None) and (reflect_ray is None): refract_ray.A = fall_ray.A return if (norm_vec is None): return print("norm_vec ", norm_vec) a_b = [ get_min_angle_between_vec(reflect_ray.dir, norm_vec), get_min_angle_between_vec(refract_ray.dir, norm_vec) ] pi_on_2 = np.pi / 2 for i in range(2): if a_b[i] > pi_on_2: a_b[i] = np.pi - a_b[i] a_b_degree = [180 * i / np.pi for i in a_b] # digit calculation have mistakes in angle to close to 90 degree. # And is created two rays with different in coordinates on machine epsilon if all(i == 0 for i in a_b_degree): refract_ray.A = fall_ray.A - np.finfo(float).eps reflect_ray.A = np.finfo(float).eps return print(fall_ray, reflect_ray, refract_ray, sep='\n') print(a_b_degree) s_amp, q_amp = recalc_amplitude(type_polarisation, fall_ray.A, a_b[0], a_b[1]) # , n1=n1, n2=n2) reflect_ray.A = q_amp refract_ray.A = s_amp
def find_intersection_with_surface(self, ray: Ray) -> list: positive_t = Ellipse.ray_surface_intersection(self, ray.dir, ray.start) if len(positive_t) > 0: ray.t0 = [positive_t[0], self] return [ray.calc_point_of_ray(t) for t in positive_t] return []
def read_param(): auto_run = True isosceles = True if not auto_run: isosceles = input("Is it isosceles triangle(y/n)?") if isosceles == 'y' or isosceles == 'Y': isosceles = True else: isosceles = False # ans = input("Do you want to enter param in console or use file(c - console/f - file)?") angle = None length = None rayarr = None refr_coef = None filename = None # if ans[0] is 'c' or ans[0] is 'C': # angle = float(input("Enter the angle of line( 0 < angle < 90).\n")) # if not is_correct_angle(angle): # return # # length = float(input("Enter the length of hypotenuse(length > 0)\n")) # if not is_correct_length(length): # return # refr_coef = input("Enter refraction coefficients. N1 - inside triangle. N2 - outside('n1 n2')\n") # refr_coef = [float(s) for s in refr_coef.split(' ')] # if len(refr_coef) is not 2: # print("Oops. You should be thoughtful") # return # raystr = input("And most difficult. Enter the ray(begin of ray and direction \'x1 y1 x2 y2\')\n") # rayarr = [float(s) for s in raystr.split(' ')] # if len(rayarr) is not 4: # print("Oops. You should read carefully. And think about it. I sad you that it is difficult.") # return # elif ans[0] is 'f' or ans[0] is 'F': # filename = input( # "Enter path to file('filename.txt') or enter the 'd' to use default file('pic.txt')") # if filename is 'd': filename = "pic.txt" file = open(filename) angle = float(file.readline()) length = float(file.readline()) refr_coef = file.readline() print(refr_coef) refr_coef = [float(val) for val in refr_coef.split(' ')] print(refr_coef) raystr = file.readline() rayarr = [float(s) for s in raystr.split(' ')] if not is_correct_angle(angle): return if not is_correct_length(length): return if len(refr_coef) != 2: print( "Oops. You should read carefully. And think about it. I sad you that it is difficult." ) return if len(rayarr) != 4: print( "Oops. You should read carefully. And think about it. I sad you that it is difficult." ) return # else: # return ray = Ray(rayarr[:2], rayarr[2:4]) axic = axicon.create_axicon(angle, isosceles, length, False, refr_coef[0], refr_coef[1]) return [ray, axic[0], axic[1], isosceles, angle]
def set_brightness(type_polarisation: str, fall_ray: Ray, refract_ray: Ray, reflect_ray: Ray, norm_vec: list, n1: float, n2: float, is_amlitude_calculate: bool = False): if (fall_ray is None) or (refract_ray is None and reflect_ray is None): return if (refract_ray is None) and (reflect_ray is not None): reflect_ray.bright = fall_ray.bright return if (refract_ray is not None) and (reflect_ray is None): refract_ray.bright = fall_ray.bright return if norm_vec is None: return reflect_brightness = 1 refract_brightness = 1 if is_amlitude_calculate: set_amplitude(type_polarisation=type_polarisation, fall_ray=fall_ray, refract_ray=refract_ray, reflect_ray=reflect_ray, norm_vec=norm_vec) if is_amlitude_calculate and type_polarisation == "s": reflect_brightness = reflect_ray.A**2 / fall_ray.A**2 refract_brightness = 1 - reflect_brightness else: if type_polarisation != 's' and type_polarisation != 'p': return a_b = [ get_min_angle_between_vec(reflect_ray.dir, norm_vec), get_min_angle_between_vec(refract_ray.dir, norm_vec) ] pi_on_2 = np.pi / 2 for i in range(2): if a_b[i] > pi_on_2: a_b[i] = np.pi - a_b[i] # digit calculation have mistakes in angle to close to 90 degree. # And is created two rays with different in coordinates on machine epsilon if all(i == 0 for i in a_b): reflect_brightness, refract_brightness = calc_norm_brightness( n1, n2) refract_ray.bright = refract_brightness * fall_ray.bright reflect_ray.bright = reflect_brightness * fall_ray.bright return a_plus_b = a_b[0] + a_b[1] a_minus_b = a_b[0] - a_b[1] sqr_sin_a_p_b = np.sin(a_plus_b)**2 if type_polarisation == 's': reflect_brightness = np.sin(a_minus_b)**2 / sqr_sin_a_p_b refract_brightness = 1 - reflect_brightness if type_polarisation == 'p': reflect_brightness = np.tan(a_minus_b)**2 / np.tan(a_plus_b)**2 refract_brightness = np.sin(2 * a_b[0]) * np.sin( 2 * a_b[1]) / (sqr_sin_a_p_b * np.cos(a_minus_b)**2) reflect_ray.bright = fall_ray.bright * reflect_brightness refract_ray.bright = fall_ray.bright * refract_brightness