mirror of
https://github.com/Xevion/visuals.git
synced 2025-12-06 01:16:57 -06:00
123 lines
4.3 KiB
Python
123 lines
4.3 KiB
Python
from typing import List
|
|
|
|
from manim import *
|
|
from palettable.matplotlib import Inferno_20
|
|
|
|
|
|
class BubbleSort(Scene):
|
|
"""
|
|
A animation of Bubble Sort sorting algorithm.
|
|
|
|
Very simple, a arrangement of boxes containing singular digits within them, slowly swapping values until
|
|
the array is sorted in increasing order.
|
|
"""
|
|
|
|
def __init__(self, *args, **kwargs, ):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.array = [3, 8, 3, 6, 6, 4, 1, 4, 8, 4, 2, 7, 9, 8, 6, 8]
|
|
self.squares: List[VGroup] = []
|
|
self.entire = VGroup()
|
|
self.size_multiplier = (14 - 1.5) / len(self.array)
|
|
self.arrow_cur = 0
|
|
self.arrow_shown = False
|
|
|
|
def construct(self):
|
|
"""Main method."""
|
|
|
|
self.assemble()
|
|
self.add(self.entire)
|
|
self.entire.to_edge(LEFT, buff=0.75)
|
|
|
|
running = True
|
|
while running:
|
|
running = self.tick()
|
|
|
|
def assemble(self):
|
|
"""Assemble all animation elements"""
|
|
max_value = max(self.array)
|
|
min_value = min(self.array)
|
|
for i, value in enumerate(self.array):
|
|
square = VGroup()
|
|
value_interpolation = (value - min_value) / (max_value - min_value)
|
|
# color = colour.Color(hsl=(, 1, 0.5)).get_hex_l()
|
|
colors = Inferno_20.hex_colors
|
|
stroke = Square(stroke_color=colors[int(value_interpolation * (len(colors) - 1 - 3)) + 3],
|
|
stroke_width=8 * self.size_multiplier, fill_opacity=0, stroke_opacity=1,
|
|
side_length=self.size_multiplier)
|
|
digit = Text(str(value), size=1.3 * self.size_multiplier)
|
|
|
|
square.add(stroke, digit)
|
|
square.shift(RIGHT * self.size_multiplier * i)
|
|
|
|
self.entire.add(square)
|
|
self.squares.append(square)
|
|
|
|
bottom = self.squares[0].get_bottom()
|
|
self.arrow = Arrow(bottom + DOWN * self.size_multiplier, bottom, buff=0, fill_opacity=0)
|
|
self.entire.add(self.arrow)
|
|
|
|
def tick(self) -> bool:
|
|
"""
|
|
Animates a single tick of the Bubble Sort sorting algorithm, swapping one value with another at most.
|
|
|
|
:return: True if anything was swapped, otherwise False.
|
|
"""
|
|
for i in range(len(self.array) - 1):
|
|
if not self.arrow_shown and i == 0:
|
|
self.move_arrow(i, time=0)
|
|
self.show_arrow(True)
|
|
if self.array[i] > self.array[i + 1]:
|
|
self.move_arrow(i + 0.5, time=0.10 * i)
|
|
self.swap(i, i + 1)
|
|
self.show_arrow(False)
|
|
self.wait(0.2)
|
|
self.array[i], self.array[i + 1] = self.array[i + 1], self.array[i]
|
|
self.squares[i], self.squares[i + 1] = self.squares[i + 1], self.squares[i]
|
|
return True
|
|
|
|
return False
|
|
|
|
def move_arrow(self, i, time: float = 0.15) -> None:
|
|
"""Move the arrow to a specific position around the array."""
|
|
shift = RIGHT * (i - self.arrow_cur) * self.size_multiplier
|
|
if time == 0:
|
|
self.arrow.shift(shift)
|
|
else:
|
|
self.play(self.arrow.animate.shift(shift), run_time=time, rate_func=rate_functions.ease_in_out_sine)
|
|
self.arrow_cur = i
|
|
|
|
def show_arrow(self, val: bool = True) -> None:
|
|
"""Show or hide the arrow via it's opacity."""
|
|
self.play(
|
|
self.arrow.animate.set_opacity(1 if val else 0),
|
|
run_time=0.05
|
|
)
|
|
|
|
def swap(self, x: int, y: int) -> None:
|
|
"""Swaps two positions in the array with each other."""
|
|
dir = x < y
|
|
diff = abs(x - y) * self.size_multiplier
|
|
self.play(
|
|
self.squares[x].animate.shift(UP * self.size_multiplier * 1.1),
|
|
self.squares[y].animate.shift(DOWN * self.size_multiplier * 1.1),
|
|
run_time=0.12
|
|
)
|
|
|
|
self.play(
|
|
self.squares[x].animate.shift((RIGHT if dir else LEFT) * diff),
|
|
self.squares[y].animate.shift((LEFT if dir else RIGHT) * diff),
|
|
run_time=0.2
|
|
)
|
|
|
|
self.play(
|
|
self.squares[x].animate.shift(DOWN * self.size_multiplier * 1.1),
|
|
self.squares[y].animate.shift(UP * self.size_multiplier * 1.1),
|
|
run_time=0.12
|
|
)
|
|
pass
|
|
|
|
def change_digit(self, pos: int, val: int) -> None:
|
|
"""Change the digit present at a specific position in the array."""
|
|
pass
|