1use ndarray::Array2;
2use ndarray_rand::rand::Rng;
3use num_traits::float::FloatConst;
4
5pub fn generate_swissroll(
8 height: f64,
9 speed: f64,
10 n_points: usize,
11 rng: &mut impl Rng,
12) -> Array2<f64> {
13 let mut roll: Array2<f64> = Array2::zeros((n_points, 3));
14
15 for i in 0..n_points {
16 let z = rng.gen_range(0.0..height);
17 let phi: f64 = rng.gen_range(0.0..10.0);
18 let offset = 0.0;
20
21 let x = speed * phi * phi.cos() + offset;
22 let y = speed * phi * phi.sin() + offset;
23
24 roll[(i, 0)] = x;
25 roll[(i, 1)] = y;
26 roll[(i, 2)] = z;
27 }
28 roll
29}
30
31pub fn generate_convoluted_rings(
32 rings: &[(f64, f64)],
33 n_points: usize,
34 rng: &mut impl Rng,
35) -> Array2<f64> {
36 let n_points = (n_points as f32 / rings.len() as f32).ceil() as usize;
37 let mut array = Array2::zeros((n_points * rings.len(), 3));
38
39 for (n, (start, end)) in rings.iter().enumerate() {
40 for i in 0..n_points {
42 let r: f64 = rng.gen_range(*start..*end);
43 let phi: f64 = rng.gen_range(0.0..(f64::PI() * 2.0));
44 let theta: f64 = rng.gen_range(0.0..(f64::PI() * 2.0));
45
46 let x = theta.sin() * phi.cos() * r;
47 let y = theta.sin() * phi.sin() * r;
48 let z = theta.cos() * r;
49
50 array[(n * n_points + i, 0)] = x;
51 array[(n * n_points + i, 1)] = y;
52 array[(n * n_points + i, 2)] = z;
53 }
54 }
55
56 array
57}
58
59pub fn generate_convoluted_rings2d(
60 rings: &[(f64, f64)],
61 n_points: usize,
62 rng: &mut impl Rng,
63) -> Array2<f64> {
64 let n_points = (n_points as f32 / rings.len() as f32).ceil() as usize;
65 let mut array = Array2::zeros((n_points * rings.len(), 2));
66
67 for (n, (start, end)) in rings.iter().enumerate() {
68 for i in 0..n_points {
70 let r: f64 = rng.gen_range(*start..*end);
71 let phi: f64 = rng.gen_range(0.0..(f64::PI() * 2.0));
72
73 let x = phi.cos() * r;
74 let y = phi.sin() * r;
75
76 array[(n * n_points + i, 0)] = x;
77 array[(n * n_points + i, 1)] = y;
78 }
79 }
80
81 array
82}