From 728549253d7b9a0bd183f15a8980ff799b5db02e Mon Sep 17 00:00:00 2001 From: Franz Dietrich Date: Sun, 19 Oct 2025 16:39:42 +0200 Subject: [PATCH] some more examples --- turtle-lib/examples/empty_star.rs | 26 ++++++ turtle-lib/examples/flower.rs | 126 +++++++++++++++++++++++++++ turtle-lib/examples/geometric_art.rs | 87 ++++++++++++++++++ turtle-lib/examples/squares.rs | 27 ++++++ 4 files changed, 266 insertions(+) create mode 100644 turtle-lib/examples/empty_star.rs create mode 100644 turtle-lib/examples/flower.rs create mode 100644 turtle-lib/examples/geometric_art.rs create mode 100644 turtle-lib/examples/squares.rs diff --git a/turtle-lib/examples/empty_star.rs b/turtle-lib/examples/empty_star.rs new file mode 100644 index 0000000..d4ef2d2 --- /dev/null +++ b/turtle-lib/examples/empty_star.rs @@ -0,0 +1,26 @@ +//! Draw an empty 5-pointed star using straight lines. +//! Ported from the turtle crate example. + +use turtle_lib::*; + +#[turtle_main("Empty Star")] +fn draw(turtle: &mut TurtlePlan) { + let points = 5.0; + let angle = 180.0 / points; + + turtle + .set_pen_width(4.0) + .set_pen_color(YELLOW) + .pen_up() + .forward(150.0) + .right(180.0 - angle / 2.0) + .pen_down(); + + for _ in 0..5 { + turtle + .forward(100.0) + .left(angle * 2.0) + .forward(100.0) + .right(180.0 - angle); + } +} diff --git a/turtle-lib/examples/flower.rs b/turtle-lib/examples/flower.rs new file mode 100644 index 0000000..fadb0ed --- /dev/null +++ b/turtle-lib/examples/flower.rs @@ -0,0 +1,126 @@ +//! Draws a simple geometric sort of flower with customizable dimensions. +//! +//! This example makes extensive use of the turtle arc methods: circle_left and circle_right. +//! Ported from the turtle crate example. + +use turtle_lib::*; + +const BOTTOM_MARGIN: f32 = 25.0; + +const LEAF_FILL_COLOR: Color = Color { + r: 0.0, + g: 0.5, + b: 0.0, + a: 1.0, +}; // green +const LEAF_BORDER_COLOR: Color = Color { + r: 0.0, + g: 0.39, + b: 0.0, + a: 1.0, +}; // dark green +const LEAF_BORDER_WIDTH: f32 = 1.0; +const LEFT_LEAF_RADIUS: f32 = 200.0; +const LEFT_LEAF_EXTENT: f32 = 45.0; +const RIGHT_LEAF_INCLINATION: f32 = 15.0; +const RIGHT_LEAF_BOTTOM_RADIUS: f32 = 250.0; +const RIGHT_LEAF_BOTTOM_EXTENT: f32 = 45.0; +const RIGHT_LEAF_TOP_RADIUS: f32 = 157.0; +const RIGHT_LEAF_TOP_EXTENT: f32 = 75.0; + +const TRUNK_COLOR: Color = LEAF_BORDER_COLOR; +const TRUNK_WIDTH: f32 = 3.0; +const TRUNK_PIECE_COUNT: usize = 4; +const TRUNK_PIECE_RADIUS: f32 = 500.0; +const TRUNK_PIECE_EXTENT: f32 = 15.0; + +const PETALS_COUNT: usize = 4; +const PETALS_FILL_COLOR: Color = Color { + r: 0.5, + g: 0.0, + b: 0.5, + a: 1.0, +}; // purple +const PETALS_BORDER_COLOR: Color = Color { + r: 0.55, + g: 0.0, + b: 0.55, + a: 1.0, +}; // dark purple +const PETALS_BORDER_WIDTH: f32 = LEAF_BORDER_WIDTH; +const PETALS_INIT_LEFT: f32 = 65.0; +const PETALS_SIDE_RADIUS: f32 = 80.0; +const PETALS_SIDE_EXTENT: f32 = 90.0; +const PETALS_SPACE_GAP: f32 = 20.0; +const PETALS_SPACE_RADIUS: f32 = 40.0; +const PETALS_SPACE_EXTENT: f32 = 30.0; + +#[turtle_main("Flower")] +fn draw(turtle: &mut TurtlePlan) { + // Initial positioning - bottom left area + turtle + .pen_up() + .go_to(vec2(-100.0, -200.0 + BOTTOM_MARGIN)) + .left(90.0) + .pen_down(); + + // Setup + turtle + .set_fill_color(LEAF_FILL_COLOR) + .set_pen_color(LEAF_BORDER_COLOR); + + for _ in 0..TRUNK_PIECE_COUNT { + // Leaves + turtle + .set_pen_width(LEAF_BORDER_WIDTH) + .set_pen_color(LEAF_BORDER_COLOR) + .begin_fill(); + + // Left leaf + turtle + .circle_left(LEFT_LEAF_RADIUS, LEFT_LEAF_EXTENT, 45) + .right(LEFT_LEAF_EXTENT) + .circle_right(LEFT_LEAF_RADIUS, -LEFT_LEAF_EXTENT, 45) + .right(LEFT_LEAF_EXTENT); + + // Right leaf + turtle.right(RIGHT_LEAF_INCLINATION); + + // Note: circle_left with negative radius is same as circle_right + // Using circle_right with negative extent instead + turtle + .circle_right(RIGHT_LEAF_BOTTOM_RADIUS, RIGHT_LEAF_BOTTOM_EXTENT, 45) + .right(RIGHT_LEAF_INCLINATION) + .circle_right(RIGHT_LEAF_TOP_RADIUS, -RIGHT_LEAF_TOP_EXTENT, 75); + + // Trunk piece + turtle + .end_fill() + .set_pen_width(TRUNK_WIDTH) + .set_pen_color(TRUNK_COLOR) + .circle_right(TRUNK_PIECE_RADIUS, TRUNK_PIECE_EXTENT, 50); + } + + // Petals + turtle + .set_fill_color(PETALS_FILL_COLOR) + .set_pen_color(PETALS_BORDER_COLOR) + .set_pen_width(PETALS_BORDER_WIDTH) + .left(PETALS_INIT_LEFT) + .begin_fill() + .circle_right(PETALS_SIDE_RADIUS, PETALS_SIDE_EXTENT, 90); + + for _ in 0..PETALS_COUNT { + turtle + .left(PETALS_SPACE_GAP) + .circle_right(PETALS_SPACE_RADIUS, -PETALS_SPACE_EXTENT, 30) + .right(2.0 * PETALS_SPACE_GAP + PETALS_SPACE_EXTENT) + .circle_left(PETALS_SPACE_RADIUS, PETALS_SPACE_EXTENT, 30); + } + + // Finish petals with error adjustments + turtle + .left(PETALS_SPACE_GAP) + .circle_left(PETALS_SIDE_RADIUS + 1.0, 3.0 - PETALS_SIDE_EXTENT, 87) + .end_fill(); +} diff --git a/turtle-lib/examples/geometric_art.rs b/turtle-lib/examples/geometric_art.rs new file mode 100644 index 0000000..3022bde --- /dev/null +++ b/turtle-lib/examples/geometric_art.rs @@ -0,0 +1,87 @@ +//! Creates colorful geometric art with randomly colored triangles. +//! +//! Ported from the turtle crate example. + +use turtle_lib::*; +use macroquad::prelude::rand; + +// Parameters to play around with for changing the character of the drawing +const WIDTH: f32 = 800.0; +const HEIGHT: f32 = 600.0; +const ROW_COUNT: u32 = 3; +const COL_COUNT: u32 = 4; +const COLOR_COUNT: usize = 7; + +/// Generate a random color +fn random_color() -> Color { + Color { + r: rand::gen_range(0.0, 1.0), + g: rand::gen_range(0.0, 1.0), + b: rand::gen_range(0.0, 1.0), + a: 1.0, + } +} + +#[turtle_main("Geometric Art")] +fn draw(turtle: &mut TurtlePlan) { + // Calculate height and width of the triangles + let row_height = HEIGHT / ROW_COUNT as f32; + let col_width = WIDTH / COL_COUNT as f32; + + // Prepare a set of random colors to randomly choose from when drawing + let colors: Vec = (0..COLOR_COUNT).map(|_| random_color()).collect(); + + // Move turtle to the upper left corner of the drawing + let x_start = -WIDTH / 2.0; + let y_start = HEIGHT / 2.0; + + turtle.pen_up().go_to(vec2(x_start, y_start)).pen_down(); + + // Draw all rows + for _ in 0..ROW_COUNT { + // Create an endless loop over the angles of 90 and 270 degrees + // (corresponds to moving right and left, respectively) + let mut angle_iter = [90.0, 270.0].iter().cycle(); + + // Create triangles from left to right + for _ in 0..COL_COUNT { + let angle = *angle_iter.next().unwrap(); + draw_triangle(turtle, angle, col_width, row_height, &colors); + } + + // Skip one angle so that we have the correct angle when turning around + angle_iter.next(); + + // Fill in triangles from right to left to complete the row + for _ in 0..COL_COUNT { + let angle = *angle_iter.next().unwrap(); + draw_triangle(turtle, angle, col_width, row_height, &colors); + } + + // Reset position to prepare for the next row + turtle.right(180.0).forward(row_height).left(180.0); + } +} + +/// Draw a single triangle by drawing two sides and filling them with a random color +/// which creates the third side of the triangle along the way. +fn draw_triangle( + turtle: &mut TurtlePlan, + angle: f32, + col_width: f32, + row_height: f32, + colors: &[Color], +) { + // Choose a random color + let color_index = rand::gen_range(0, colors.len()); + let color = colors[color_index]; + + turtle + .set_fill_color(color) + .begin_fill() + .right(angle) + .forward(col_width) + .right(angle) + .forward(row_height) + .end_fill(); +} diff --git a/turtle-lib/examples/squares.rs b/turtle-lib/examples/squares.rs new file mode 100644 index 0000000..a9b3529 --- /dev/null +++ b/turtle-lib/examples/squares.rs @@ -0,0 +1,27 @@ +use turtle_lib::*; + +#[turtle_main("Squares")] +fn draw(turtle: &mut TurtlePlan) { + turtle.set_speed(1000); + for i in 0..36 { + let base_color = if i % 2 == 0 { + Color::new(1.0, 0.0, 0.0, 1.0) // red + } else { + Color::new(1.0, 1.0, 1.0, 1.0) // white + }; + let alpha = (1.0 - i as f64 / 54.0) as f32; + let fill_color = Color::new(base_color.r, base_color.g, base_color.b, alpha); + turtle.set_fill_color(fill_color); + turtle.begin_fill(); + square(turtle); + turtle.end_fill(); + turtle.right(10.0); + } +} + +fn square(turtle: &mut TurtlePlan) { + for _ in 0..4 { + turtle.forward(200.0); + turtle.right(90.0); + } +}