Beispiel #1
0
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
Beispiel #3
0
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
Beispiel #4
0
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)))
Beispiel #6
0
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
Beispiel #7
0
 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])
Beispiel #8
0
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