def collect_point_to_draw( e: (list, iter), r: (list, iter), t0: float, t1: float): begin = ARay.calc_point_of_ray_(e, r, t0) end = ARay.calc_point_of_ray_(e, r, t1) x_coor = [begin[0], end[0]] y_coor = [begin[1], end[1]] return (x_coor, y_coor)
def aray_typing_test(): e = [1, 0, 0] r = [2.3, 12, 3] p = Plane([3, 0, 0], [1, 0, 0]) args = ARay.reflect_(e, r, p) print(f"ray: \ne = {e},\nr = {r}") print(f"{p}") print(f"{args}")
def reflect(self, surface: Surface): if self.__dim != surface.dim: raise AttributeError( "Different dimension of ray(%d) and of surface(%d)" % (self.__dim, surface.dim)) point, e, t_1 = ARay.reflect_(e=self.dir, r=self.start, surface=surface) if len(point) == 0 or len(e) == 0 or t_1 is None: return None self.t1 = t_1 return Ray(point, e)
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 ray_surface_intersection(self, e: [List[Union[float, int]], np.ndarray], r: [List[Union[float, int]], np.ndarray]) \ -> List[Union[float, int]]: # get lenghts of ray for plne and cone plane_t = self.plane.ray_surface_intersection(e, r) cone_t = self.lim_cone.ray_surface_intersection(e, r) # is point of intersection on base of axicon. Base of axicon is a infinity plane. if len(plane_t) > 0: point = ARay.calc_point_of_ray_(e, r, plane_t[0]) if not self.is_point_on_base(point): plane_t = [] cone_t.extend(plane_t) cone_t.sort() return cone_t
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 generate_rays_2d(point1: (list, tuple), point2: (list, tuple), intensity: float) -> VecRayPool: if len(point1) != 2 or len(point2) != 2: raise AttributeError("Point dimension is not 2. point1: " + str(point1) + " point2: " + str(point2)) if (not all(isinstance(coor, (float, int)) for coor in point1)) or \ (not all(isinstance(coor, (float, int)) for coor in point2)): raise AttributeError( "Lists of point1 or list of point2 not contained type float or int" ) if intensity < np.finfo(float).eps: raise AttributeError("Negative intensity (%f)".format(intensity)) vec = np.subtract(point2, point1) norm = np.linalg.norm(vec) # нормировка вектора для вычисления начал координат лучей vec = list(np.divide(vec, norm)) pre_count = norm * intensity count = int(pre_count) # для равномерного распеределения в середине vec_t0 = (pre_count - count) / 2 step = (norm - 2 * vec_t0) / (count - 1) m_rot = [[0, 1], [-1, 0]] vec_e = np.dot(m_rot, vec) e_norm = np.linalg.norm(vec_e) # нормировка вектора направления vec_e = list(np.divide(vec_e, e_norm)) arr_ray_pool = [] # создаем бассейн с размерностью лучей 2(плоскость, а не пространство) # оставляем место для ячеек, куда мы не можем положить информацию. Заполняем только e и r remain_len = Compon2D.RAY_OFFSET - (2 * Compon2D.DIM.value + 2) empty_list = [None for i in range(remain_len)] for i in range(count): vec_r = ARay.calc_point_of_ray_(vec, point1, vec_t0 + i * step) arr_ray_pool.extend(vec_e) arr_ray_pool.extend(vec_r) arr_ray_pool.append(0) arr_ray_pool.append(None) arr_ray_pool.extend(empty_list) return VecRayPool(arr_ray_pool, Compon2D)
def model_path(ray: Ray, surfaces: list, is_return_ray_list: bool = False, is_have_ray_in_infinity: bool = False, length_last_ray: float = 1): way_point_of_ray = [] ray_list = [ray] new_ray = ray temp = None while True: min_p = float(np.finfo(float).max) # index of nearest surface and intersection point # ищем ближайшую поверхность index, i_point = -1, None index, i_point = _not_sequence_modeling(new_ray, surfaces) print(i_point) if i_point is None: break # print("Surf " + str(surfaces[index])) if surfaces[index].type == Surface.types.REFLECTING: temp = new_ray.reflect(surfaces[index]) elif surfaces[index].type == Surface.types.REFRACTING: temp = new_ray.refract(surfaces[index]) print(temp) _append_point_to_path(new_ray, way_point_of_ray, temp.start) # print(new_ray,temp,'\n') if is_return_ray_list: ray_list.append(temp) new_ray = temp if is_have_ray_in_infinity: _append_point_to_path( new_ray, way_point_of_ray, ARay.calc_point_of_ray_(new_ray.dir, new_ray.start, length_last_ray)) if is_return_ray_list: return way_point_of_ray, ray_list return way_point_of_ray
def calc_point_of_ray(self, i: int, t: float) -> list: return ARay.calc_point_of_ray_(self.e(i), self.r(i), t - self.t0(i))
def calc_point_of_ray(self, t: float) -> list: if not t > 10 * np.finfo(float).eps: return [] return ARay.calc_point_of_ray_(self.dir, self.start, t)