From ec47191a4d41e23d540791b90e9cd0fa30b88e29 Mon Sep 17 00:00:00 2001 From: serr Date: Wed, 25 Jun 2025 16:12:48 +0300 Subject: [PATCH] left_forward/forward_left,... --- imgs/circle.png | Bin 0 -> 3705 bytes imgs/square.png | Bin 0 -> 2535 bytes output.png | Bin 2534 -> 3125 bytes src/main.rs | 46 +++++++++++++++++++------ src/turtle.rs | 89 +++++++++++++++++++++++++++++++++++------------- 5 files changed, 102 insertions(+), 33 deletions(-) create mode 100644 imgs/circle.png create mode 100644 imgs/square.png diff --git a/imgs/circle.png b/imgs/circle.png new file mode 100644 index 0000000000000000000000000000000000000000..a0d96186ffd38b7c187a9e19ae75521f338350f1 GIT binary patch literal 3705 zcmeHKZA_C_6uvFxLmk2}jsYr&Wi>cp>V|Pniwcv%6lP$}lrM!r)H0$3LDalVvoIDN zSR%&YsGG@fkN`pkDlwJJjR_Kd7y_(Wa4tZ?GLbY)LE5|L+?N&-f6V>c4-?4CbMC$8 z>z;GZLs{ak9i9vQ7c#~?b+OUA8B@GTzaC0R{tomDW^8ekE_!QHk>ao0E|=9GSN%M} z3m={RLd*d)!W*2bUZz$x?6qtVs6898+l+pt-c+} z`M}6JT?u6UN|M#6SyK-`-m1{0WLMXxMU%?@3Q|9sh0_YyPFEo$-?KQZzmq3O2-XqZmO4yeeg=A$s@YGjs_$@HH{56@F1PVt>&*4{nn1`AV? zM@bjYBjDo0_J4`mI9`0#A+6x9?L5p^tg@dwTEfcsM&@BJJ%`(AnC_*^-aaqB1UWv_ z-Bz_-!_Y$ru22#5G;lj==jNE!g#5I*%*jn#h1~ola~0M%IM;)o zj#K%hP7ZazPP^0oT%Oygdhi@m{=?881xRA5^Xp-MCdX4q@f6RCbEh1CP7~z&o$|Rn zESJ|c*RUS<+`40*4`&-&zFe5TfNfDL)_1>rX0p^lv$hn)}ZF_MY*=z(6eHs~~s580nR9UI_4d z#a#cF=ZJlc7&<(2o}7ji&NpIm@k*SJzyk*SE!qDa@7fbIKI~q=^T1EweXhqtn5@5r zXVhv|&WkTn#MfJnQ3~q!*j$mT!yA)NUNuKAug`2e3fET?Cf`x(FCa@O3~h0ap+V z01OZilglctfbIlCJP{cl3yLx$F=7@(LBKrDAUzz}<3^-sQd4tJ z1i2ZC21Ved?CJ~$?-3kt8>uwAMh%BH5lu)I;}i1<1gTdrDqAhFFk(!bOJpKu->!4g zsueO{n=TZL(VfQ2B5*9?9parIh2}cnE?LtWan4F22@HkMa6FFtAPvMDn+=pfYzzGmJ&V4NWRi zI%TjjW6_G%sqvsPaM*hLA#&b)DHpU8z{8wi-54W|-^ZOgFG_@?r!M~JD7qct6VOz$je*h+z%vb;b literal 0 HcmV?d00001 diff --git a/imgs/square.png b/imgs/square.png new file mode 100644 index 0000000000000000000000000000000000000000..8eb356fcc211b6bd8eee5fc80a76150524c8d882 GIT binary patch literal 2535 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&4kn<;H+e}V1_sV`o-U3d6^w5WFfUMvoObNv z|MGXeC(bM{@=jitdwUxcW%kUQ=CyvFk+IUdpJm&#s+P4|XJ1`^>)EQ+>we`kIy?o@ z@0mvFfewdy70;N`tMyE`|C|TLO1;)?5KqJNPycA#jHc1iJUUuNjg|wWMDLGJFidMG!JPVr1#)|d5gXdv(hiZez_ndRuJvM%L%kDP z!(ipuFda8;6b^skP;Z9Tkd(K|IenqovP5{fmQkSad&%&A?WL%_ygFj6zFih> zSTgB*uG@HdwZ3D~I_NMDWQJzF(l%CXkLPW^X5lp`a|@n4*6UM$6fXq0#b0zdsARK2 zpL&m?lmUkZZU;MiBq*&D{macaEC{v7+jVOjmLfZy4t02>q|c{*&vN8g={95?3%Mq3 zyqIO$<1@}yH~+Y!=C-$B6T58VAE6vKhn*LryD}>d1;K!SS-IgCIR`d@*YMk`kYx_t|>-{5gGIp$?}1`I15WlN6sdin20Mk%~V_?@Paf zpMloKuAo#vs0x9~R=N?L8hU>7V(f@+{>d+>o{Uw|kt!!e z6(TtgRJk5_>tej-I%lD>yo&^kt{ zQQs#;(GDbr^=}JWH<28q?a-!_o1znRfoOoQh5oD$Off+1%n+P8nqGek;9YtXWr|Z( zko7}tE%HIR;Q=M z$9teQSyTOcw5gsen3gmET@96zK+A8rCb`|&aWt4qI_ItaA|3jDIUnb#DF?XYbE8ID ztqgjjEXsFBhasKgYNDAB?VwERRX zH)xwcwDR2@HFRNI*m-;W3Bs=QJ1W3#0j`Em4N%VcHslP`GV!Naog6bw_~}I45%q*> z9o?yeiDS2tSJ*cNr=)?e-S3_f(2%Ku8d48v_g26eF^>kM=T~3RXTuFoBXH64YW`_( z%j>92WWsV9B^Eu2@OA)EQ+>we`kIy?o@ z@0mvF(Qp_|2PpaA|5KHZ_LFkgRXt=_5%YEb{M>)-6OV-cS7Oi#k1f4gFFr~SSUCKB zuim-(pE=WlqO1Rlw(WdXuQ?hS0~Q&hnPIdr7%dD5RSN$EU49Czi+|d_71(}b@O1Ta JS?83{1OUdBUL^nk diff --git a/src/main.rs b/src/main.rs index 92edce2..d8f458f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,45 @@ mod turtle; -use turtle::Turtle; +use turtle::{defaults, Turtle}; -fn square(turtle: &mut turtle::Turtle) { - turtle.left(90.0); - turtle.forward(5); +#[allow(dead_code)] +fn square() { + let mut turtle = Turtle::new(); + let default_pos = defaults::position(); + let steps_count = 20; + + turtle.set_pos(( + default_pos.0 - (turtle.step_length() * steps_count / 2) as i32, + default_pos.1 + (turtle.step_length() * steps_count / 2) as i32 + )); + + turtle.left_forward(90.0, steps_count); for _ in 0..3 { - turtle.right(90.0); - turtle.forward(5); + turtle.right_forward(90.0, steps_count); } + turtle.save("imgs/square.png").unwrap(); +} + +#[allow(dead_code)] +fn circle() { + let mut turtle = Turtle::new(); + let default_pos = defaults::position(); + + let circumference = (36 * 2 * defaults::STEP_LENGTH) as f64; + let radius = circumference / (2.0 * std::f64::consts::PI); + + turtle.set_pos(( + default_pos.0 - (turtle.step_length() * 2 / 2) as i32, + default_pos.1 - radius as i32 + )); + + for _ in 0..36 { + turtle.forward_right(2, 10.0); + } + turtle.save("imgs/circle.png").unwrap(); } fn main() { - let mut turtle = Turtle::new(); - - square(&mut turtle); - turtle.save("output.png").unwrap(); + square(); + circle(); } diff --git a/src/turtle.rs b/src/turtle.rs index f7edf83..0e05048 100644 --- a/src/turtle.rs +++ b/src/turtle.rs @@ -8,36 +8,50 @@ type ImgBufU8 = ImageBuffer, Vec>; type Colour = Rgb; type Coord = (i32, i32); -const DEFAULT_WIDTH: u32 = 300; -const DEFAULT_HEIGHT: u32 = 300; -const DEFAULT_BACKGROUND_COLOUR: Colour = Rgb([255u8, 255u8, 255u8]); -const DEFAULT_COLOUR: Colour = Rgb([0u8, 0u8, 0u8]); -const DEFAULT_POS: Coord = ((DEFAULT_WIDTH as f64/2.0) as i32, (DEFAULT_HEIGHT as f64/2.0) as i32); +pub mod defaults { + use super::{Colour, Coord, Rgb}; + + pub const WIDTH: u32 = 300; + pub const HEIGHT: u32 = 300; + pub const BACKGROUND_COLOUR: Colour = Rgb([255u8, 255u8, 255u8]); + pub const COLOUR: Colour = Rgb([0u8, 0u8, 0u8]); + pub const STEP_LENGTH: u32 = 10; + pub const ANGLE: f64 = 0.0; + + pub fn position() -> Coord { + ((WIDTH as f64 / 2.0) as i32, + (HEIGHT as f64 / 2.0) as i32) + } +} pub struct Turtle { buf: ImgBufU8, colour: Colour, pos: Coord, step_length: u32, - angle: f64, // угол в радианах + angle: f64, } impl Turtle { pub fn new() -> Self { - let mut buf = ImageBuffer::new(DEFAULT_WIDTH, DEFAULT_HEIGHT); + let mut buf = ImageBuffer::new(defaults::WIDTH, defaults::HEIGHT); for pixel in buf.pixels_mut() { - *pixel = DEFAULT_BACKGROUND_COLOUR; + *pixel = defaults::BACKGROUND_COLOUR; } Turtle { buf, - colour: DEFAULT_COLOUR, - pos: DEFAULT_POS, - step_length: 10, - angle: 0.0, + colour: defaults::COLOUR, + pos: defaults::position(), + step_length: defaults::STEP_LENGTH, + angle: defaults::ANGLE, } } + pub fn step_length(&self) -> u32 { + self.step_length + } + pub fn position(&self) -> Coord { self.pos } @@ -46,26 +60,55 @@ impl Turtle { self.angle.to_degrees() } + pub fn set_pos(&mut self, coord: Coord) { + self.pos.0 = coord.0; + self.pos.1 = coord.1; + } + + pub fn right(&mut self, degrees: f64) { + self.angle += degrees.to_radians(); + self.angle = self.angle.rem_euclid(2.0 * std::f64::consts::PI); + } + + pub fn right_forward(&mut self, degrees: f64, steps_count: u32) { + self.right(degrees); + self.forward(steps_count); + } + + pub fn forward_right(&mut self, steps_count: u32, degrees: f64) { + self.forward(steps_count); + self.right(degrees); + } + + pub fn left(&mut self, degrees: f64) { + self.angle -= degrees.to_radians(); + self.angle = self.angle.rem_euclid(2.0 * std::f64::consts::PI); + } + + pub fn left_forward(&mut self, degrees: f64, steps_count: u32) { + self.left(degrees); + self.forward(steps_count); + } + + pub fn forward_left(&mut self, steps_count: u32, degrees: f64) { + self.forward(steps_count); + self.left(degrees); + } + pub fn forward(&mut self, steps_count: u32) { let start_pos = self.pos; let dy = self.angle.sin() * steps_count as f64 * self.step_length as f64; let dx = self.angle.cos() * steps_count as f64 * self.step_length as f64; - self.pos.0 += dx.round() as i32; - self.pos.1 += dy.round() as i32; - + self.set_pos(( + self.pos.0 + dx.round() as i32, + self.pos.1 + dy.round() as i32 + )); + self.draw_line(start_pos, self.pos); } - pub fn right(&mut self, degrees: f64) { - self.angle += degrees.to_radians(); - } - - pub fn left(&mut self, degrees: f64) { - self.angle -= degrees.to_radians(); - } - pub fn save

(&self, output_path: P) -> ImageResult<()> where P: AsRef