1use crate::{ifs::IFS, image::Image};
10
11pub struct AnimationSequence {
13 pub ifs_vec: Vec<IFS>,
14 pub step_counts: Vec<usize>
15}
16
17impl AnimationSequence {
18 fn determine_current_pair_index(&self, current_step: usize) -> usize {
19 let mut pair_index = 0;
20 let mut accumulator = 0;
21 while accumulator < current_step {
22 accumulator += self.step_counts.get(pair_index).expect("current_step exceeds total step count.");
23 pair_index += 1;
24 }
25 pair_index - 1
26 }
27
28 fn determine_current_pct(&self, current_step: usize, pair_index: usize) -> f32{
29 let mut current_pair = 0;
30 let mut accumulator = 0;
31 while current_pair < pair_index {
32 accumulator += self.step_counts.get(current_pair).expect("current_step exceeds total step count.");
33 current_pair += 1;
34 }
35 let this_pair_steps = current_step - accumulator;
36 this_pair_steps as f32 / *self.step_counts.get(pair_index).unwrap() as f32
37 }
38
39 pub fn animate_single_step(&self, width: usize, height: usize,
56 num_iterations: usize, num_points: usize, current_step: usize) -> Image {
57 let pair_index = self.determine_current_pair_index(current_step);
58
59 let start = self.ifs_vec.get(pair_index).unwrap();
60 let end = self.ifs_vec.get(pair_index + 1).unwrap();
61 let pct = self.determine_current_pct(current_step, pair_index);
62 let this_ifs = start.morph(end, pct);
63
64 let mut this_image = Image::new(width, height);
65 this_ifs.evaluate(&mut this_image, num_points, num_iterations);
66 this_image
67 }
68
69 pub fn animate(&self, width: usize, height: usize, num_iterations: usize, num_points: usize) -> Vec<Image> {
86 let mut images = vec![];
87
88 for pair_index in 0..self.ifs_vec.len()-1 {
89 let num_steps_for_pair = *self.step_counts.get(pair_index).unwrap();
90
91 let start = self.ifs_vec.get(pair_index).unwrap();
92 let end = self.ifs_vec.get(pair_index + 1).unwrap();
93 for step in 0..num_steps_for_pair{
94
95 let this_ifs = start.morph(end, step as f32 / num_steps_for_pair as f32);
96
97 let mut this_image = Image::new(width, height);
98 this_ifs.evaluate(&mut this_image, num_points, num_iterations);
99
100 images.insert(images.len(), this_image);
101 }
102 }
103 images
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use crate::{ifs::IFS, animation::AnimationSequence};
110
111 #[test]
112 fn test_determine_current_pair_index() {
113 let ifs1: IFS = IFS::new();
114 let ifs2: IFS = IFS::new();
115 let ifs3: IFS = IFS::new();
116 let ifs4: IFS = IFS::new();
117
118 let seq = AnimationSequence{ifs_vec: vec![ifs1, ifs2, ifs3, ifs4],
119 step_counts: vec![100, 200, 300]};
120
121 assert_eq!(seq.determine_current_pair_index(30), 0);
122 assert_eq!(seq.determine_current_pair_index(100), 0);
123 assert_eq!(seq.determine_current_pair_index(101), 1);
124 assert_eq!(seq.determine_current_pair_index(101), 1);
125 assert_eq!(seq.determine_current_pair_index(305), 2);
126 }
127
128 #[test]
129 fn test_determine_current_pct() {
130 let ifs1: IFS = IFS::new();
131 let ifs2: IFS = IFS::new();
132 let ifs3: IFS = IFS::new();
133 let ifs4: IFS = IFS::new();
134
135 let seq = AnimationSequence{ifs_vec: vec![ifs1, ifs2, ifs3, ifs4],
136 step_counts: vec![100, 200, 300]};
137
138 assert!((seq.determine_current_pct(30, 0) - 0.3).abs() < 0.01);
139 assert!((seq.determine_current_pct(101, 1) - 1.0/200.0).abs() < 0.01);
140 assert!((seq.determine_current_pct(201, 1) - 101.0/200.0).abs() < 0.01);
141 }
142}