Skip to content

Instantly share code, notes, and snippets.

@MacTuitui
Created January 13, 2019 04:25
Show Gist options
  • Select an option

  • Save MacTuitui/a89f3cae83a92cb51727278f11369d79 to your computer and use it in GitHub Desktop.

Select an option

Save MacTuitui/a89f3cae83a92cb51727278f11369d79 to your computer and use it in GitHub Desktop.
extern crate nannou;
use nannou::prelude::*;
use nannou::prelude::Frame;
use std::process::exit;
use nannou::rand::*;
const SEED: u64 = 3;
fn main() {
nannou::app(model, event, view).run();
}
struct Model {
things: Vec<Thing>,
rng: XorShiftRng,
}
struct Thing {
position: Point2,
speed: Vector2,
acceleration: Vector2,
}
impl Thing {
fn new(x: f32, y:f32) -> Self {
let position = pt2(x,y);
let speed = vec2(0.0, 0.0);
let acceleration = vec2(0.0, 0.0);
Thing {
position,
speed,
acceleration,
}
}
fn push(&mut self, other: &Thing, f:f32) {
let diff = (self.position - other.position).normalize() * f ;
self.acceleration += diff;
}
fn pull(&mut self, other: &Thing, f:f32) {
let diff = (self.position - other.position).normalize() * -f;
self.acceleration += diff;
}
fn pullpt(&mut self, other: Point2, f:f32) {
let diff = (self.position - other).normalize() * -f;
self.acceleration += diff;
}
fn pushpt(&mut self, other: Point2, f:f32) {
let diff = (self.position - other).normalize() * f;
self.acceleration += diff;
}
fn update(&mut self, dt:f32, damp:f32) {
self.speed += self.acceleration * dt;
if self.speed.magnitude() > 1.0 {
self.speed = self.speed.normalize();
}
self.position += self.speed * dt;
self.speed *= damp;
self.acceleration *= 0.0;
}
}
fn model(app: &App) -> Model {
let _window = app.new_window().with_dimensions(1000, 1000).build().unwrap();
//create the random values we will need each frame
//with a prng for reproducability
let mut rng = XorShiftRng::seed_from_u64(SEED);
let s =200;
let mut things = Vec::new();
for i in 0..s {
let r = (rng.gen::<f32>()).sqrt() * 100.0;
let a = (rng.gen::<f32>())*2.0*PI;
let t = Thing::new(r*a.cos(), r*a.sin());
things.push(t);
}
Model{things, rng}
}
fn event(app: &App, mut model: Model, event: Event) -> Model {
match event {
Event::WindowEvent {
simple: Some(event),
..
} => match event {
Moved(_pos) => {}
KeyPressed(_key) => {
println!("{}", app.elapsed_frames());
}
KeyReleased(_key) => {}
MouseMoved(_pos) => {}
MouseDragged(_pos, _button) => {}
MousePressed(_button) => {}
MouseReleased(_button) => {}
MouseEntered => {}
MouseExited => {}
Resized(_size) => {}
_other => (),
},
Event::Update(_dt) => {
let mut frac = ((app.elapsed_frames() % 80) as f32)/(80 as f32);
let rng = &mut model.rng;
for i in 0..model.things.len() {
let (left, right) = model.things.split_at_mut(i+1);
let m = &mut left[i];
for j in 0..right.len() {
let m2 = &mut right[j];
let d = m.position.distance2(m2.position);
if d < 10.0*10.0 {
m.push(m2,10.0);
m2.push(m,10.0);
} else if d < 100.0*100.0 {
m.push(m2,1.0);
m2.push(m,1.0);
}
}
m.pullpt(pt2(0.0,0.0), 1.0 + 30.0*(((app.elapsed_frames() % 50) as f32/50.0)*PI).sin());
}
for i in 0..model.things.len() {
model.things[i].update(1.0, 0.9);
}
}
_ => (),
}
model
}
fn view(app: &App, mut model: &Model, frame: Frame) -> Frame {
// Prepare to draw.
let draw = app.draw();
// Clear the background
if app.elapsed_frames() == 0 {
draw.background().color(BLACK);
}
draw.rect().w_h(1000.0, 1000.0).rgba(0.0,0.0,0.0,0.08);
for i in 0..model.things.len() {
let m = &model.things[i];
for j in i+1..model.things.len() {
let m2 = &model.things[j];
let d = m.position.distance(m2.position);
if d < 30.0 {
draw.line()
.thickness(6.0)
.start(m.position)
.end(m2.position)
.hsva(0.0,0.0, 1.0,0.05);
}
}
}
// Write to the window frame.
draw.to_frame(app, &frame).unwrap();
// Return the drawn frame.
frame
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment