From 20b8f6d4db49013867123db0e979b275d19f5902 Mon Sep 17 00:00:00 2001 From: Tobias Ollive Date: Sat, 12 Mar 2022 21:20:55 +0100 Subject: [PATCH] add ring and ringscanner pattern --- spectacle.yml | 12 ++---- src/patterns.rs | 12 ++++++ src/patterns/fade_random.rs | 4 +- src/patterns/fade_unstable.rs | 4 +- src/patterns/ring.rs | 66 +++++++++++++++++++++++++++++++++ src/patterns/ring_scanner.rs | 70 +++++++++++++++++++++++++++++++++++ 6 files changed, 155 insertions(+), 13 deletions(-) create mode 100644 src/patterns/ring.rs create mode 100644 src/patterns/ring_scanner.rs diff --git a/spectacle.yml b/spectacle.yml index f3c016f..07accab 100644 --- a/spectacle.yml +++ b/spectacle.yml @@ -55,15 +55,9 @@ - name: titi sequence: - pattern: - type: FadeRandom - fade : - steps: 50 - begin_color: *black - end_color: &cyan - red: 0 - green: 255 - blue: 255 - stability : 30 + type: RingScanner + color: *green + ring_size: 4 max_iteration : 50 period: 100 - pattern: diff --git a/src/patterns.rs b/src/patterns.rs index e85af09..022f667 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -7,6 +7,8 @@ mod fill_random; mod fill_unstable; mod rain; mod rainbow; +mod ring; +mod ring_scanner; mod scanner; use crate::patterns::blink::Blink; @@ -18,6 +20,8 @@ use crate::patterns::fill_random::FillRandom; use crate::patterns::fill_unstable::FillUnstable; use crate::patterns::rain::Rain; use crate::patterns::rainbow::Rainbow; +use crate::patterns::ring::Ring; +use crate::patterns::ring_scanner::RingScanner; use crate::patterns::scanner::Scanner; use rand::rngs::ThreadRng; use rand::Rng; @@ -38,6 +42,8 @@ pub(crate) enum Patterns { Rain(Rain), FadeRandom(FadeRandom), FadeUnstable(FadeUnstable), + Ring(Ring), + RingScanner(RingScanner), } pub trait Pattern: Iterator { @@ -62,6 +68,8 @@ impl Iterator for Patterns { Patterns::Rain(p) => p.next(), Patterns::FadeRandom(p) => p.next(), Patterns::FadeUnstable(p) => p.next(), + Patterns::Ring(p) => p.next(), + Patterns::RingScanner(p) => p.next(), } } } @@ -81,6 +89,8 @@ impl Pattern for Patterns { Patterns::Rain(p) => p.init(), Patterns::FadeRandom(p) => p.init(), Patterns::FadeUnstable(p) => p.init(), + Patterns::Ring(p) => p.init(), + Patterns::RingScanner(p) => p.init(), } } @@ -96,6 +106,8 @@ impl Pattern for Patterns { Patterns::Rain(p) => p.is_last_iteration(), Patterns::FadeRandom(p) => p.is_last_iteration(), Patterns::FadeUnstable(p) => p.is_last_iteration(), + Patterns::Ring(p) => p.is_last_iteration(), + Patterns::RingScanner(p) => p.is_last_iteration(), } } } diff --git a/src/patterns/fade_random.rs b/src/patterns/fade_random.rs index f5bf2c5..bd2f363 100644 --- a/src/patterns/fade_random.rs +++ b/src/patterns/fade_random.rs @@ -3,9 +3,9 @@ use crate::patterns::Pattern; use crate::Strip; use serde::{Deserialize, Serialize}; -/// # Blink +/// # FadeRandom /// -/// fade from one color to an other then go back several times +/// fade from one color to an other with random variations applied to each pixel #[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] pub struct FadeRandom { #[serde(default)] diff --git a/src/patterns/fade_unstable.rs b/src/patterns/fade_unstable.rs index 68ec6ba..5455972 100644 --- a/src/patterns/fade_unstable.rs +++ b/src/patterns/fade_unstable.rs @@ -3,9 +3,9 @@ use crate::patterns::Pattern; use crate::Strip; use serde::{Deserialize, Serialize}; -/// # Blink +/// # FadeUnstable /// -/// fade from one color to an other then go back several times +/// fade from one color to an other with random variations applied to the entire strip #[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] pub struct FadeUnstable { #[serde(default)] diff --git a/src/patterns/ring.rs b/src/patterns/ring.rs new file mode 100644 index 0000000..90fa820 --- /dev/null +++ b/src/patterns/ring.rs @@ -0,0 +1,66 @@ +use crate::patterns::{Pattern, PixelColor}; +use crate::Strip; +use serde::{Deserialize, Serialize}; + +/// # Ring +/// +/// display a ring on the strip +#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] +pub struct Ring { + #[serde(default)] + pub(crate) current_iteration: usize, + pub(crate) max_iteration: Option, + pub(crate) color: PixelColor, + pub(crate) background_color: Option, + pub(crate) ring_size: usize, +} + +impl Pattern for Ring { + type Strip = Strip; + + fn init(&mut self) -> Option { + None + } + + fn is_last_iteration(&self) -> bool { + match self.max_iteration { + None => false, + Some(max_iter) => { + if self.current_iteration >= max_iter { + true + } else { + false + } + } + } + } +} + +impl Iterator for Ring { + type Item = Strip; + + fn next(&mut self) -> Option { + if self.is_last_iteration() { + return None; + } + + let mut strip: Strip; + + if let Some(color) = self.background_color { + strip = Strip::new(color); + } else { + strip = Strip::default(); + } + + let nbr_iter = N / self.ring_size; + let iter = self.current_iteration % nbr_iter; + let first_index = iter * self.ring_size; + let last_index = first_index + self.ring_size; + + for i in first_index..last_index { + strip[i] = Some(self.color); + } + self.current_iteration += 1; + Some(strip) + } +} diff --git a/src/patterns/ring_scanner.rs b/src/patterns/ring_scanner.rs new file mode 100644 index 0000000..d2128a5 --- /dev/null +++ b/src/patterns/ring_scanner.rs @@ -0,0 +1,70 @@ +use crate::patterns::{Pattern, PixelColor}; +use crate::Strip; +use serde::{Deserialize, Serialize}; + +/// # RingScanner +/// +/// display a ring on the strip fading for the previous ones +#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] +pub struct RingScanner { + #[serde(default)] + pub(crate) current_iteration: usize, + pub(crate) max_iteration: Option, + pub(crate) color: PixelColor, + pub(crate) background_color: Option, + pub(crate) ring_size: usize, +} + +impl Pattern for RingScanner { + type Strip = Strip; + + fn init(&mut self) -> Option { + None + } + + fn is_last_iteration(&self) -> bool { + match self.max_iteration { + None => false, + Some(max_iter) => { + if self.current_iteration >= max_iter { + true + } else { + false + } + } + } + } +} + +impl Iterator for RingScanner { + type Item = Strip; + + fn next(&mut self) -> Option { + if self.is_last_iteration() { + return None; + } + + let mut strip: Strip; + + if let Some(color) = self.background_color { + strip = Strip::new(color); + } else { + strip = Strip::default(); + } + + let nbr_iter = N / self.ring_size; + let iter = self.current_iteration % nbr_iter; + + for j in 0..iter { + let first_index = j * self.ring_size; + let last_index = first_index + self.ring_size; + let fade_gain = 2 * (iter - j); + for i in first_index..last_index { + strip[i] = Some(self.color / fade_gain as u8); + } + } + + self.current_iteration += 1; + Some(strip) + } +}