Skip to content

Instantly share code, notes, and snippets.

@meganehouser
Created July 12, 2018 12:19
Show Gist options
  • Save meganehouser/6284f88136649c00a9f5f1a6431bba37 to your computer and use it in GitHub Desktop.
Save meganehouser/6284f88136649c00a9f5f1a6431bba37 to your computer and use it in GitHub Desktop.
nannou sample
extern crate nannou;
use std::f32::consts::PI;
use nannou::prelude::*;
use nannou::math::pt2;
use nannou::geom::Line;
use nannou::color::Rgba;
use nannou::event::Key;
const WIN_WIDTH: u32 = 640;
const WIN_HEIGHT: u32 = 640;
const MAX_RADIUS: f32 = 200.0f32;
const MIN_RADIUS: f32 = 80.0f32;
const STAR_SIZE: f32 = 0.01f32;
const STAR_NUM: usize = 150;
const STAR_DISTANCE: f32 = 70.0f32;
const LINE_WIDHT: f32 = 0.8f32;
const POSI_NEGA: [f32; 2] = [-1.0f32, 1.0f32];
fn main() {
nannou::app(model, event, view).run();
}
enum State {
Play,
Pause,
}
struct Star {
origin: Point2<f32>,
radius: f32,
radian: f32,
direction: f32,
point: Point2<f32>,
}
impl Star {
fn rand(rect: Rect<f32>) -> Star {
let origin = pt2(
random_range(rect.left(), rect.right()),
random_range(rect.bottom(), rect.top()),
);
let radius = random_range(MIN_RADIUS, MAX_RADIUS);
let radian = random_range(0.0f32, PI * 2.0f32);
let direction = POSI_NEGA[random_range(0, 2)];
Star {
origin: origin,
radius: radius,
radian: radian,
direction: direction,
point: Star::get_pt(&origin, radius, radian),
}
}
fn get_pt(origin: &Point2<f32>, radius: f32, radian: f32) -> Point2<f32> {
pt2(
radian.cos() * radius + origin.x,
radian.sin() * radius + origin.y,
)
}
fn update_next(&mut self) {
self.radian += PI / 180.0f32 * self.direction;
self.point = Star::get_pt(&self.origin, self.radius, self.radian);
}
fn distance(&self, star: &Star) -> f32 {
((self.point.x - star.point.x).powf(2.0) + (self.point.y - star.point.y).powf(2.0)).sqrt()
}
}
struct Model {
stars: Vec<Star>,
lines: Vec<Line>,
state: State,
}
fn model(app: &App) -> Model {
app.set_loop_mode(LoopMode::rate_fps(30.0f64));
let _window = app.new_window()
.with_dimensions(WIN_WIDTH, WIN_HEIGHT)
.build()
.unwrap();
let mut stars = Vec::<Star>::with_capacity(STAR_NUM);
for _ in 0..STAR_NUM {
stars.push(Star::rand(app.window_rect()));
}
Model {
stars: stars,
lines: Vec::<Line>::new(),
state: State::Play,
}
}
fn event(_app: &App, mut model: Model, event: Event) -> Model {
match event {
Event::WindowEvent {
simple: Some(event),
raw: _,
id: _,
} => {
match event {
KeyPressed(key) => {
match key {
Key::Down => model.state = State::Pause,
Key::Up => model.state = State::Play,
_ => {}
}
}
_other => (),
}
}
Event::Update(_update) => {
if let State::Play = model.state {
for star in model.stars.iter_mut() {
star.update_next();
}
model.lines.clear();
let len = model.stars.len();
for i in 0..len {
if let Some(ref s1) = model.stars.get(i) {
for j in i..len {
if let Some(ref s2) = model.stars.get(j) {
if s1.distance(&s2) < STAR_DISTANCE {
let line = Line::new(
pt2(s1.point.x, s1.point.y),
pt2(s2.point.x, s2.point.y),
LINE_WIDHT,
);
model.lines.push(line);
}
}
}
}
}
}
}
_ => (),
}
model
}
fn view(app: &App, _model: &Model, frame: Frame) -> Frame {
let draw = app.draw();
draw.background().color(BLACK);
let star_color = Rgba::new(1.0f32, 1.0f32, 1.0f32, 0.05f32);
for star in _model.stars.iter() {
draw.ellipse()
.radius(STAR_SIZE)
.x_y(star.point.x, star.point.y)
.color(star_color);
}
for line in _model.lines.iter() {
draw.line()
.start(line.start)
.end(line.end)
.thickness(line.half_thickness)
.color(star_color);
}
draw.to_frame(app, &frame).unwrap();
frame
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment