Exemplo n.º 1
0
def main():
    R = np.array([[0, 0], [1, 0], [0, 2], [1.5, 2]])

    P = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])

    Q, r, _ = convex_solution(R, P)

    ax: plt.Axes
    fig, ax = plt.subplots()

    R_scat = ax.scatter(*R.T, c="black")
    Q_scat = ax.scatter(*Q.T, c="green")

    vecs = Q - R

    arrows = [
        FancyArrow(0, 0, *vec, color="black", head_width=0.02) for vec in vecs
    ]
    arrows.append(
        FancyArrow(0, 0, *(vecs[0] + vecs[1]), color="green", head_width=0.02))
    for arrow in arrows:
        ax.add_patch(arrow)

    for p in P[2:]:
        tri = Triangle(PlanarTriangle([*P[:2], p]).angles)
        c = tri.trivial_replication_point(*P[:2])
        ax.scatter(*c, color="blue")

    ax.axis("square")
    plt.show()
Exemplo n.º 2
0
def main():
    savedir = thisdir.joinpath("metric_eq")
    eq = Triangle.equilateral()
    dim = (4, 6)
    num = dim[0] * dim[1]
    labels = list(string.ascii_uppercase[:num])
    tris = [Triangle.random() for i in range(num)]
    plot_grid(savedir, tris, dim, labels)

    labels, sorted_tris = zip(*sorted(
        zip(labels, tris), key=lambda x: eq.distance(x[1]), reverse=True))
    labels = [
        f"$\\tau({label}, EQ) = {eq.distance(tri):.2f}$"
        for label, tri in zip(labels, sorted_tris)
    ]
    plot_grid(savedir, sorted_tris, dim, labels)
Exemplo n.º 3
0
def main():
    fig: plt.Figure
    ax: plt.Axes

    speed = 0.05

    R = PlanarTriangle([[0, 0], [1, 0], [0.6, 0.2]])
    P = Triangle.equilateral()  # Triangle([30, 60, 90], deg=True)
    Q = R.min_max_traversal_triangle(P)
    pad = 0.02
    center = np.sum(Q.points, axis=0) / 3

    x_min = np.min([center[0], *R.points[:, 0], *Q.points[:, 0]]) - pad
    x_max = np.max([center[0], *R.points[:, 0], *Q.points[:, 0]]) + pad
    y_min = np.min([center[1], *R.points[:, 1], *Q.points[:, 1]]) - pad
    y_max = np.max([center[1], *R.points[:, 1], *Q.points[:, 1]]) + pad

    savepath = thisdir.joinpath("center")
    for i in range(10):
        with plot(savepath, x_min, x_max, y_min, y_max) as (fig, ax):
            ax.scatter(*center, c="blue")

            _R = PlanarTriangle(R.points + (Q.points - R.points) * i / 9)
            Q.plot(fig, ax, "green")

            ax.scatter(*_R.points.T, c="black")
            ax.scatter(*Q.points.T, c="green")
Exemplo n.º 4
0
def visualize_problem():
    tri = PlanarTriangle([
        [0.2, 0.5],
        [0.4, 0.1],
        [0.6, 0.7],
    ])
    eq = Triangle.equilateral()

    ps = np.array(
        [np.random.random(5) * 0.3 + 0.1,
         np.random.random(5) * 0.3 + 0.1],
        dtype=np.float64).T
    qs = np.array(
        [np.random.random(5) * 0.3 + 0.5,
         np.random.random(5) * 0.3 + 0.1],
        dtype=np.float64).T

    savedir = thisdir.joinpath("visualize_problem")
    savedir.mkdir(exist_ok=True, parents=True)
    for i, (p, q) in enumerate(zip(ps, qs)):
        rep = eq.trivial_replication(p, q)
        fig, ax = plot(tri, rep)
        fig.savefig(str(savedir.joinpath(f"frame_{i}.png")), transparent=True)

    sol = tri.min_max_traversal_triangle(eq)
    fig, ax = plot(tri, sol, "green")
    fig.savefig(str(savedir.joinpath(f"sol.png")), transparent=True)
Exemplo n.º 5
0
def main():
    fig: plt.Figure
    ax: plt.Axes
    alpha, beta = 45, 65
    A = Triangle(np.sort([alpha, beta, 180 - alpha - beta]), deg=True)
    B = Triangle(np.sort([30, 60, 90]), deg=True)
    pad = 0.02

    savepath = thisdir.joinpath("metric")
    plot_tris(A, B, savepath, pad, annotate=False)
    plot_tris(A, B, savepath, pad, annotate=True)

    _A, _B = get_tris(A, B)
    _plot = partial(plot, savepath, 0 - pad, 1 + pad, 0 - pad,
                    max(_A.points[2][1], _B.points[2][1]) + pad)

    # Fix to (0, 0) (1, 0)
    with _plot() as (fig, ax):
        plot_triv(fig, ax, A, B, dist=False)

    # Fix to (0, 0) (1, 0)
    with _plot() as (fig, ax):
        plot_triv(fig, ax, A, B)
Exemplo n.º 6
0
def test_oblivious(speed: float = 0.01):
    eq: Triangle = Triangle.equilateral()
    tri: PlanarTriangle = PlanarTriangle.random()
    dst: PlanarTriangle = tri.min_max_traversal_triangle(eq)
    unit = dst.points - tri.points
    unit /= np.linalg.norm(unit)

    def next_dst() -> PlanarTriangle:
        nonlocal tri, unit, dst
        _dst: PlanarTriangle = tri.min_max_traversal_triangle(eq)
        if not np.isclose(dst.points, _dst.points).all():
            dst = _dst
            unit = dst.points - tri.points
            unit /= np.linalg.norm(unit)
        tri = PlanarTriangle(tri.points + unit * speed)

    fig: plt.Figure
    ax: plt.Axes
    fig, ax = plt.subplots()
    ax.axis("equal")
    ax.set_xlim(-2, 2)
    ax.set_ylim(-2, 2)

    # Initialize
    next_dst()
    tri_scatter = ax.scatter(*dst.points.T)
    dst_scatter = ax.scatter(*tri.points.T, c='green')

    def update_frame(frame):
        next_dst()
        tri_scatter.set_offsets(tri.points)
        dst_scatter.set_offsets(dst.points)

        return tri_scatter, dst_scatter

    ani = FuncAnimation(fig,
                        update_frame,
                        frames=None,
                        blit=True,
                        repeat=False,
                        interval=1,
                        cache_frame_data=False)
    plt.show()
Exemplo n.º 7
0
def main():
    fig: plt.Figure
    ax: plt.Axes

    speed = 0.05

    R = PlanarTriangle([[0, 0], [1, 0], [0.6, 0.2]])
    P = Triangle([30, 60, 90], deg=True)
    Q = R.min_max_traversal_triangle(P)
    pad = 0.02
    focal = seg_intersect(R.points[0], Q.points[0], R.points[1], Q.points[1])

    x_min = np.min([focal[0], *R.points[:, 0], *Q.points[:, 0]]) - pad
    x_max = np.max([focal[0], *R.points[:, 0], *Q.points[:, 0]]) + pad
    y_min = np.min([focal[1], *R.points[:, 1], *Q.points[:, 1]]) - pad
    y_max = np.max([focal[1], *R.points[:, 1], *Q.points[:, 1]]) + pad

    savepath = thisdir.joinpath("focal")
    for i in range(10):
        with plot(savepath, x_min, x_max, y_min, y_max) as (fig, ax):
            ax.scatter(*focal, c="blue")

            _R = PlanarTriangle(R.points + (Q.points - R.points) * i / 9)
            Q.plot(fig, ax, "green")

            ax.add_collection(
                LineCollection([[Q.points[2], focal]],
                               linestyles="--",
                               colors="black"))
            ax.add_collection(
                LineCollection([[R.points[0], focal], [R.points[1], focal]],
                               linestyles="--",
                               colors="black"))

            ax.scatter(*_R.points.T, c="black")
            ax.scatter(*Q.points.T, c="green")
Exemplo n.º 8
0
def get_triv(A: Triangle,
             B: Triangle) -> Tuple[PlanarTriangle, PlanarTriangle]:
    _A = A.trivial_replication([0, 0], [1, 0])
    _B = B.trivial_replication([0, 0], [1, 0])
    return _A, _B
Exemplo n.º 9
0
def get_tris(A: Triangle,
             B: Triangle) -> Tuple[PlanarTriangle, PlanarTriangle]:
    _A = A.trivial_replication([0, 0.2], [1, 0])
    _B = B.trivial_replication([1.2, .1], [2.2, .5])
    return _A, _B
Exemplo n.º 10
0
def get_triv(R: PlanarTriangle, P: Triangle, i: int) -> PlanarTriangle:
    j, k = (i + 1) % 3, (i + 2) % 3
    return P.roll(-(i + 1)).trivial_replication(R.points[j], R.points[k])
Exemplo n.º 11
0
def main():
    fig: plt.Figure
    ax: plt.Axes

    R = PlanarTriangle([[0, 0], [1, 0], [0.6, 0.6]])
    P = Triangle([30, 60, 90], deg=True)
    Q = R.min_max_traversal_triangle(P)
    p_u, p_v = [1.2, 0.5], [1.6, 0.5]
    pad = 0.02

    r = R.min_max_traversal(P)
    xmins, ymins = [p_u[0] - pad, p_v[0] + pad], [p_u[1] - pad, p_v[1] + pad]
    xmaxs, ymaxs = [p_u[0] - pad, p_v[0] + pad], [p_u[1] - pad, p_v[1] + pad]
    for i in range(3):
        c, r = get_span_circle(R, Triangle(np.sort(P.angles)), i)
        xmins.append(c[0] - r - pad)
        xmaxs.append(c[0] + r + pad)
        ymins.append(c[1] - r - pad)
        ymaxs.append(c[1] + r + pad)

        xmins.append(R.points[i][0] - r - pad)
        xmaxs.append(R.points[i][0] + r + pad)
        ymins.append(R.points[i][1] - r - pad)
        ymaxs.append(R.points[i][1] + r + pad)

    xmin = min(xmins)
    xmax = max(xmaxs)
    ymin = min(ymins)
    ymax = max(ymaxs)

    P_ref = P.trivial_replication(p_u, p_v)
    savepath = thisdir.joinpath("visualize_solution")
    _plot = partial(plot, savepath, xmin, xmax, ymin, ymax)

    # Show robots & Pattern
    with _plot() as (fig, ax):
        plot_base(fig,
                  ax,
                  R,
                  P_ref,
                  annotate_points=False,
                  annotate_sides=True,
                  scale=False)

    _plot_base = partial(plot_base,
                         R=R,
                         P_ref=P_ref,
                         annotate_points=True,
                         annotate_sides=True,
                         scale=True)

    # robots are sorted by angles
    assert ((np.diff(R.angles) >= 0).all())

    # Show robots & Pattern w/ annotations
    with _plot() as (fig, ax):
        _plot_base(fig, ax)

    # get correct assignment
    P = Triangle(np.sort(P.angles))

    # Show robots & Pattern with annotations
    for i in range(3):
        with _plot() as (fig, ax):
            _plot_base(fig, ax)
            plot_triv(fig, ax, R, P, i)
            plot_arrow(fig, ax, R, P, i, scale=False)
            plot_sol_points(fig, ax, R, P, list(range(i)))

        with _plot() as (fig, ax):
            _plot_base(fig, ax)
            plot_triv(fig, ax, R, P, i)
            plot_arrow(fig, ax, R, P, i, scale=True)
            plot_sol_points(fig, ax, R, P, list(range(i + 1)))

    with _plot() as (fig, ax):
        _plot_base(fig, ax)
        plot_sol_points(fig, ax, R, P, list(range(i + 1)))
        for i in range(3):
            plot_arrow(fig, ax, R, P, i, scale=True)
        plot_sol(fig, ax, R, P)

    # Show radius circles
    with _plot() as (fig, ax):
        _plot_base(fig, ax)
        plot_sol_points(fig, ax, R, P, list(range(3)))
        plot_sol(fig, ax, R, P)
        for i in range(3):
            plot_radius_circle(fig, ax, R, P, i)

    # Show spanner circles
    for i in range(3):
        with _plot() as (fig, ax):
            _plot_base(fig, ax)
            plot_sol_points(fig, ax, R, P, list(range(3)))
            plot_sol(fig, ax, R, P)

            plot_triv(fig, ax, R, P, i, annotate=True)
            plot_span_circle(fig, ax, R, P, i)
            for j in range(3):
                plot_radius_circle(fig, ax, R, P, j)
Exemplo n.º 12
0
def get_span_circle(R: PlanarTriangle, P: Triangle,
                    i: int) -> Tuple[np.ndarray, float]:
    j, k = (i + 1) % 3, (i + 2) % 3
    r = R.min_max_traversal(P)
    return P.roll(-(i + 1)).replication_spanner_circle(R.points[j],
                                                       R.points[k], r)
Exemplo n.º 13
0
def visualize_replications(mode: str, savepath: str) -> None:
    alpha, beta = 37, 52
    tri = Triangle([alpha, beta, 180 - alpha - beta], deg=True)
    anchors, radius = ([0, 0], [1, 0]), 0.1
    trivial = tri.trivial_replication(*anchors)
    if mode == "machine":
        rep_center, rep_radius = tri.replication_machine_circle(
            *anchors, radius)
        reps = tri.replication_machine(*anchors, radius, num=15)
    else:
        rep_center, rep_radius = tri.replication_spanner_circle(
            *anchors, radius)
        reps = tri.replication_spanner(*anchors, radius, num=10)

    savepath = pathlib.Path(savepath).resolve().with_suffix("")
    savepath.mkdir(parents=True)
    for i, rep in enumerate(reps[:-1]):
        # set up figure
        fig: plt.Figure
        ax: plt.Axes
        fig, ax = plt.subplots()
        ax.axis("square")
        pad = 0.01
        ax.set_xlim(0 - radius - pad, 1 + radius + pad)
        ax.set_ylim(0 - radius - pad, trivial.points[2][1] + rep_radius + pad)

        # ax.scatter(*(rep.points.T), c="blue")
        rep.plot(fig, ax, color="black")  # plot replication
        trivial.plot(fig, ax)

        ax.scatter(*(trivial.points.T), c="black")
        if mode == "spanner":
            ax.add_patch(Circle([0, 0], radius, color="black", fill=None))
        ax.add_patch(Circle([1, 0], radius, color="black", fill=None))
        ax.add_patch(
            Circle(rep_center,
                   rep_radius,
                   color="blue",
                   fill=None,
                   linestyle="--"))

        ax.annotate("$u$", trivial.points[0] - 0.03)
        ax.annotate("$v$", trivial.points[1] + 0.01)
        ax.annotate("$c$", trivial.points[2] + 0.015)

        lines = [[
            trivial.points[1], trivial.points[1] - np.array([0, radius])
        ]]
        if mode == "spanner":
            lines.append(
                [trivial.points[0], trivial.points[0] - np.array([0, radius])])

        ax.add_collection(LineCollection(lines, color="black",
                                         linestyles="--"))
        loc = np.array(
            [lines[0][0][0] + 0.01, (lines[0][0][1] + lines[0][1][1]) / 2])
        ax.annotate("r", loc)

        plt.axis("off")
        plt.tight_layout()
        fig.savefig(str(savepath.joinpath(f"frame-{i}.png")),
                    transparent=True,
                    bbox_inches="tight",
                    dpi=240)
        plt.close(fig)