Finalize the circle command
This commit is contained in:
parent
d16607ff4d
commit
d8a5c67fd5
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -2933,18 +2933,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.143"
|
version = "1.0.144"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
|
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.143"
|
version = "1.0.144"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
|
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -8,9 +8,9 @@ default-run = "turtlers"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.8", features = ["dynamic"] }
|
bevy = { version = "0.8", features = ["dynamic"] }
|
||||||
bevy-inspector-egui = "0.12.1"
|
bevy-inspector-egui = "0.12"
|
||||||
bevy_prototype_lyon = "0.6"
|
bevy_prototype_lyon = "0.6"
|
||||||
bevy_tweening = "0.5.0"
|
bevy_tweening = "0.5"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
|
|
||||||
# Enable a small amount of optimization in debug mode
|
# Enable a small amount of optimization in debug mode
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use bevy_inspector_egui::Inspectable;
|
use bevy_inspector_egui::Inspectable;
|
||||||
use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
|
use std::{
|
||||||
|
f32::consts::PI,
|
||||||
|
ops::{Add, Div, Mul, Neg, Rem, Sub},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Inspectable, Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Inspectable, Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum AngleUnit<T: Default> {
|
pub enum AngleUnit<T: Default> {
|
||||||
@ -40,6 +43,18 @@ impl<T: Default + Clone + Mul<T, Output = T>> Mul<T> for Angle<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Angle<f32> {
|
||||||
|
pub fn limit_smaller_than_full_circle(self) -> Self {
|
||||||
|
match self.value {
|
||||||
|
AngleUnit::Degrees(v) => Self {
|
||||||
|
value: AngleUnit::Degrees(v % 360.),
|
||||||
|
},
|
||||||
|
AngleUnit::Radians(v) => Self {
|
||||||
|
value: AngleUnit::Radians(v % (2. * PI)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl<T: Default + Clone + Div<T, Output = T>> Div<T> for Angle<T> {
|
impl<T: Default + Clone + Div<T, Output = T>> Div<T> for Angle<T> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
@ -101,6 +116,14 @@ impl<T: Default + num_traits::float::Float> Angle<T> {
|
|||||||
AngleUnit::Radians(_) => self,
|
AngleUnit::Radians(_) => self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn to_degrees(self) -> Self {
|
||||||
|
match self.value {
|
||||||
|
AngleUnit::Degrees(_) => self,
|
||||||
|
AngleUnit::Radians(v) => Self {
|
||||||
|
value: AngleUnit::Degrees(v.to_degrees()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Add<Output = T> + Default + num_traits::float::Float> Add for Angle<T> {
|
impl<T: Add<Output = T> + Default + num_traits::float::Float> Add for Angle<T> {
|
||||||
|
@ -42,12 +42,47 @@ impl Default for Turtle {
|
|||||||
fill_color: Color::BLACK,
|
fill_color: Color::BLACK,
|
||||||
},
|
},
|
||||||
commands: TurtleCommands::new(vec![
|
commands: TurtleCommands::new(vec![
|
||||||
TurtleCommand::Forward(Length(-100.)),
|
|
||||||
TurtleCommand::Circle {
|
|
||||||
radius: Length(150.),
|
|
||||||
angle: Angle::degrees(30.),
|
|
||||||
},
|
|
||||||
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::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 {
|
TurtleCommand::Circle {
|
||||||
radius: Length(70.),
|
radius: Length(70.),
|
||||||
angle: Angle::degrees(60.),
|
angle: Angle::degrees(60.),
|
||||||
@ -58,7 +93,7 @@ impl Default for Turtle {
|
|||||||
TurtleCommand::Circle {
|
TurtleCommand::Circle {
|
||||||
radius: Length(30.),
|
radius: Length(30.),
|
||||||
angle: Angle::degrees(360. - 46.),
|
angle: Angle::degrees(360. - 46.),
|
||||||
},
|
}, */
|
||||||
/* TurtleCommand::Backward(Length(100.)),
|
/* TurtleCommand::Backward(Length(100.)),
|
||||||
TurtleCommand::Right(Angle(90.)),
|
TurtleCommand::Right(Angle(90.)),
|
||||||
TurtleCommand::Forward(Length(100.)),
|
TurtleCommand::Forward(Length(100.)),
|
||||||
@ -113,6 +148,7 @@ pub struct TurtleCommands {
|
|||||||
pub struct TurtleState {
|
pub struct TurtleState {
|
||||||
pub start: Vec2,
|
pub start: Vec2,
|
||||||
pub heading: Angle<f32>,
|
pub heading: Angle<f32>,
|
||||||
|
pub speed: u64,
|
||||||
pub index: u64,
|
pub index: u64,
|
||||||
pub drawing: bool,
|
pub drawing: bool,
|
||||||
}
|
}
|
||||||
@ -125,6 +161,7 @@ impl TurtleCommands {
|
|||||||
state: TurtleState {
|
state: TurtleState {
|
||||||
start: Vec2::ZERO,
|
start: Vec2::ZERO,
|
||||||
heading: Angle::degrees(0.),
|
heading: Angle::degrees(0.),
|
||||||
|
speed: 2000,
|
||||||
index: 0,
|
index: 0,
|
||||||
drawing: true,
|
drawing: true,
|
||||||
},
|
},
|
||||||
@ -260,7 +297,7 @@ fn draw_lines(
|
|||||||
let line_animator = Animator::new(Tween::new(
|
let line_animator = Animator::new(Tween::new(
|
||||||
EaseFunction::QuadraticInOut,
|
EaseFunction::QuadraticInOut,
|
||||||
TweeningType::Once,
|
TweeningType::Once,
|
||||||
Duration::from_millis(500),
|
Duration::from_millis(tcmd.state.speed),
|
||||||
LineAnimationLens::new(start, end),
|
LineAnimationLens::new(start, end),
|
||||||
));
|
));
|
||||||
commands
|
commands
|
||||||
@ -278,7 +315,7 @@ fn draw_lines(
|
|||||||
let line_animator = Animator::new(Tween::new(
|
let line_animator = Animator::new(Tween::new(
|
||||||
EaseFunction::QuadraticInOut,
|
EaseFunction::QuadraticInOut,
|
||||||
TweeningType::Once,
|
TweeningType::Once,
|
||||||
Duration::from_millis(500),
|
Duration::from_millis(tcmd.state.speed),
|
||||||
CircleAnimationLens {
|
CircleAnimationLens {
|
||||||
start_pos: start,
|
start_pos: start,
|
||||||
center,
|
center,
|
||||||
@ -324,6 +361,7 @@ fn keypresses(
|
|||||||
tcmd.state = TurtleState {
|
tcmd.state = TurtleState {
|
||||||
start: Vec2::ZERO,
|
start: Vec2::ZERO,
|
||||||
heading: Angle::degrees(0.),
|
heading: Angle::degrees(0.),
|
||||||
|
speed: 2000,
|
||||||
index: 0,
|
index: 0,
|
||||||
drawing: true,
|
drawing: true,
|
||||||
};
|
};
|
||||||
@ -335,7 +373,7 @@ fn keypresses(
|
|||||||
let line_animator = Animator::new(Tween::new(
|
let line_animator = Animator::new(Tween::new(
|
||||||
EaseFunction::QuadraticInOut,
|
EaseFunction::QuadraticInOut,
|
||||||
TweeningType::Once,
|
TweeningType::Once,
|
||||||
Duration::from_millis(500),
|
Duration::from_millis(tcmd.state.speed),
|
||||||
LineAnimationLens::new(start, end),
|
LineAnimationLens::new(start, end),
|
||||||
));
|
));
|
||||||
commands
|
commands
|
||||||
|
@ -17,24 +17,24 @@ pub fn turtle_turn(
|
|||||||
angle_to_turn: Angle<f32>,
|
angle_to_turn: Angle<f32>,
|
||||||
) -> (Option<Tween<Transform>>, Option<TurtleGraphElement>) {
|
) -> (Option<Tween<Transform>>, Option<TurtleGraphElement>) {
|
||||||
let start = state.heading;
|
let start = state.heading;
|
||||||
let end = state.heading + (angle_to_turn * PI / 180.);
|
let end = state.heading + angle_to_turn;
|
||||||
let animation = Tween::new(
|
let animation = Tween::new(
|
||||||
// Use a quadratic easing on both endpoints
|
// Use a quadratic easing on both endpoints
|
||||||
EaseFunction::QuadraticInOut,
|
EaseFunction::QuadraticInOut,
|
||||||
TweeningType::Once,
|
TweeningType::Once,
|
||||||
// Animation time
|
// Animation time
|
||||||
Duration::from_millis(500),
|
Duration::from_millis(state.speed),
|
||||||
// Rotate the turtle
|
// Rotate the turtle
|
||||||
TransformRotateZLens {
|
TransformRotateZLens {
|
||||||
start: start.value(),
|
start: start.to_radians().value(),
|
||||||
end: end.value(),
|
end: end.to_radians().value(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_completed_event(state.index as u64);
|
.with_completed_event(state.index as u64);
|
||||||
// Dont move and draw
|
// Dont move and draw
|
||||||
let line = TurtleGraphElement::Noop;
|
let line = TurtleGraphElement::Noop;
|
||||||
// Update the state
|
// Update the state
|
||||||
state.heading = end % (2. * PI);
|
state.heading = end.limit_smaller_than_full_circle();
|
||||||
(Some(animation), Some(line))
|
(Some(animation), Some(line))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ pub fn turtle_move(
|
|||||||
EaseFunction::QuadraticInOut,
|
EaseFunction::QuadraticInOut,
|
||||||
TweeningType::Once,
|
TweeningType::Once,
|
||||||
// later to be controlled by speed
|
// later to be controlled by speed
|
||||||
Duration::from_millis(500),
|
Duration::from_millis(state.speed),
|
||||||
// set the start and end of the animation
|
// set the start and end of the animation
|
||||||
TransformPositionLens {
|
TransformPositionLens {
|
||||||
start: start.extend(0.),
|
start: start.extend(0.),
|
||||||
@ -74,10 +74,9 @@ pub fn turtle_circle(
|
|||||||
) -> (Option<Tween<Transform>>, Option<TurtleGraphElement>) {
|
) -> (Option<Tween<Transform>>, Option<TurtleGraphElement>) {
|
||||||
let radius_tuple = Vec2::ONE * radius.abs();
|
let radius_tuple = Vec2::ONE * radius.abs();
|
||||||
let left_right = Angle::degrees(if radius >= 0. { 90. } else { -90. });
|
let left_right = Angle::degrees(if radius >= 0. { 90. } else { -90. });
|
||||||
println!("Heading: {}", state.heading.value());
|
|
||||||
let center = state.start
|
let center = state.start
|
||||||
+ (Vec2::new(radius.abs(), 0.).rotate(Vec2::from_angle(
|
+ (Vec2::new(radius.abs(), 0.).rotate(Vec2::from_angle(
|
||||||
(state.heading + left_right.to_radians()).value(),
|
((state.heading + left_right).to_radians()).value(),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let turtle_movement_animation = Tween::new(
|
let turtle_movement_animation = Tween::new(
|
||||||
@ -85,7 +84,7 @@ pub fn turtle_circle(
|
|||||||
EaseFunction::QuadraticInOut,
|
EaseFunction::QuadraticInOut,
|
||||||
TweeningType::Once,
|
TweeningType::Once,
|
||||||
// later to be controlled by speed
|
// later to be controlled by speed
|
||||||
Duration::from_millis(500),
|
Duration::from_millis(state.speed),
|
||||||
// set the start and end of the animation
|
// set the start and end of the animation
|
||||||
CircleMovementLens {
|
CircleMovementLens {
|
||||||
start: Transform {
|
start: Transform {
|
||||||
@ -105,15 +104,16 @@ pub fn turtle_circle(
|
|||||||
radii: radius_tuple,
|
radii: radius_tuple,
|
||||||
angle,
|
angle,
|
||||||
start: state.start,
|
start: state.start,
|
||||||
end: state.start + 200.,
|
end: state.start,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TurtleGraphElement::Noop
|
TurtleGraphElement::Noop
|
||||||
};
|
};
|
||||||
let end_pos = center
|
let end_pos = center
|
||||||
+ Vec2::new(radius.abs(), 0.).rotate(Vec2::from_angle(
|
+ Vec2::new(radius.abs(), 0.).rotate(Vec2::from_angle(
|
||||||
(state.heading + angle).to_radians().value(),
|
(state.heading + angle - left_right).to_radians().value(),
|
||||||
));
|
));
|
||||||
state.start = end_pos;
|
state.start = end_pos;
|
||||||
|
state.heading = state.heading + angle;
|
||||||
(Some(turtle_movement_animation), Some(line))
|
(Some(turtle_movement_animation), Some(line))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user