def find_tangent(LC_s, LC_t): """ Given a source and target lighthouse center with radius 1, find the tangent. This is done by first finding the angle between LC_t, LC_s, tang and then calculating the tang itself via rotation. """ return rotate(LC_s, LC_t, np.arcsin(1 / dist_2d(LC_s, LC_t)))
def compute_darkness(N, print_res=True): if N == 1: DA = 0 elif N == 2: DA = inf else: placement_center = (0.0, 0.0) centers = find_lighthouse_centers(N, placement_center) lighthouses = [] for c in centers: left, mid, right = find_lighthouse_illum_points( N, c, placement_center) lighthouses.append({ "center": c, "left": left, "middle": mid, "right": right }) source, tang, _ = get_first_illumination_line(lighthouses) # We can find the dark area coeff = np.polyfit( [tang[0], source[0]], [tang[1], source[1]], 1) # finds the coefficients of y = ax + b for points x, y. target_cross_x = -coeff[1] / coeff[ 0] # we look for 0 = ax' + b --> x = -b/a x = dist_2d( (target_cross_x, 0.0), tang) # this is the nugget, we can find the dark area from this. DA = N * (x - np.arctan(x)) # Theorem 4.3 if print_res: print("D(" + str(N) + ") by Calculation:", DA) return DA
def flat_locus(atlas, x0, y0, r, z): for i, point in enumerate(atlas.points): dz = 0 n = util.dist_2d(x0, y0, point[0], point[1]) if (n <= r): dz = z atlas.elevs[i] += dz
def bounded_quad(atlas, x0, y0, zmin, zmax, a, b, c): for i, point in enumerate(atlas.points): n = util.dist_2d(x0, y0, point[0], point[1]) dz = a * n**2 + b * n + c dz = max(zmin, dz) dz = min(zmax, dz) atlas.elevs[i] += dz
def find_tangent(LL_s, LC_t): """ Given a source point and target lighthouse center with radius 1, find the tangent. This is done by first finding the angle between LC_t, LL_s, tang and then calculating the tang itself via rotation. LL is "Lighthouse->Left". It is possible that the angle between the supposed """ return rotate(LL_s, LC_t, np.arcsin(1 / dist_2d(LL_s, LC_t)))
def rand_bounded_quad(atlas, zmin, zmax, a, b, c): x0 = randrange(0, atlas.width) y0 = randrange(0, atlas.height) for i, point in enumerate(atlas.points): n = util.dist_2d(x0, y0, point[0], point[1]) dz = a * n**2 + b * n + c dz = max(zmin, dz) dz = min(zmax, dz) atlas.elevs[i] += dz
def dist_2d(self, idx1, idx2): p1 = self.points[idx1] p2 = self.points[idx2] return util.dist_2d(p1[0], p1[1], p2[0], p2[1])
def draw_all(N): ''' Draw all lines until a match. ''' placement_center = (0.0, 0.0) centers = find_lighthouse_centers(N, placement_center) lighthouses = [] for c in centers: left, mid, right = find_lighthouse_illum_points(N, c, placement_center) lighthouses.append({ "center": c, "left": left, "middle": mid, "right": right }) # plots fig = plt.figure() ax = plt.axes() ax.scatter(placement_center[0], placement_center[1], color="red") for l in lighthouses: ax.add_patch(plt.Circle(l['center'], 1.0, color='black', fill=False)) ax.scatter(l['center'][0], l['center'][1], color="yellow") ax.scatter(l['left'][0], l['left'][1], color="gray") ax.scatter(l['right'][0], l['right'][1], color="gray") ax.scatter(l['middle'][0], l['middle'][1], color="gray") ax.add_line( Line2D([l['center'][0], placement_center[0]], [l['center'][1], placement_center[1]], linestyle='--', color='gray', linewidth=0.4)) ax.add_line( Line2D([l['center'][0], l['left'][0]], [l['center'][1], l['left'][1]], color='gray', linewidth=0.5)) ax.add_line( Line2D([l['center'][0], l['right'][0]], [l['center'][1], l['right'][1]], color='gray', linewidth=0.5)) plt.xlim([-N - 1.5, N + 1.5]) plt.ylim([-N - 1.5, N + 1.5]) if N == 1: DA = 0 else: target = lighthouses[0] for source in lighthouses[1:int(len(lighthouses) / 2) + 1]: isValid, tang, line = get_illumination_line( source['center'], target['center'], placement_center, len(lighthouses)) ax.add_line(line) if isValid: ax.scatter(source['center'][0], source['center'][1], color="green") ax.scatter(tang[0], tang[1], color="green") break else: ax.scatter(source['center'][0], source['center'][1], color="red") ax.scatter(tang[0], tang[1], color="red") if source['center'][1] <= tang[1]: # The dark area is infinite DA = inf else: # We can find the dark area coeff = np.polyfit( [tang[0], source['center'][0]], [tang[1], source['center'][1]], 1) # finds the coefficients of y = ax + b for points x, y. target_cross_x = -coeff[1] / coeff[ 0] # we look for 0 = ax' + b --> x = -b/a ax.scatter(target_cross_x, 0.0, color="orange") ax.add_line( Line2D([tang[0], target_cross_x], [tang[1], 0.0], color='gray', linewidth=0.5)) ax.add_line( Line2D([lighthouses[0]['center'][0], target_cross_x], [lighthouses[0]['center'][1], 0.0], color='gray', linewidth=0.5)) x = dist_2d( (target_cross_x, 0.0), tang ) # this is the nugget, we can find the dark area from this. DA = N * (x - np.arctan(x)) # Theorem 4.3 plt.xlim([-N - 1.5, target_cross_x + 1.5]) DA_theorem = theorem_4_3_formula(N) print("D(" + str(N) + ") by Calculation:", DA) print("D(" + str(N) + ") by Theorem:", DA_theorem) ax.set_title(str(N) + " lighthouses") plt.show() return DA, DA_theorem