|
|
|
@ -90,19 +90,15 @@ impl Object { |
|
|
|
|
|
|
|
|
|
fn update_border_dist(&mut self, args: &RenderArgs) { |
|
|
|
|
self.window_size = vec![args.width, args.height]; |
|
|
|
|
|
|
|
|
|
let mut middle: Vec<f64> = Vec::new(); |
|
|
|
|
for size in &self.window_size { |
|
|
|
|
middle.push(size / 2.0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (i, pos) in &mut self.pos.iter().enumerate() { |
|
|
|
|
if pos < &mut middle[i as usize] { |
|
|
|
|
self.border_dist[i as usize] = *pos; |
|
|
|
|
} else { |
|
|
|
|
self.border_dist[i as usize] = self.window_size[i as usize] - *pos; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
self.border_dist = self |
|
|
|
|
.pos |
|
|
|
|
.iter() |
|
|
|
|
.zip(&self.window_size) |
|
|
|
|
.map(|(pos, win_size)| match *pos { |
|
|
|
|
pos if pos < win_size / 2.0 => pos, |
|
|
|
|
_ => win_size - pos, |
|
|
|
|
}) |
|
|
|
|
.collect(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn edge_repel(weighted_bd: f64, vel: f64, limiter: f64) -> f64 { |
|
|
|
@ -113,22 +109,23 @@ impl Object { |
|
|
|
|
let pos: Vec<f64> = self.get_pos(); |
|
|
|
|
let dist: Vec<f64> = vec![pos[0] - mouse_pos[0], pos[1] - mouse_pos[1]]; |
|
|
|
|
let amount = calc_amount(&dist); |
|
|
|
|
for (i, d) in dist.iter().enumerate() { |
|
|
|
|
self.vel[i] -= 0.2 * d / amount.max(0.1); |
|
|
|
|
self.vel[i] = self.vel[i].min(10.0).max(-10.0); |
|
|
|
|
} |
|
|
|
|
self.vel = dist |
|
|
|
|
.iter() |
|
|
|
|
.zip(&self.vel) |
|
|
|
|
.map(|(d, vel)| { |
|
|
|
|
let res = vel - 0.2 * d / amount.max(0.1); |
|
|
|
|
res.min(10.0).max(-10.0) |
|
|
|
|
}) |
|
|
|
|
.collect(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn attract(&mut self, objs: &mut Vec<Vec<f64>>) { |
|
|
|
|
let this_pos: Vec<f64> = self.get_pos(); |
|
|
|
|
let distances: Vec<Vec<f64>> = objs |
|
|
|
|
.iter() |
|
|
|
|
.map( |
|
|
|
|
|obj_pos| |
|
|
|
|
{ |
|
|
|
|
Object::calc_xy_distances(&this_pos, obj_pos) |
|
|
|
|
} |
|
|
|
|
).collect(); |
|
|
|
|
.map(|obj_pos| Object::calc_xy_distances(&this_pos, obj_pos)) |
|
|
|
|
.collect(); |
|
|
|
|
|
|
|
|
|
for dist in distances { |
|
|
|
|
let amount = calc_amount(&dist); |
|
|
|
|
for (i, d) in dist.iter().enumerate() { |
|
|
|
@ -141,45 +138,26 @@ impl Object { |
|
|
|
|
obj_pos |
|
|
|
|
.iter() |
|
|
|
|
.zip(this_pos) |
|
|
|
|
.map( |
|
|
|
|
|(obj, this)| |
|
|
|
|
{ obj - this } |
|
|
|
|
).collect() |
|
|
|
|
.map(|(obj, this)| obj - this) |
|
|
|
|
.collect() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn repel(&mut self, obj_pos: &mut Vec<Vec<f64>>) { |
|
|
|
|
let this_pos: Vec<f64> = self.get_pos(); |
|
|
|
|
obj_pos |
|
|
|
|
.iter() |
|
|
|
|
.for_each( |
|
|
|
|
|pos| |
|
|
|
|
{ |
|
|
|
|
let dist_vec: Vec<f64> = this_pos.iter().zip(pos).map(|(t, p)| {t - p}).collect(); |
|
|
|
|
// let mut dist_vec: Vec<f64> = Vec::new();
|
|
|
|
|
// for i in 0..2 {
|
|
|
|
|
// dist_vec.push(this_pos[i] - pos[i]);
|
|
|
|
|
// }
|
|
|
|
|
let amount = calc_amount(&dist_vec); |
|
|
|
|
|
|
|
|
|
self.apply_force_to_self(&dist_vec, amount) |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
// for pos in obj_pos {
|
|
|
|
|
// let mut dist_vec: Vec<f64> = Vec::new();
|
|
|
|
|
// for i in 0..2 {
|
|
|
|
|
// dist_vec.push(this_pos[i] - pos[i]);
|
|
|
|
|
// }
|
|
|
|
|
// let amount = calc_amount(&dist_vec);
|
|
|
|
|
//
|
|
|
|
|
// self.apply_force_to_self(&mut dist_vec, amount)
|
|
|
|
|
// }
|
|
|
|
|
obj_pos.iter().for_each(|pos| { |
|
|
|
|
let dist_vec: Vec<f64> = this_pos.iter().zip(pos).map(|(t, p)| t - p).collect(); |
|
|
|
|
let amount = calc_amount(&dist_vec); |
|
|
|
|
|
|
|
|
|
self.apply_force_to_self(&dist_vec, amount) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn apply_force_to_self(&mut self, dist_vec: &Vec<f64>, amount: f64) { |
|
|
|
|
for (i, d) in dist_vec.iter().enumerate() { |
|
|
|
|
let repel_force = 1.5 * d.min(150.0).max(-150.0) / (amount).max(0.01); |
|
|
|
|
self.vel[i] += repel_force; |
|
|
|
|
} |
|
|
|
|
self.vel = dist_vec |
|
|
|
|
.iter() |
|
|
|
|
.zip(&self.vel) |
|
|
|
|
.map(|(d, vel)| vel + 1.5 * d.min(150.0).max(-150.0) / (amount).max(0.01)) |
|
|
|
|
.collect(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn calc_vel(&mut self) -> Vec<f64> { |
|
|
|
@ -197,9 +175,12 @@ impl Object { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn update_vel(&mut self, new_vel: Vec<f64>) { |
|
|
|
|
for (i, d) in new_vel.iter().enumerate() { |
|
|
|
|
self.vel[i] = ((self.vel[i] + d) / 2.0).max(-10.0).min(10.0); |
|
|
|
|
} |
|
|
|
|
self.vel = self |
|
|
|
|
.vel |
|
|
|
|
.iter() |
|
|
|
|
.zip(new_vel) |
|
|
|
|
.map(|(vel, new_vel)| ((vel + new_vel) / 2.0).max(-10.0).min(10.0)) |
|
|
|
|
.collect(); |
|
|
|
|
let amount = calc_amount(&self.vel); |
|
|
|
|
for i in 0..2 { |
|
|
|
|
self.vel[i] *= 10.0 / amount; |
|
|
|
@ -278,20 +259,19 @@ fn main() { |
|
|
|
|
let mut events = Events::new(EventSettings::new()); |
|
|
|
|
while let Some(e) = events.next(&mut window) { |
|
|
|
|
if let Some(r) = e.render_args() { |
|
|
|
|
for i in 0..objects.len() { |
|
|
|
|
objects[i].update_border_dist(&r); |
|
|
|
|
objects[i].update(); |
|
|
|
|
positions[i] = objects[i].get_pos(); |
|
|
|
|
} |
|
|
|
|
objects.iter_mut().for_each(|obj| { |
|
|
|
|
obj.update_border_dist(&r); |
|
|
|
|
obj.update(); |
|
|
|
|
}); |
|
|
|
|
positions = objects.iter().map(|obj| obj.get_pos()).collect(); |
|
|
|
|
app.render(&objects, &r); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let Some(_u) = e.update_args() { |
|
|
|
|
for obj in &mut objects { |
|
|
|
|
objects.iter_mut().for_each(|obj| { |
|
|
|
|
obj.attract(&mut positions); |
|
|
|
|
obj.repel(&mut positions); |
|
|
|
|
} |
|
|
|
|
// positions.clear()
|
|
|
|
|
obj.repel(&mut positions) |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let Some(p) = e.press_args() { |
|
|
|
@ -308,9 +288,7 @@ fn main() { |
|
|
|
|
|
|
|
|
|
if let Some(c) = e.mouse_cursor_args() { |
|
|
|
|
if m_attract { |
|
|
|
|
for obj in &mut objects { |
|
|
|
|
obj.mouse_attract(c); |
|
|
|
|
} |
|
|
|
|
objects.iter_mut().for_each(|obj| obj.mouse_attract(c)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|