Raster bars: Difference between revisions

Content added Content deleted
(add Rust version)
Line 665: Line 665:


(Small) Moving gif of swaying bars: [https://github.com/thundergnat/rc/blob/master/img/Raster-bars-swaying-Raku.gif (offsite .gif image)]
(Small) Moving gif of swaying bars: [https://github.com/thundergnat/rc/blob/master/img/Raster-bars-swaying-Raku.gif (offsite .gif image)]

=={{header|Rust}}==
<lang rust>
extern crate minifb;

use std::iter::repeat;

use minifb::{Key, Window, WindowOptions};

const WIDTH: usize = 640;
const HEIGHT: usize = 360;

struct Bar {
color: [f32; 3],
height: u32,
position: f32,
speed: f32,
}

impl Bar {

fn draw_column(&self, column_buffer: &mut [u32]) {
let start_row = (self.position.round() as i32).clamp(0, HEIGHT as i32) as usize;
let end_row = (start_row + self.height as usize).clamp(0, HEIGHT);

column_buffer[start_row..end_row].iter_mut().enumerate()
.for_each(|(row_index, color)| {
*color = self.row_color(row_index as i32);
});
}

fn row_color(&self, y: i32) -> u32 {
let yy = y as f32 / (self.height - 1) as f32;
let yy = 1.0 - 2.0 * (yy - 0.5).abs();

let r = (25.0 + yy.powf((2.0 - 2.0 * self.color[0]).exp()) * 230.0).round() as u8;
let g = (25.0 + yy.powf((2.0 - 2.0 * self.color[1]).exp()) * 230.0).round() as u8;
let b = (25.0 + yy.powf((2.0 - 2.0 * self.color[2]).exp()) * 230.0).round() as u8;

u32::from_be_bytes([255, r, g, b])
}

fn update_position(&mut self) {
self.position += self.speed;

if let Some(position) = self.bounce_position() {
self.position = position;
self.speed = -self.speed;
}
}

fn bounce_position(&self) -> Option<f32> {
if self.speed > 0.0 {
let limit = (HEIGHT as i32 - self.height as i32) as f32;
(self.position >= limit).then(|| limit - (self.position - limit))
} else {
(self.position <= 0.0).then(|| -self.position)
}
}

}

fn main() {

let mut window = Window::new(
"Raster Bars",
WIDTH,
HEIGHT,
WindowOptions::default(),
)
.unwrap_or_else(|e| {
panic!("{}", e);
});

// Limit to max ~60 fps update rate
window.limit_update_rate(Some(std::time::Duration::from_micros(16600)));

let mut bars = Vec::new();

bars.push(Bar { color: [1.0, 1.0, 0.0], height: 20, position: 0.0, speed: 3.1 });
bars.push(Bar { color: [1.0, 0.0, 0.0], height: 25, position: 0.0, speed: 0.2 });
bars.push(Bar { color: [0.0, 1.0, 0.0], height: 7, position: 0.0, speed: 0.4 });
bars.push(Bar { color: [0.0, 0.0, 1.0], height: 30, position: 0.0, speed: 1.0 });

while window.is_open() && !window.is_key_down(Key::Escape) {

let mut column_buffer = vec![0x_00_00_00_u32; HEIGHT];
for bar in &mut bars {
bar.draw_column(&mut column_buffer);
bar.update_position();
}

let buffer: Vec<u32> = column_buffer.iter()
.flat_map(|&row_color| repeat(row_color).take(WIDTH))
.collect();

window
.update_with_buffer(&buffer, WIDTH, HEIGHT)
.unwrap();
}
}
</lang>



=={{header|Wren}}==
=={{header|Wren}}==