From 140ab5181147e727166573da16e509c81c53385f Mon Sep 17 00:00:00 2001 From: Dukantic Date: Thu, 29 May 2025 22:05:37 +0200 Subject: [PATCH] polygon struct and draw polygons --- src/main.rs | 38 ++++++++++++--------- src/polygon_draw.rs | 82 +++++++++++++++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 41 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1a7b4d9..635e4bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,18 @@ mod polygon_draw; use iced::{ - Task, + Settings, Task, Theme, time::{self, Duration}, widget::{button, canvas, column, row, text}, }; -use polygon_draw::PolygonFrame; +use polygon_draw::{Polygon, PolygonFrame}; use std::f32::consts::PI; use std::time::Instant; fn main() -> iced::Result { iced::application("My App", MyApp::update, MyApp::view) + .theme(|_| Theme::Dark) .subscription(MyApp::subscription) .run_with(MyApp::new) } @@ -26,18 +27,18 @@ enum Message { struct MyApp { polys: PolygonFrame, time_last_frame: Instant, - revo_per_sec: u32, + nb_sec_for_rev: u32, } impl MyApp { fn new() -> (Self, Task) { ( Self { - revo_per_sec: 1, + nb_sec_for_rev: 4, time_last_frame: Instant::now(), polys: PolygonFrame { - radius: 128.0, teta: 0.0, + polygons: vec![Polygon::triangle(0.0), Polygon::triangle(PI / 2.0)], }, }, Task::none(), @@ -45,17 +46,17 @@ impl MyApp { } fn update(&mut self, message: Message) { match message { - Message::ButtonPressedIncrement => self.revo_per_sec += 1, + Message::ButtonPressedIncrement => self.nb_sec_for_rev += 1, Message::ButtonPressedDecrement => { - if self.revo_per_sec > 1 { - self.revo_per_sec -= 1 + if self.nb_sec_for_rev > 1 { + self.nb_sec_for_rev -= 1 } } Message::Tick => { let time_btw = Instant::now().duration_since(self.time_last_frame); self.polys.teta += 2.0 * PI - * (1.0 / self.revo_per_sec as f32) + * (1.0 / self.nb_sec_for_rev as f32) * (time_btw.as_millis() as f32 / 1_000.0); self.polys.teta %= 2.0 * PI; //println!("Teta : {}", self.polys.teta); @@ -65,18 +66,23 @@ impl MyApp { } fn view(&self) -> iced::Element { - let txt_nb_rev = format!("Revolution per second : {}", self.revo_per_sec); + let txt_nb_rev = format!("Revolution per second : {}", self.nb_sec_for_rev); column![ - text(txt_nb_rev), + text("Polymusic").size(32.0), row![ - button("Increment").on_press(Message::ButtonPressedIncrement), - button("Decrement").on_press(Message::ButtonPressedDecrement), - ], - canvas(&self.polys).height(500).width(500), + canvas(&self.polys).height(500).width(500), + column![ + text(txt_nb_rev), + row![ + button("Increment").on_press(Message::ButtonPressedIncrement), + button("Decrement").on_press(Message::ButtonPressedDecrement), + ], + ], + ] ] .into() } fn subscription(&self) -> iced::Subscription { - time::every(Duration::from_millis(16)).map(|_| Message::Tick) + time::every(Duration::from_millis(1)).map(|_| Message::Tick) } } diff --git a/src/polygon_draw.rs b/src/polygon_draw.rs index aaad4b0..7786979 100644 --- a/src/polygon_draw.rs +++ b/src/polygon_draw.rs @@ -12,17 +12,16 @@ pub trait RotationExt { } impl RotationExt for Vector { - fn rotate(&mut self, teta: f32) -> Self { - let temp_x = self.x; - let temp_y = self.y; - self.x = temp_x * teta.cos() - temp_y * teta.sin(); - self.y = temp_x * teta.sin() + temp_y * teta.cos(); - *self + 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 radius: f32, pub teta: f32, + pub polygons: Vec, } impl canvas::Program for PolygonFrame { @@ -37,27 +36,34 @@ impl canvas::Program for PolygonFrame { bounds: Rectangle, _cursor: mouse::Cursor, ) -> Vec { - // We prepare a new `Frame` 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(); - // We create a `Path` representing a simple circle - let circle = canvas::Path::circle(frame.center(), self.radius); - let mut vec = Vector::new(0.0, -self.radius); - let line = canvas::Path::line( - frame.center() + vec, - frame.center() + vec.rotate(2.0 * PI / 3.0), - ); - let dot = canvas::Path::circle(frame.center() + vec.rotate(self.teta), 10.0); + // 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: 5.0, + style: Style::Solid(Color::BLACK), + ..Stroke::default() + }, + ); + } + } - frame.stroke( - &line, - Stroke { - width: 5.0, - ..Stroke::default() - }, - ); - - // And fill it with some color + // Draw Circle + let circle = canvas::Path::circle(frame.center(), radius); frame.stroke( &circle, Stroke { @@ -66,9 +72,35 @@ impl canvas::Program for PolygonFrame { ..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()] } } + +pub struct Polygon { + pub global_teta: f32, + pub points_teta: Vec, +} + +impl Polygon { + pub fn triangle(teta: f32) -> Self { + Polygon { + global_teta: teta, + points_teta: vec![0.0, 2.0 * PI / 3.0, 4.0 * PI / 3.0], + } + } +}