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 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 debug;
mod paths;
mod primitives;
mod turtle;
mod turtle_movement;
@ -14,8 +15,8 @@ fn main() {
.insert_resource(Msaa { samples: 4 })
.insert_resource(ClearColor(Color::BEIGE))
.insert_resource(WindowDescriptor {
width: 400.0,
height: 400.0,
width: 500.0,
height: 500.0,
title: "Turtle Window".to_string(),
present_mode: bevy::window::PresentMode::AutoVsync,
..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};
use bevy_prototype_lyon::{
entity::ShapeBundle,
prelude::{DrawMode, FillMode, GeometryBuilder, Path, PathBuilder, ShapePath, StrokeMode},
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,
}
}
}
pub mod animation;
pub mod bundles;
pub mod components;
pub mod turtle_primitives;

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,
};
#[allow(unused_imports)]
use crate::paths::{circle_star::circle_star, geometry_task::geometry_task};
use crate::{
datatypes::angle::Angle,
primitives::{CircleAnimationLens, LineAnimationLens, TurtleDrawCircle, TurtleDrawLine},
datatypes::{angle::Angle, length::Length},
primitives::{
animation::{CircleAnimationLens, LineAnimationLens},
bundles::{Turtle, TurtleDrawCircle, TurtleDrawLine},
},
turtle_shapes,
};
@ -27,116 +32,7 @@ impl Plugin for TurtlePlugin {
.register_inspectable::<TurtleCommands>();
}
}
#[derive(Bundle)]
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
} */
}
pub type Precision = f32;
#[derive(Component, Inspectable)]
pub struct TurtleCommands {
@ -154,7 +50,7 @@ pub struct TurtleState {
}
impl TurtleCommands {
fn new(commands: Vec<TurtleCommand>) -> Self {
pub fn new(commands: Vec<TurtleCommand>) -> Self {
Self {
commands,
lines: vec![],
@ -229,15 +125,12 @@ pub enum TurtleGraphElement {
#[derive(Clone, Component, Inspectable)]
pub struct TurtleShape;
#[derive(Clone, Component, Inspectable)]
#[derive(Clone, Component, Inspectable, Default)]
pub struct Colors {
color: Color,
fill_color: Color,
}
#[derive(Inspectable, Default, Copy, Clone, Debug)]
pub struct Length(f32);
#[derive(Component, Inspectable, Default)]
pub enum TurtleCommand {
Forward(Length),
@ -265,8 +158,10 @@ fn setup(mut commands: Commands) {
},
));
commands.spawn_bundle(Camera2dBundle::default());
let mut turtle_bundle = Turtle::default();
turtle_bundle.set_commands(geometry_task());
commands
.spawn_bundle(Turtle::default())
.spawn_bundle(turtle_bundle)
.insert_bundle(GeometryBuilder::build_as(
&turtle_shapes::turtle(),
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_tweening::{
lens::{TransformPositionLens, TransformRotateAxisLens, TransformRotateZLens},
lens::{TransformPositionLens, TransformRotateZLens},
EaseFunction, Tween, TweeningType,
};
use crate::{
datatypes::angle::Angle,
primitives::{CircleAnimationLens, CircleMovementLens},
primitives::animation::CircleMovementLens,
turtle::{TurtleGraphElement, TurtleState},
};