reorganizing the code

This commit is contained in:
Dietrich 2022-08-23 10:52:20 +02:00
parent d8a5c67fd5
commit ee2c869a03
Signed by: dietrich
GPG Key ID: F0CE5A20AB5C4B27
14 changed files with 327 additions and 280 deletions

View File

@ -1 +1 @@
*[x] Fix orientation after and during circles *[x] make the

View File

@ -1 +1,2 @@
pub mod angle; pub mod angle;
pub mod length;

View File

@ -0,0 +1,4 @@
use bevy_inspector_egui::Inspectable;
#[derive(Inspectable, Default, Copy, Clone, Debug)]
pub struct Length(pub f32);

View File

@ -1,5 +1,6 @@
mod datatypes; mod datatypes;
mod debug; mod debug;
mod paths;
mod primitives; mod primitives;
mod turtle; mod turtle;
mod turtle_movement; mod turtle_movement;
@ -14,8 +15,8 @@ fn main() {
.insert_resource(Msaa { samples: 4 }) .insert_resource(Msaa { samples: 4 })
.insert_resource(ClearColor(Color::BEIGE)) .insert_resource(ClearColor(Color::BEIGE))
.insert_resource(WindowDescriptor { .insert_resource(WindowDescriptor {
width: 400.0, width: 500.0,
height: 400.0, height: 500.0,
title: "Turtle Window".to_string(), title: "Turtle Window".to_string(),
present_mode: bevy::window::PresentMode::AutoVsync, present_mode: bevy::window::PresentMode::AutoVsync,
..default() ..default()

46
src/paths/circle_star.rs Normal file
View File

@ -0,0 +1,46 @@
use crate::{
datatypes::{angle::Angle, length::Length},
turtle::TurtleCommand,
};
#[allow(dead_code)]
pub fn circle_star() -> Vec<TurtleCommand> {
vec![
TurtleCommand::Right(Angle::degrees(36.)),
TurtleCommand::Forward(Length(200.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(200.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(200.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(200.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(200.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
]
}

View File

@ -0,0 +1,32 @@
use crate::{
datatypes::{angle::Angle, length::Length},
turtle::TurtleCommand,
};
#[allow(dead_code)]
pub fn geometry_task() -> Vec<TurtleCommand> {
vec![
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Backward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(45.)),
//TurtleCommand::PenUp,
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(50.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(50.)),
TurtleCommand::Right(Angle::degrees(45.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Left(Angle::degrees(120.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Left(Angle::degrees(120.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(150.)),
TurtleCommand::Forward(Length(100.)),
]
}

2
src/paths/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod circle_star;
pub mod geometry_task;

View File

@ -1,156 +1,4 @@
use bevy::prelude::{Bundle, Color, Component, Name, Quat, Transform, Vec2}; pub mod animation;
use bevy_prototype_lyon::{ pub mod bundles;
entity::ShapeBundle, pub mod components;
prelude::{DrawMode, FillMode, GeometryBuilder, Path, PathBuilder, ShapePath, StrokeMode}, pub mod turtle_primitives;
shapes::{self, Line},
};
use bevy_tweening::Lens;
use crate::datatypes::angle::Angle;
pub(crate) struct LineAnimationLens {
start: Vec2,
end: Vec2,
}
impl LineAnimationLens {
pub(crate) fn new(start: Vec2, end: Vec2) -> Self {
Self { start, end }
}
}
impl Lens<Path> for LineAnimationLens {
fn lerp(&mut self, target: &mut Path, ratio: f32) {
let line = shapes::Line(self.start, self.start + ((self.end - self.start) * ratio));
*target = ShapePath::build_as(&line);
}
}
#[derive(Bundle)]
pub(crate) struct TurtleDrawLine {
#[bundle]
line: ShapeBundle,
name: Name,
marker: LineMarker,
}
#[derive(Component, Default)]
struct LineMarker;
impl TurtleDrawLine {
pub(crate) fn new(start: Vec2, _end: Vec2, index: u64) -> Self {
Self {
line: GeometryBuilder::build_as(
&Line(start, start),
DrawMode::Outlined {
fill_mode: FillMode::color(Color::MIDNIGHT_BLUE),
outline_mode: StrokeMode::new(Color::BLACK, 1.0),
},
Transform::identity(),
),
name: Name::new(format!("Line {}", index)),
marker: LineMarker,
}
}
}
pub(crate) struct CircleAnimationLens {
pub start_pos: Vec2,
pub center: Vec2,
pub radii: Vec2,
pub start: Angle<f32>,
pub end: Angle<f32>,
}
impl Lens<Path> for CircleAnimationLens {
fn lerp(&mut self, target: &mut Path, ratio: f32) {
let mut path_builder = PathBuilder::new();
path_builder.move_to(self.start_pos);
// The center point of the radius, then the radii in x and y direction, then the angle that will be drawn, then the x_rotation ?
path_builder.arc(
self.center,
self.radii,
(self.start + ((self.end - self.start) * ratio))
.to_radians()
.value(),
0.,
);
let line = path_builder.build();
*target = ShapePath::build_as(&line);
}
}
pub(crate) struct CircleMovementLens {
pub center: Vec2,
pub start: Transform,
pub end: Angle<f32>,
}
impl Lens<Transform> for CircleMovementLens {
fn lerp(&mut self, target: &mut Transform, ratio: f32) {
let angle = self.end * ratio;
let mut rotated = self.start;
rotated.rotate_around(
self.center.extend(0.),
Quat::from_rotation_z(angle.to_radians().value()),
);
*target = rotated;
}
}
#[derive(Bundle)]
pub(crate) struct TurtleDrawCircle {
#[bundle]
line: ShapeBundle,
name: Name,
marker: CircleMarker,
}
#[derive(Component, Default)]
struct CircleMarker;
impl TurtleDrawCircle {
pub(crate) fn new(
center: Vec2,
radii: Vec2,
angle: Angle<f32>,
index: u64,
start: Vec2,
end: Vec2,
) -> Self {
let mut path_builder = PathBuilder::new();
path_builder.move_to(start);
// The center point of the radius, then the radii in x and y direction, then the angle that will be drawn, then the x_rotation ?
path_builder.arc(center, radii, angle.to_radians().value(), 0.);
/* println!("The radiuses: {}", radii);
path_builder.move_to(Vec2::ZERO);
path_builder.line_to(center);
path_builder.line_to(Vec2::new(radii.x, 0.) + center);
path_builder.move_to(center);
path_builder.line_to(Vec2::new(0., radii.y) + center);
path_builder.move_to(center);
path_builder.line_to(
center + Vec2::new(radii.x.abs(), 0.).rotate(Vec2::from_angle(angle.0.to_radians())),
);
path_builder.move_to(center); */
let line = path_builder.build();
println!("Draw Circle: {} {} {:?}", center, radii, angle);
Self {
line: GeometryBuilder::build_as(
&line,
DrawMode::Outlined {
fill_mode: FillMode::color(Color::rgba(0., 0., 0., 0.)),
outline_mode: StrokeMode::new(Color::BLACK, 1.0),
},
Transform::identity(),
),
name: Name::new(format!("Circle {}", index)),
marker: CircleMarker,
}
}
}

View File

@ -0,0 +1,72 @@
use bevy::prelude::{Quat, Transform, Vec2};
use bevy_prototype_lyon::{
prelude::{Path, PathBuilder, ShapePath},
shapes,
};
use bevy_tweening::Lens;
use crate::datatypes::angle::Angle;
pub(crate) struct LineAnimationLens {
start: Vec2,
end: Vec2,
}
impl LineAnimationLens {
pub(crate) fn new(start: Vec2, end: Vec2) -> Self {
Self { start, end }
}
}
impl Lens<Path> for LineAnimationLens {
fn lerp(&mut self, target: &mut Path, ratio: f32) {
let line = shapes::Line(self.start, self.start + ((self.end - self.start) * ratio));
*target = ShapePath::build_as(&line);
}
}
pub(crate) struct CircleAnimationLens {
pub start_pos: Vec2,
pub center: Vec2,
pub radii: Vec2,
pub start: Angle<f32>,
pub end: Angle<f32>,
}
impl Lens<Path> for CircleAnimationLens {
fn lerp(&mut self, target: &mut Path, ratio: f32) {
let mut path_builder = PathBuilder::new();
path_builder.move_to(self.start_pos);
// The center point of the radius, then the radii in x and y direction, then the angle that will be drawn, then the x_rotation ?
path_builder.arc(
self.center,
self.radii,
(self.start + ((self.end - self.start) * ratio))
.to_radians()
.value(),
0.,
);
let line = path_builder.build();
*target = ShapePath::build_as(&line);
}
}
pub(crate) struct CircleMovementLens {
pub center: Vec2,
pub start: Transform,
pub end: Angle<f32>,
}
impl Lens<Transform> for CircleMovementLens {
fn lerp(&mut self, target: &mut Transform, ratio: f32) {
let angle = self.end * ratio;
let mut rotated = self.start;
rotated.rotate_around(
self.center.extend(0.),
Quat::from_rotation_z(angle.to_radians().value()),
);
*target = rotated;
}
}

123
src/primitives/bundles.rs Normal file
View File

@ -0,0 +1,123 @@
use bevy::prelude::{Bundle, Color, Component, Name, Transform, Vec2};
use bevy_prototype_lyon::{
entity::ShapeBundle,
prelude::{DrawMode, FillMode, GeometryBuilder, PathBuilder, StrokeMode},
shapes::Line,
};
use crate::{
datatypes::angle::Angle,
turtle::{Colors, TurtleCommand, TurtleCommands},
};
#[derive(Bundle)]
pub(crate) struct TurtleDrawLine {
#[bundle]
line: ShapeBundle,
name: Name,
marker: LineMarker,
}
#[derive(Component, Default)]
struct LineMarker;
impl TurtleDrawLine {
pub(crate) fn new(start: Vec2, _end: Vec2, index: u64) -> Self {
Self {
line: GeometryBuilder::build_as(
&Line(start, start),
DrawMode::Outlined {
fill_mode: FillMode::color(Color::MIDNIGHT_BLUE),
outline_mode: StrokeMode::new(Color::BLACK, 1.0),
},
Transform::identity(),
),
name: Name::new(format!("Line {}", index)),
marker: LineMarker,
}
}
}
#[derive(Bundle)]
pub(crate) struct TurtleDrawCircle {
#[bundle]
line: ShapeBundle,
name: Name,
marker: CircleMarker,
}
#[derive(Component, Default)]
struct CircleMarker;
impl TurtleDrawCircle {
pub(crate) fn new(
center: Vec2,
radii: Vec2,
angle: Angle<f32>,
index: u64,
start: Vec2,
end: Vec2,
) -> Self {
let mut path_builder = PathBuilder::new();
path_builder.move_to(start);
// The center point of the radius - this is responsible for the orientation of the ellipse,
// then the radii in x and y direction - this can be rotated using the x_rotation parameter,
// then the angle - the part of the circle that will be drawn like (PI/2.0) for a quarter circle,
// then the x_rotation (maybe the rotation of the radii?)
path_builder.arc(center, radii, angle.to_radians().value(), 0.);
let line = path_builder.build();
println!("Draw Circle: {} {} {:?}", center, radii, angle);
Self {
line: GeometryBuilder::build_as(
&line,
DrawMode::Outlined {
fill_mode: FillMode::color(Color::rgba(0., 0., 0., 0.)),
outline_mode: StrokeMode::new(Color::BLACK, 1.0),
},
Transform::identity(),
),
name: Name::new(format!("Circle {}", index)),
marker: CircleMarker,
}
}
}
#[derive(Bundle)]
pub struct Turtle {
colors: Colors,
commands: TurtleCommands,
name: Name,
}
impl Default for Turtle {
fn default() -> Self {
Self {
colors: Colors::default(),
commands: TurtleCommands::new(vec![]),
name: Name::new("Turtle"),
}
}
}
impl Turtle {
/* pub fn set_color(&mut self, color: Color) {
self.colors.color = color;
}
pub fn set_fill_color(&mut self, color: Color) {
self.colors.fill_color = color;
}
pub fn get_colors(&self) -> &Colors {
&self.colors
}
pub fn forward(&mut self) -> &mut Self {
self.commands
.commands
.push(TurtleCommand::Forward(Length(100.0)));
self
} */
pub fn set_commands(&mut self, commands: Vec<TurtleCommand>) {
self.commands = TurtleCommands::new(commands);
}
}

View File

View File

@ -0,0 +1,23 @@
use bevy::prelude::Vec2;
use crate::{datatypes::angle::Angle, turtle::Precision};
pub struct TurtleAction {
heading: Angle<Precision>,
position: Vec2,
primitive: TurtleActionType,
}
pub enum TurtleActionType {
Straight {
target: Vec2,
},
Rotate {
angle: Angle<Precision>,
},
Circle {
center: Vec2,
radii: Vec2,
extent: Angle<Precision>,
},
}

View File

@ -8,9 +8,14 @@ use bevy_tweening::{
TweenCompleted, TweeningPlugin, TweeningType, TweenCompleted, TweeningPlugin, TweeningType,
}; };
#[allow(unused_imports)]
use crate::paths::{circle_star::circle_star, geometry_task::geometry_task};
use crate::{ use crate::{
datatypes::angle::Angle, datatypes::{angle::Angle, length::Length},
primitives::{CircleAnimationLens, LineAnimationLens, TurtleDrawCircle, TurtleDrawLine}, primitives::{
animation::{CircleAnimationLens, LineAnimationLens},
bundles::{Turtle, TurtleDrawCircle, TurtleDrawLine},
},
turtle_shapes, turtle_shapes,
}; };
@ -27,116 +32,7 @@ impl Plugin for TurtlePlugin {
.register_inspectable::<TurtleCommands>(); .register_inspectable::<TurtleCommands>();
} }
} }
#[derive(Bundle)] pub type Precision = f32;
pub struct Turtle {
colors: Colors,
commands: TurtleCommands,
name: Name,
}
impl Default for Turtle {
fn default() -> Self {
Self {
colors: Colors {
color: Color::DARK_GRAY,
fill_color: Color::BLACK,
},
commands: TurtleCommands::new(vec![
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Circle {
radius: Length(20.),
angle: Angle::degrees(324.),
},
TurtleCommand::Right(Angle::degrees(90.)),
TurtleCommand::Forward(Length(100.)),
/* TurtleCommand::Forward(Length(100.)),
TurtleCommand::Circle {
radius: Length(70.),
angle: Angle::degrees(60.),
},
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle::degrees(70.)),
//TurtleCommand::PenDown,
TurtleCommand::Circle {
radius: Length(30.),
angle: Angle::degrees(360. - 46.),
}, */
/* TurtleCommand::Backward(Length(100.)),
TurtleCommand::Right(Angle(90.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle(45.)),
//TurtleCommand::PenUp,
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle(90.)),
TurtleCommand::Forward(Length(50.)),
TurtleCommand::Right(Angle(90.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle(90.)),
TurtleCommand::Forward(Length(50.)),
TurtleCommand::Right(Angle(45.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Left(Angle(120.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Left(Angle(120.)),
TurtleCommand::Forward(Length(100.)),
TurtleCommand::Right(Angle(150.)),
TurtleCommand::Forward(Length(100.)), */
]),
name: Name::new("Turtle"),
}
}
}
impl Turtle {
/* pub fn set_color(&mut self, color: Color) {
self.colors.color = color;
}
pub fn set_fill_color(&mut self, color: Color) {
self.colors.fill_color = color;
}
pub fn get_colors(&self) -> &Colors {
&self.colors
}
pub fn forward(&mut self) -> &mut Self {
self.commands
.commands
.push(TurtleCommand::Forward(Length(100.0)));
self
} */
}
#[derive(Component, Inspectable)] #[derive(Component, Inspectable)]
pub struct TurtleCommands { pub struct TurtleCommands {
@ -154,7 +50,7 @@ pub struct TurtleState {
} }
impl TurtleCommands { impl TurtleCommands {
fn new(commands: Vec<TurtleCommand>) -> Self { pub fn new(commands: Vec<TurtleCommand>) -> Self {
Self { Self {
commands, commands,
lines: vec![], lines: vec![],
@ -229,15 +125,12 @@ pub enum TurtleGraphElement {
#[derive(Clone, Component, Inspectable)] #[derive(Clone, Component, Inspectable)]
pub struct TurtleShape; pub struct TurtleShape;
#[derive(Clone, Component, Inspectable)] #[derive(Clone, Component, Inspectable, Default)]
pub struct Colors { pub struct Colors {
color: Color, color: Color,
fill_color: Color, fill_color: Color,
} }
#[derive(Inspectable, Default, Copy, Clone, Debug)]
pub struct Length(f32);
#[derive(Component, Inspectable, Default)] #[derive(Component, Inspectable, Default)]
pub enum TurtleCommand { pub enum TurtleCommand {
Forward(Length), Forward(Length),
@ -265,8 +158,10 @@ fn setup(mut commands: Commands) {
}, },
)); ));
commands.spawn_bundle(Camera2dBundle::default()); commands.spawn_bundle(Camera2dBundle::default());
let mut turtle_bundle = Turtle::default();
turtle_bundle.set_commands(geometry_task());
commands commands
.spawn_bundle(Turtle::default()) .spawn_bundle(turtle_bundle)
.insert_bundle(GeometryBuilder::build_as( .insert_bundle(GeometryBuilder::build_as(
&turtle_shapes::turtle(), &turtle_shapes::turtle(),
DrawMode::Outlined { DrawMode::Outlined {

View File

@ -1,14 +1,14 @@
use std::{f32::consts::PI, time::Duration}; use std::time::Duration;
use bevy::prelude::{Quat, Transform, Vec2, Vec3}; use bevy::prelude::{Quat, Transform, Vec2, Vec3};
use bevy_tweening::{ use bevy_tweening::{
lens::{TransformPositionLens, TransformRotateAxisLens, TransformRotateZLens}, lens::{TransformPositionLens, TransformRotateZLens},
EaseFunction, Tween, TweeningType, EaseFunction, Tween, TweeningType,
}; };
use crate::{ use crate::{
datatypes::angle::Angle, datatypes::angle::Angle,
primitives::{CircleAnimationLens, CircleMovementLens}, primitives::animation::CircleMovementLens,
turtle::{TurtleGraphElement, TurtleState}, turtle::{TurtleGraphElement, TurtleState},
}; };