325 lines
10 KiB
Rust
325 lines
10 KiB
Rust
use std::f32::consts::PI;
|
|
|
|
use iced::Vector;
|
|
use iced::mouse;
|
|
use iced::widget::canvas;
|
|
use iced::widget::canvas::Stroke;
|
|
use iced::widget::canvas::Style;
|
|
use iced::{Color, Rectangle, Renderer, Theme};
|
|
use kira::sound::static_sound::StaticSoundData;
|
|
|
|
pub trait RotationExt {
|
|
fn rotate(&mut self, teta: f32) -> Self;
|
|
}
|
|
|
|
impl RotationExt for Vector {
|
|
fn rotate(&mut self, teta: f32) -> Vector {
|
|
Vector::new(
|
|
self.x * teta.cos() - self.y * teta.sin(),
|
|
self.x * teta.sin() + self.y * teta.cos(),
|
|
)
|
|
}
|
|
}
|
|
pub struct PolygonFrame {
|
|
pub teta: f32,
|
|
pub polygons: Vec<Polygon>,
|
|
}
|
|
|
|
impl PolygonFrame {
|
|
pub fn all_sound_to_play_btw(&self, before: f32, after: f32) -> Vec<&StaticSoundData> {
|
|
let mut all_sound: Vec<&StaticSoundData> = vec![];
|
|
for poly in &self.polygons {
|
|
all_sound.extend(poly.sound_to_play_btw(before, after));
|
|
}
|
|
all_sound
|
|
}
|
|
}
|
|
|
|
impl<Message> canvas::Program<Message> for PolygonFrame {
|
|
// No internal state
|
|
type State = ();
|
|
|
|
fn draw(
|
|
&self,
|
|
_state: &(),
|
|
renderer: &Renderer,
|
|
_theme: &Theme,
|
|
bounds: Rectangle,
|
|
_cursor: mouse::Cursor,
|
|
) -> Vec<canvas::Geometry> {
|
|
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
|
let radius = frame.size().width / 2.0 - 32.0;
|
|
let mut vec = Vector::new(0.0, -radius);
|
|
let c = frame.center();
|
|
// Draw Circle
|
|
let circle = canvas::Path::circle(frame.center(), radius);
|
|
frame.stroke(
|
|
&circle,
|
|
Stroke {
|
|
width: 6.0,
|
|
style: Style::Solid(Color::from_rgba(0.0, 0.0, 0.0, 1.0)),
|
|
..Stroke::default()
|
|
},
|
|
);
|
|
|
|
// Draw all polygons by there points
|
|
for poly in &self.polygons {
|
|
let l = poly.points_teta.len();
|
|
let mut line: canvas::Path;
|
|
let mut t1: f32;
|
|
let mut t2: f32;
|
|
for i in 0..l {
|
|
t1 = poly.points_teta[i] + poly.global_teta;
|
|
t2 = poly.points_teta[(i + 1) % l] + poly.global_teta;
|
|
line = canvas::Path::line(c + vec.rotate(t1), c + vec.rotate(t2));
|
|
frame.stroke(
|
|
&line,
|
|
Stroke {
|
|
width: 4.0,
|
|
style: Style::Solid(poly.color.clone()),
|
|
..Stroke::default()
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
// Draw the red dot on the current position
|
|
let dot = canvas::Path::circle(frame.center() + vec.rotate(self.teta), 5.0);
|
|
frame.fill(&dot, Color::from_rgb(1.0, 0.0, 0.0));
|
|
|
|
// Draw the frame
|
|
frame.stroke_rectangle(
|
|
iced::Point { x: 0.0, y: 0.0 },
|
|
frame.size(),
|
|
Stroke {
|
|
width: 16.0,
|
|
..Stroke::default()
|
|
},
|
|
);
|
|
|
|
// Then, we produce the geometry
|
|
vec![frame.into_geometry()]
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Polygon {
|
|
pub global_teta: f32,
|
|
pub points_teta: Vec<f32>,
|
|
pub sound: StaticSoundData,
|
|
pub sound_name: String,
|
|
pub name: String,
|
|
pub color: Color,
|
|
pub color_name: String,
|
|
}
|
|
#[warn(dead_code)]
|
|
impl Polygon {
|
|
pub fn sound_to_play_btw(&self, before: f32, after: f32) -> Vec<&StaticSoundData> {
|
|
let mut sound_to_play: Vec<&StaticSoundData> = vec![];
|
|
if after < before {
|
|
sound_to_play = self.sound_to_play_btw(before, 2.0 * PI);
|
|
sound_to_play.extend(self.sound_to_play_btw(0.0, after));
|
|
return sound_to_play;
|
|
}
|
|
let mut p_g;
|
|
for p in self.points_teta.clone() {
|
|
p_g = (p + self.global_teta) % (2.0 * PI);
|
|
if before <= p_g && p_g <= after {
|
|
sound_to_play.push(&self.sound);
|
|
}
|
|
}
|
|
sound_to_play
|
|
}
|
|
|
|
pub fn n_gon(teta: f32, n_side: u8, sound: StaticSoundData) -> Self {
|
|
let mut v: Vec<f32> = Vec::with_capacity(n_side as usize);
|
|
for i in 0..n_side {
|
|
v.push((i as f32 * 2.0 * PI) / n_side as f32);
|
|
}
|
|
Polygon {
|
|
global_teta: teta,
|
|
points_teta: v,
|
|
sound: sound,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
}
|
|
}
|
|
pub fn segment(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon::n_gon(teta, 2, sound)
|
|
}
|
|
|
|
pub fn triangle(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon::n_gon(teta, 3, sound)
|
|
}
|
|
|
|
pub fn square(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon::n_gon(teta, 4, sound)
|
|
}
|
|
|
|
pub fn nr_6_in_30(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon {
|
|
sound: sound,
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
global_teta: teta,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
points_teta: vec![
|
|
2.0 * 5.0 * PI / 30.0,
|
|
2.0 * 6.0 * PI / 30.0,
|
|
2.0 * 12.0 * PI / 30.0,
|
|
2.0 * 18.0 * PI / 30.0,
|
|
2.0 * 24.0 * PI / 30.0,
|
|
2.0 * 25.0 * PI / 30.0,
|
|
],
|
|
}
|
|
}
|
|
pub fn nr_7_in_30(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon {
|
|
sound: sound,
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
global_teta: teta,
|
|
points_teta: vec![
|
|
0.0,
|
|
2.0 * 6.0 * PI / 30.0,
|
|
2.0 * 7.0 * PI / 30.0,
|
|
2.0 * 13.0 * PI / 30.0,
|
|
2.0 * 17.0 * PI / 30.0,
|
|
2.0 * 23.0 * PI / 30.0,
|
|
2.0 * 24.0 * PI / 30.0,
|
|
],
|
|
}
|
|
}
|
|
pub fn nr_8_in_30(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon {
|
|
sound: sound,
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
global_teta: teta,
|
|
points_teta: vec![
|
|
2.0 * PI / 30.0,
|
|
2.0 * 5.0 * PI / 30.0,
|
|
2.0 * 11.0 * PI / 30.0,
|
|
2.0 * 12.0 * PI / 30.0,
|
|
2.0 * 18.0 * PI / 30.0,
|
|
2.0 * 19.0 * PI / 30.0,
|
|
2.0 * 25.0 * PI / 30.0,
|
|
2.0 * 29.0 * PI / 30.0,
|
|
],
|
|
}
|
|
}
|
|
pub fn nr_9_in_30(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon {
|
|
sound: sound,
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
global_teta: teta,
|
|
points_teta: vec![
|
|
0.0,
|
|
2.0 * PI / 30.0,
|
|
2.0 * 7.0 * PI / 30.0,
|
|
2.0 * 11.0 * PI / 30.0,
|
|
2.0 * 13.0 * PI / 30.0,
|
|
2.0 * 17.0 * PI / 30.0,
|
|
2.0 * 19.0 * PI / 30.0,
|
|
2.0 * 23.0 * PI / 30.0,
|
|
2.0 * 29.0 * PI / 30.0,
|
|
],
|
|
}
|
|
}
|
|
pub fn nr_8_in_42(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon {
|
|
sound: sound,
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
global_teta: teta,
|
|
points_teta: vec![
|
|
2.0 * 3.0 * PI / 42.0,
|
|
2.0 * 9.0 * PI / 42.0,
|
|
2.0 * 14.0 * PI / 42.0,
|
|
2.0 * 15.0 * PI / 42.0,
|
|
2.0 * 27.0 * PI / 42.0,
|
|
2.0 * 28.0 * PI / 42.0,
|
|
2.0 * 33.0 * PI / 42.0,
|
|
2.0 * 39.0 * PI / 42.0,
|
|
],
|
|
}
|
|
}
|
|
pub fn nr_9_in_42(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon {
|
|
sound: sound,
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
global_teta: teta,
|
|
points_teta: vec![
|
|
0.0,
|
|
2.0 * 6.0 * PI / 42.0,
|
|
2.0 * 11.0 * PI / 42.0,
|
|
2.0 * 12.0 * PI / 42.0,
|
|
2.0 * 17.0 * PI / 42.0,
|
|
2.0 * 25.0 * PI / 42.0,
|
|
2.0 * 30.0 * PI / 42.0,
|
|
2.0 * 31.0 * PI / 42.0,
|
|
2.0 * 36.0 * PI / 42.0,
|
|
],
|
|
}
|
|
}
|
|
pub fn nr_10a_in_42(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon {
|
|
sound: sound,
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
global_teta: teta,
|
|
points_teta: vec![
|
|
2.0 * 6.0 * PI / 42.0,
|
|
2.0 * 7.0 * PI / 42.0,
|
|
2.0 * 11.0 * PI / 42.0,
|
|
2.0 * 12.0 * PI / 42.0,
|
|
2.0 * 17.0 * PI / 42.0,
|
|
2.0 * 25.0 * PI / 42.0,
|
|
2.0 * 30.0 * PI / 42.0,
|
|
2.0 * 31.0 * PI / 42.0,
|
|
2.0 * 35.0 * PI / 42.0,
|
|
2.0 * 36.0 * PI / 42.0,
|
|
],
|
|
}
|
|
}
|
|
pub fn nr_10b_in_42(teta: f32, sound: StaticSoundData) -> Self {
|
|
Polygon {
|
|
sound: sound,
|
|
name: "".to_string(),
|
|
color: Color::BLACK,
|
|
sound_name: "./assets/tick.ogg".to_string(),
|
|
color_name: "Black".to_string(),
|
|
global_teta: teta,
|
|
points_teta: vec![
|
|
0.0,
|
|
2.0 * 1.0 * PI / 42.0,
|
|
2.0 * 5.0 * PI / 42.0,
|
|
2.0 * 13.0 * PI / 42.0,
|
|
2.0 * 18.0 * PI / 42.0,
|
|
2.0 * 19.0 * PI / 42.0,
|
|
2.0 * 24.0 * PI / 42.0,
|
|
2.0 * 29.0 * PI / 42.0,
|
|
2.0 * 30.0 * PI / 42.0,
|
|
2.0 * 41.0 * PI / 42.0,
|
|
],
|
|
}
|
|
}
|
|
}
|