示例#1
0
def random_positions(plot_radius: bool = False):
    fig: plt.Figure
    ax: plt.Axes
    fig, ax = plt.subplots()
    plt.subplots_adjust(bottom=0.25)
    ax.axis('equal')
    
    axslider = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    axbutton = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    bnew = Button(axbutton, 'New')
    num_slider = Slider(axslider, 'Robots', 3, 7, valinit=3, valstep=1)

    # Initalize
    formation = regular_shape(int(num_slider.val))
    positions = random_shape(len(formation))
    target, radius = approximation(positions, formation)

    colors = get_colors(len(formation))
    arr = np.arange(positions.shape[0])
    srcs = ax.scatter(positions[:,0], positions[:,1], marker='o', color=colors)
    dsts = ax.scatter(target[:,0], target[:,1], marker='x', color=colors)

    def get_circles(positions: np.array, radius: float) -> List[plt.Circle]:
        return [plt.Circle(position, radius) for position in positions]

    circles = PatchCollection(get_circles(positions, radius), alpha=0.4)
    circles.set_color(colors)
    ax.add_collection(circles)

    def update(event):
        formation = regular_shape(int(num_slider.val))
        positions = random_shape(len(formation))
        target, radius = approximation(positions, formation)
        srcs.set_offsets(positions)
        dsts.set_offsets(target)
        circles.set_paths(get_circles(positions, radius))

        colors = get_colors(positions.shape[0])
        srcs.set_color(colors)
        dsts.set_color(colors)
        circles.set_color(colors)

        # Set Axis Scale
        points = np.concatenate([positions, target])
        llim, hlim = points.min() - radius, points.max() + radius
        ax.set_xlim(llim, hlim)
        ax.set_ylim(llim, hlim)
        ax.autoscale_view()
        fig.canvas.draw_idle()

    bnew.on_clicked(update)
    num_slider.on_changed(update)

    ax.autoscale_view()
    plt.show()
示例#2
0
    def new_positions(val=None):
        nonlocal positions, formation
        positions = random_shape(number)
        formation = regular_shape(number)
        scatter_positions.set_offsets(positions)

        # Set Axis Scale
        points = np.concatenate([positions, formation])
        llim, hlim = points.min() - 1, points.max() + 1
        ax.set_xlim(llim, hlim)
        ax.set_ylim(llim, hlim)
        ax.autoscale_view()

        update()
示例#3
0
def test_four_circles():
    """Tests the conjecture that at most four must travel the solution"""
    pos = random_shape(4, 0.0, 1.0)
    shp = random_shape(4, 0.0, 1.0)
    shp = regular_shape(4)

    rep, radiuses = replication_spanner_circles(shp, pos[0], pos[1], 0.1)

    ax: plt.Axes
    fig, ax = plt.subplots()
    ax.set_aspect('equal', 'box')
    ax.scatter(*zip(*pos), color='black')
    ax.scatter(*zip(*rep), color='blue')

    patches = [plt.Circle(c, radius) for c, radius in zip(rep[2:], radiuses[2:])]
    ax.add_collection(PatchCollection(patches, alpha=0.4))

    plt.show()
示例#4
0
    def update(event):
        formation = regular_shape(int(num_slider.val))
        positions = random_shape(len(formation))
        target, radius = approximation(positions, formation)
        srcs.set_offsets(positions)
        dsts.set_offsets(target)
        circles.set_paths(get_circles(positions, radius))

        colors = get_colors(positions.shape[0])
        srcs.set_color(colors)
        dsts.set_color(colors)
        circles.set_color(colors)

        # Set Axis Scale
        points = np.concatenate([positions, target])
        llim, hlim = points.min() - radius, points.max() + radius
        ax.set_xlim(llim, hlim)
        ax.set_ylim(llim, hlim)
        ax.autoscale_view()
        fig.canvas.draw_idle()
示例#5
0
def test_same_solution(positions: Optional[np.array] = None,
                       formation: Optional[np.array] = None,
                       speed: float = 0.002):
    if positions is None:
        positions = random_shape(3)
        print(positions)
    if formation is None:
        formation = regular_shape(3)

    fig: plt.Figure
    ax: plt.Axes
    fig, ax = plt.subplots()
    plt.subplots_adjust(bottom=0.25)
    ax.axis('equal')
    
    axslider = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    axbutton = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    bnew = Button(axbutton, 'New')
    speed_slider = Slider(axslider, 'Speed', 0, 0.05, valinit=speed)

    # Intial computation
    target, radius = triangle_solution(positions, formation)
    directions = (target - positions) / np.linalg.norm(target -
                                                       positions, axis=1)[:, np.newaxis] * speed
    focuses = []
    focus = get_intersect(positions[0], target[0], positions[1], target[1])
    focuses.append(focus)

    # Create scatter plots
    pos_scatter = ax.scatter(positions[:, 0], positions[:, 1], c='red')
    tar_scatter = ax.scatter(target[:, 0], target[:, 1], c='blue')
    foc_scatter = ax.scatter([focus[0]], [focus[1]], c='green')

    def init():
        ax.set_xlim(-2, 2)
        ax.set_ylim(-2, 2)
        return pos_scatter, tar_scatter, foc_scatter

    def new_positions(event):
        nonlocal positions, focuses, target
        positions = random_shape(3)
        target, radius = triangle_solution(positions, formation)
        focus = get_intersect(positions[0], target[0], positions[1], target[1])
        focuses = [focus]

    bnew.on_clicked(new_positions)

    def new_speed(event):
        nonlocal speed, directions
        speed = speed_slider.val
        directions = np.linalg.norm(directions, axis=0) * speed


    speed_slider.on_changed(new_speed)

    def update(frame):  # Gets called for every frame in animation
        nonlocal target, positions, directions, speed
        _target, _ = triangle_solution(positions, formation)

        # switch direction only when a new target is found
        if not np.allclose(_target, target):
            target = _target
            directions = (target - positions) / np.linalg.norm(target - positions, axis=1)[:, np.newaxis] * speed

            focus = get_intersect(positions[0], target[0], positions[1], target[1])
            # foc_scatter.set_offsets([focus])
            focuses.append(focus)
            foc_scatter.set_offsets(focuses)

        positions += directions
        pos_scatter.set_offsets(positions)
        tar_scatter.set_offsets(target)

        return pos_scatter, tar_scatter, foc_scatter

    ani = FuncAnimation(fig, update, frames=None,
                        init_func=init, blit=True, repeat=False, interval=1, cache_frame_data=False)
    plt.show()
示例#6
0
def test_replications(
        formation: Optional[np.array] = None,
        radius_range: Tuple[float, float] = (0.0, 0.5)) -> None:
    fig, ax = plt.subplots()
    plt.subplots_adjust(bottom=0.3)
    ax.axis('equal')

    number = 3
    positions = random_shape(number)
    if not formation:
        formation = regular_shape(number)


    init_radius = radius_range[1]
    ax_radius = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    ax_button = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    ax_number = plt.axes([0.25, 0.2, 0.65, 0.03], facecolor='lightgoldenrodyellow')
    num_slider = Slider(ax_number, 'Robots', 3, 7, valinit=3, valstep=1)
    s_radius = Slider(ax_radius, 'Radius', *radius_range, valinit=init_radius)
    b_random = Button(ax_button, 'New')
    scatter_positions = ax.scatter(x=positions[:, 0], y=positions[:, 1], color='black')


    def get_shapes(radius):
        c_positions = list(combinations(range(len(positions)), 2))
        c_formations = list(combinations(range(len(formation)), 2))
        combs = list(product(c_positions, c_formations))
        patches = []
        colors = get_colors(len(combs))
        for color, ((i_pos1, i_pos2), (i_for1, i_for2) )in zip(colors, combs):
            repl, radiuses = replication_spanner_circles(
                formation,
                positions[i_pos1], positions[i_pos2],
                radius,
                *sorted([i_for1, i_for2])
            )

            patches.append(plt.Polygon(repl, color=color, fill=False))
            for i, _radius in enumerate(radiuses):
                # if i in (i_pos1, i_pos2):
                #     continue
                patches.append(plt.Circle(repl[i], _radius, color=color, fill=False))

        for position in positions:
            patches.append(plt.Circle(position, radius, color='black', fill=False))

        return patches

    collection = PatchCollection(get_shapes(init_radius), match_original=True)
    ax.add_collection(collection)

    def update(val=None):
        collection.set_paths(get_shapes(s_radius.val))
        # collection.set_edgecolor(get_colors(len(positions) * (len(positions) - 1)))
        # collection.set_array(np.array(list(range(len(positions)))))
        
        fig.canvas.draw_idle()

    def new_positions(val=None):
        nonlocal positions, formation
        positions = random_shape(number)
        formation = regular_shape(number)
        scatter_positions.set_offsets(positions)

        # Set Axis Scale
        points = np.concatenate([positions, formation])
        llim, hlim = points.min() - 1, points.max() + 1
        ax.set_xlim(llim, hlim)
        ax.set_ylim(llim, hlim)
        ax.autoscale_view()

        update()

    def update_number(val=None):
        nonlocal number
        number = int(num_slider.val)
        new_positions()

    s_radius.on_changed(update)
    b_random.on_clicked(new_positions)
    num_slider.on_changed(update_number)

    ax.autoscale_view()
    plt.show()