1use std::f32::consts::PI;
4
5use glam::Vec2;
6use rand::Rng;
7use rand_distr::Distribution;
8
9pub fn round(input: Vec2) -> (isize, isize) {
11 (input.x.round() as isize, input.y.round() as isize)
12}
13
14pub fn gen_points_circle(radius: isize, n: usize) -> Vec<Vec2> {
16 let mut res = Vec::new();
17 while res.len() < n {
18 let x = rand::thread_rng().gen_range(-radius..=radius);
19 let y = rand::thread_rng().gen_range(-radius..=radius);
20 if x.pow(2) + y.pow(2) <= radius.pow(2) {
21 res.push(Vec2::new(x as f32, y as f32));
22 }
23 }
24 res
25}
26
27pub fn gen_points_circle_normal(radius: f32, n: usize) -> Vec<Vec2> {
31 let mut rng = rand::thread_rng();
32 let normal =
33 rand_distr::Normal::new(0., radius / 9.).expect("Unable to generate normal distribution.");
34 let mut res = Vec::new();
35 while res.len() < n {
36 let x = normal.sample(&mut rng);
37 if x < -radius || x > radius {
38 continue;
39 }
40 let y = normal.sample(&mut rng);
41 if x < -radius || y > radius {
42 continue;
43 }
44 if x.powi(2) + y.powi(2) <= radius.powi(2) {
45 res.push(Vec2::new(x, y));
46 }
47 }
48 res
49}
50
51pub fn gen_points_circle_normal_dev(radius: f32, n: usize, std_dev: f32) -> Vec<Vec2> {
56 let mut rng = rand::thread_rng();
57 let normal =
58 rand_distr::Normal::new(0., std_dev).expect("Unable to generate normal distribution.");
59 let mut res = Vec::new();
60 while res.len() < n {
61 let x = normal.sample(&mut rng);
62 if x < -radius || x > radius {
63 continue;
64 }
65 let y = normal.sample(&mut rng);
66 if x < -radius || y > radius {
67 continue;
68 }
69 if x.powi(2) + y.powi(2) <= radius.powi(2) {
70 res.push(Vec2::new(x, y));
71 }
72 }
73 res
74}
75
76pub fn gen_points_fan(radius: f32, n: usize, st_angle: f32, ed_angle: f32) -> Vec<Vec2> {
78 let mut res = Vec::new();
79 while res.len() < n {
80 let x = rand::thread_rng().gen_range(-radius..=radius);
81 let y = rand::thread_rng().gen_range(-radius..=radius);
82 let t = y.atan2(x);
83 if t <= ed_angle && t >= st_angle && x.powi(2) + y.powi(2) <= radius.powi(2) {
84 res.push(Vec2::new(x, -y));
85 }
86 }
87 res
88}
89
90pub fn gen_points_arc(radius: f32, n: usize, st_angle: f32, ed_angle: f32) -> Vec<Vec2> {
92 let mut res = Vec::new();
93 while res.len() < n {
94 let a = rand::thread_rng().gen_range(st_angle..=ed_angle);
95 res.push(Vec2::new(radius * a.cos(), -radius * a.sin()));
96 }
97 res
98}
99
100pub fn gen_points_on_circle(radius: f32, n: usize) -> Vec<Vec2> {
102 let mut res = Vec::new();
103 while res.len() < n {
104 let a = rand::thread_rng().gen_range(0.0..PI);
105 res.push(Vec2::new(radius * a.cos(), -radius * a.sin()));
106 }
107 res
108}
109
110pub fn distance_squared(a: Vec2, b: Vec2) -> f32 {
112 (b.x - a.x).powi(2) + (b.y - a.y).powi(2)
113}
114
115pub fn explosion_gradient_1(x: f32) -> f32 {
119 if x < 0.087 {
120 150. * x.powi(2)
121 } else {
122 -0.8 * x + 1.2
123 }
124}
125
126pub fn explosion_gradient_2(x: f32) -> f32 {
130 if x < 0.067 {
131 5. * x + 0.1
132 } else if x < 0.2 {
133 2. * x + 0.3
134 } else if x < 0.5 {
135 x + 0.5
136 } else if x < 0.684 {
137 0.5 * x + 0.75
138 } else {
139 -7. * (x - 0.65).powi(2) + 1.1
140 }
141}
142
143pub fn explosion_gradient_3(x: f32) -> f32 {
147 if x < 0.087 {
148 150. * x.powi(2) * 0.6
149 } else {
150 (-0.8 * x + 1.2) * 0.6
151 }
152}
153
154pub fn linear_gradient_1(x: f32) -> f32 {
158 -0.7 * x + 1.
159}