def attenuation_length(self, start, end): """ Calculate attenuation length for geometry. Can account for starting and ending in any position. """ intercepts, indexes = self.get_intersecting_segments(start, end) if len(intercepts) == 0: ray_intercepts, ray_indexes = self.get_intersecting_segments(start, end, ray=True) if len(ray_intercepts) == 0: return np.linalg.norm(start - end) * self.universe_material.attenuation distances = np.linalg.norm(np.add(ray_intercepts, -start), axis=1) distances_argmin = np.argmin(distances) closest_index = ray_indexes[distances_argmin] closest_intercept = ray_intercepts[distances_argmin] closest_normal = math2d.normal(self.geometry.mesh.segments[closest_index]) start_sign = np.sign(np.dot(start - closest_intercept, closest_normal)) if start_sign > 0: outer_atten = self.geometry.outer_materials[closest_index].attenuation atten_length = np.linalg.norm(start - end) * outer_atten else: inner_atten = self.geometry.inner_materials[closest_index].attenuation atten_length = np.linalg.norm(start - end) * inner_atten return atten_length distances = np.linalg.norm(np.add(intercepts, -start), axis=1) distances_argmin = np.argmin(distances) closest_index = indexes[distances_argmin] closest_intercept = intercepts[distances_argmin] closest_normal = math2d.normal(self.geometry.mesh.segments[closest_index]) start_sign = np.sign(np.dot(start - closest_intercept, closest_normal)) if start_sign > 0: outer_atten = self.geometry.outer_materials[closest_index].attenuation atten_length = np.linalg.norm(start - end) * outer_atten else: inner_atten = self.geometry.inner_materials[closest_index].attenuation atten_length = np.linalg.norm(start - end) * inner_atten for intercept, index in zip(intercepts, indexes): normal = math2d.normal(self.geometry.mesh.segments[index]) start_sign = np.sign(np.dot(start - intercept, normal)) end_sign = np.sign(np.dot(end - intercept, normal)) inner_atten = self.geometry.inner_materials[index].attenuation outer_atten = self.geometry.outer_materials[index].attenuation atten_length += start_sign * np.linalg.norm(intercept - end) * (inner_atten - outer_atten) return atten_length
def draw(self, show_normal=False, color='green'): for i, segment in enumerate(self.segments): plt.plot(segment[:, 0], segment[:, 1], color=color) if show_normal: normal = math2d.normal(segment) center = math2d.center(segment) plt.arrow(center[0], center[1], normal[0], normal[1], width=0.01, color=color)
def draw(self, draw_normals=False): #segments = continuous_path_order(self.mesh.segments) segments = self.mesh.segments xs = np.ravel(segments[:, :, 0]) ys = np.ravel(segments[:, :, 1]) plt.fill(xs, ys, color=self.color) if draw_normals: for segment in segments: normal = math2d.normal(segment) center = math2d.center(segment) plt.arrow(center[0], center[1], normal[0], normal[1], width=0.01, color=self.color)
def attenuation_length(self, start, end): """ Calculate attenuation length for geometry. Can account for starting and ending in any position. """ intercepts, indexes = self.get_intersecting_segments(start, end) if len(intercepts) == 0: ray_intercepts, ray_indexes = self.get_intersecting_segments( start, end, ray=True) if len(ray_intercepts) == 0: return np.linalg.norm(start - end) * self.universe_material.attenuation distances = np.linalg.norm(np.add(ray_intercepts, -start), axis=1) distances_argmin = np.argmin(distances) closest_index = ray_indexes[distances_argmin] closest_intercept = ray_intercepts[distances_argmin] closest_normal = math2d.normal( self.geometry.mesh.segments[closest_index]) start_sign = np.sign( np.dot(start - closest_intercept, closest_normal)) if start_sign > 0: outer_atten = self.geometry.outer_materials[ closest_index].attenuation atten_length = np.linalg.norm(start - end) * outer_atten else: inner_atten = self.geometry.inner_materials[ closest_index].attenuation atten_length = np.linalg.norm(start - end) * inner_atten return atten_length distances = np.linalg.norm(np.add(intercepts, -start), axis=1) distances_argmin = np.argmin(distances) closest_index = indexes[distances_argmin] closest_intercept = intercepts[distances_argmin] closest_normal = math2d.normal( self.geometry.mesh.segments[closest_index]) start_sign = np.sign(np.dot(start - closest_intercept, closest_normal)) if start_sign > 0: outer_atten = self.geometry.outer_materials[ closest_index].attenuation atten_length = np.linalg.norm(start - end) * outer_atten else: inner_atten = self.geometry.inner_materials[ closest_index].attenuation atten_length = np.linalg.norm(start - end) * inner_atten for intercept, index in zip(intercepts, indexes): normal = math2d.normal(self.geometry.mesh.segments[index]) start_sign = np.sign(np.dot(start - intercept, normal)) end_sign = np.sign(np.dot(end - intercept, normal)) inner_atten = self.geometry.inner_materials[index].attenuation outer_atten = self.geometry.outer_materials[index].attenuation atten_length += start_sign * np.linalg.norm(intercept - end) * ( inner_atten - outer_atten) return atten_length