1use bevy::prelude::*;
2
3#[derive(Component)]
4pub struct FluidParticle {
5 pub velocity: Vec2,
6 pub density: f32,
7 pub pressure: f32,
8}
9
10impl Default for FluidParticle {
11 fn default() -> Self {
12 Self {
13 velocity: Vec2::ZERO,
14 density: 1.225,
15 pressure: 0.0,
16 }
17 }
18}
19
20#[derive(Component)]
21pub struct SolidBoundary {
22 pub points: Vec<Vec2>,
23 pub normals: Vec<Vec2>,
24}
25
26impl SolidBoundary {
27 pub fn new_airfoil(chord: f32, position: Vec2, angle_of_attack: f32) -> Self {
28 let num_points = 50;
29 let mut points = Vec::with_capacity(num_points);
30 let mut normals = Vec::with_capacity(num_points);
31
32 for i in 0..num_points {
33 let x = (i as f32) / (num_points as f32 - 1.0);
34 let t = 0.12; let y = 5.0
36 * t
37 * chord
38 * (0.2969 * x.sqrt() - 0.1260 * x - 0.3516 * x.powi(2) + 0.2843 * x.powi(3)
39 - 0.1015 * x.powi(4));
40
41 let point = Vec2::new(x * chord - chord / 2.0, y);
42
43 points.push(crate::math::rotate_point(point, angle_of_attack) + position);
44 points.push(
45 crate::math::rotate_point(Vec2::new(point.x, -point.y), angle_of_attack) + position,
46 );
47
48 let dx = 0.01;
49 let dy = if i < num_points - 1 {
50 let next_y = 5.0
51 * t
52 * chord
53 * (0.2969 * (x + dx).sqrt() - 0.1260 * (x + dx) - 0.3516 * (x + dx).powi(2)
54 + 0.2843 * (x + dx).powi(3)
55 - 0.1015 * (x + dx).powi(4));
56 (next_y - y) / dx
57 } else {
58 let prev_x = x - dx;
59 let prev_y = 5.0
60 * t
61 * chord
62 * (0.2969 * prev_x.sqrt() - 0.1260 * prev_x - 0.3516 * prev_x.powi(2)
63 + 0.2843 * prev_x.powi(3)
64 - 0.1015 * prev_x.powi(4));
65 (y - prev_y) / dx
66 };
67
68 let normal = Vec2::new(-dy, 1.0).normalize();
69 normals.push(crate::math::rotate_vector(normal, angle_of_attack));
70 normals.push(crate::math::rotate_vector(
71 Vec2::new(-dy, -1.0).normalize(),
72 angle_of_attack,
73 ));
74 }
75
76 Self { points, normals }
77 }
78
79 pub fn new_wind_tunnel(box_size: Vec2) -> Self {
80 let half_width = box_size.x / 2.0;
81 let half_height = box_size.y / 2.0;
82
83 let points = vec![
84 Vec2::new(-half_width, half_height),
85 Vec2::new(half_width, half_height),
86 Vec2::new(-half_width, -half_height),
87 Vec2::new(half_width, -half_height),
88 ];
89
90 let normals = vec![
91 Vec2::new(0.0, -1.0),
92 Vec2::new(0.0, -1.0),
93 Vec2::new(0.0, 1.0),
94 Vec2::new(0.0, 1.0),
95 ];
96
97 Self { points, normals }
98 }
99}