1 | use glam::{DVec3, dvec2};
|
2 | use rand::{SeedableRng, seq::SliceRandom};
|
3 | use ranim::{
|
4 | animation::transform::TransformAnimSchedule, color::palettes::manim, components::Anchor,
|
5 | items::vitem::Rectangle, prelude::*, timeline::TimeMark, utils::rate_functions::linear,
|
6 | };
|
7 |
|
8 | #[scene]
|
9 | struct SelectiveSortScene(pub usize);
|
10 |
|
11 | impl TimelineConstructor for SelectiveSortScene {
|
12 | fn construct(self, timeline: &RanimTimeline, _camera: &mut Rabject<CameraFrame>) {
|
13 | let num = self.0;
|
14 |
|
15 | let frame_size = dvec2(8.0 * 16.0 / 9.0, 8.0);
|
16 | let padded_frame_size = frame_size * 0.9;
|
17 |
|
18 | let anim_step_duration = 15.0 / num.pow(2) as f64;
|
19 |
|
20 | let width_unit = padded_frame_size.x / num as f64;
|
21 | let height_unit = padded_frame_size.y / num as f64;
|
22 |
|
23 | let mut rng = rand_chacha::ChaChaRng::seed_from_u64(114514);
|
24 | let mut heights = (1..=num)
|
25 | .map(|x| x as f64 * height_unit)
|
26 | .collect::<Vec<f64>>();
|
27 | heights.shuffle(&mut rng);
|
28 |
|
29 | let padded_frame_bl = dvec2(padded_frame_size.x / -2.0, padded_frame_size.y / -2.0);
|
30 | let mut rects = heights
|
31 | .iter()
|
32 | .enumerate()
|
33 | .map(|(i, &height)| {
|
34 | let mut rect = Rectangle(width_unit, height).build();
|
35 | let target_bc_coord = padded_frame_bl.extend(0.0)
|
36 | + DVec3::X * (width_unit * i as f64 + width_unit / 2.0);
|
37 | rect.scale(DVec3::splat(0.8))
|
38 | .put_anchor_on(Anchor::edge(0, -1, 0), target_bc_coord)
|
39 | .set_color(manim::WHITE)
|
40 | .set_stroke_width(0.0)
|
41 | .set_fill_opacity(0.5);
|
42 | timeline.insert(rect)
|
43 | })
|
44 | .collect::<Vec<_>>();
|
45 |
|
46 | let shift_right = DVec3::X * width_unit;
|
47 | for i in 0..num - 1 {
|
48 | timeline.play(
|
49 | rects[i]
|
50 | .transform(|data| {
|
51 | data.set_color(manim::RED_C).set_fill_opacity(0.5);
|
52 | })
|
53 | .with_duration(anim_step_duration)
|
54 | .with_rate_func(linear)
|
55 | .apply(),
|
56 | );
|
57 | for j in i + 1..num {
|
58 | timeline.play(
|
59 | rects[j]
|
60 | .transform(|data| {
|
61 | data.set_color(manim::BLUE_C).set_fill_opacity(0.5);
|
62 | })
|
63 | .with_duration(anim_step_duration)
|
64 | .with_rate_func(linear)
|
65 | .apply(),
|
66 | );
|
67 | timeline.sync();
|
68 |
|
69 | if heights[i] > heights[j] {
|
70 | timeline.play(
|
71 | rects[i]
|
72 | .transform(|data| {
|
73 | data.shift(shift_right * (j - i) as f64)
|
74 | .set_color(manim::BLUE_C)
|
75 | .set_fill_opacity(0.5);
|
76 | })
|
77 | .with_duration(anim_step_duration)
|
78 | .with_rate_func(linear)
|
79 | .apply(),
|
80 | );
|
81 | timeline.play(
|
82 | rects[j]
|
83 | .transform(|data| {
|
84 | data.shift(-shift_right * (j - i) as f64)
|
85 | .set_color(manim::RED_C)
|
86 | .set_fill_opacity(0.5);
|
87 | })
|
88 | .with_duration(anim_step_duration)
|
89 | .with_rate_func(linear)
|
90 | .apply(),
|
91 | );
|
92 | timeline.sync();
|
93 | heights.swap(i, j);
|
94 | rects.swap(i, j);
|
95 | }
|
96 | timeline.play(
|
97 | rects[j]
|
98 | .transform(|data| {
|
99 | data.set_color(manim::WHITE).set_fill_opacity(0.5);
|
100 | })
|
101 | .with_duration(anim_step_duration)
|
102 | .with_rate_func(linear)
|
103 | .apply(),
|
104 | );
|
105 | timeline.sync();
|
106 | }
|
107 | timeline.play(
|
108 | rects[i]
|
109 | .transform(|data| {
|
110 | data.set_color(manim::WHITE).set_fill_opacity(0.5);
|
111 | })
|
112 | .with_duration(anim_step_duration)
|
113 | .with_rate_func(linear)
|
114 | .apply(),
|
115 | );
|
116 | timeline.sync();
|
117 | }
|
118 |
|
119 | timeline.insert_time_mark(
|
120 | timeline.duration_secs() / 2.0,
|
121 | TimeMark::Capture(format!("preview-{num}.png")),
|
122 | );
|
123 | }
|
124 | }
|
125 |
|
126 | fn main() {
|
127 | render_scene(
|
128 | SelectiveSortScene(10),
|
129 | &AppOptions {
|
130 | output_filename: "output-10.mp4",
|
131 | ..Default::default()
|
132 | },
|
133 | );
|
134 | render_scene(
|
135 | SelectiveSortScene(100),
|
136 | &AppOptions {
|
137 | output_filename: "output-100.mp4",
|
138 | ..Default::default()
|
139 | },
|
140 | );
|
141 | }
|
142 |
|