Finalize the circle command
This commit is contained in:
+24
-1
@@ -1,5 +1,8 @@
|
||||
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)]
|
||||
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> {
|
||||
type Output = Self;
|
||||
|
||||
@@ -101,6 +116,14 @@ impl<T: Default + num_traits::float::Float> Angle<T> {
|
||||
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> {
|
||||
|
||||
+47
-9
@@ -42,12 +42,47 @@ impl Default for Turtle {
|
||||
fill_color: Color::BLACK,
|
||||
},
|
||||
commands: TurtleCommands::new(vec![
|
||||
TurtleCommand::Forward(Length(-100.)),
|
||||
TurtleCommand::Circle {
|
||||
radius: Length(150.),
|
||||
angle: Angle::degrees(30.),
|
||||
},
|
||||
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.),
|
||||
@@ -58,7 +93,7 @@ impl Default for Turtle {
|
||||
TurtleCommand::Circle {
|
||||
radius: Length(30.),
|
||||
angle: Angle::degrees(360. - 46.),
|
||||
},
|
||||
}, */
|
||||
/* TurtleCommand::Backward(Length(100.)),
|
||||
TurtleCommand::Right(Angle(90.)),
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
@@ -113,6 +148,7 @@ pub struct TurtleCommands {
|
||||
pub struct TurtleState {
|
||||
pub start: Vec2,
|
||||
pub heading: Angle<f32>,
|
||||
pub speed: u64,
|
||||
pub index: u64,
|
||||
pub drawing: bool,
|
||||
}
|
||||
@@ -125,6 +161,7 @@ impl TurtleCommands {
|
||||
state: TurtleState {
|
||||
start: Vec2::ZERO,
|
||||
heading: Angle::degrees(0.),
|
||||
speed: 2000,
|
||||
index: 0,
|
||||
drawing: true,
|
||||
},
|
||||
@@ -260,7 +297,7 @@ fn draw_lines(
|
||||
let line_animator = Animator::new(Tween::new(
|
||||
EaseFunction::QuadraticInOut,
|
||||
TweeningType::Once,
|
||||
Duration::from_millis(500),
|
||||
Duration::from_millis(tcmd.state.speed),
|
||||
LineAnimationLens::new(start, end),
|
||||
));
|
||||
commands
|
||||
@@ -278,7 +315,7 @@ fn draw_lines(
|
||||
let line_animator = Animator::new(Tween::new(
|
||||
EaseFunction::QuadraticInOut,
|
||||
TweeningType::Once,
|
||||
Duration::from_millis(500),
|
||||
Duration::from_millis(tcmd.state.speed),
|
||||
CircleAnimationLens {
|
||||
start_pos: start,
|
||||
center,
|
||||
@@ -324,6 +361,7 @@ fn keypresses(
|
||||
tcmd.state = TurtleState {
|
||||
start: Vec2::ZERO,
|
||||
heading: Angle::degrees(0.),
|
||||
speed: 2000,
|
||||
index: 0,
|
||||
drawing: true,
|
||||
};
|
||||
@@ -335,7 +373,7 @@ fn keypresses(
|
||||
let line_animator = Animator::new(Tween::new(
|
||||
EaseFunction::QuadraticInOut,
|
||||
TweeningType::Once,
|
||||
Duration::from_millis(500),
|
||||
Duration::from_millis(tcmd.state.speed),
|
||||
LineAnimationLens::new(start, end),
|
||||
));
|
||||
commands
|
||||
|
||||
+11
-11
@@ -17,24 +17,24 @@ pub fn turtle_turn(
|
||||
angle_to_turn: Angle<f32>,
|
||||
) -> (Option<Tween<Transform>>, Option<TurtleGraphElement>) {
|
||||
let start = state.heading;
|
||||
let end = state.heading + (angle_to_turn * PI / 180.);
|
||||
let end = state.heading + angle_to_turn;
|
||||
let animation = Tween::new(
|
||||
// Use a quadratic easing on both endpoints
|
||||
EaseFunction::QuadraticInOut,
|
||||
TweeningType::Once,
|
||||
// Animation time
|
||||
Duration::from_millis(500),
|
||||
Duration::from_millis(state.speed),
|
||||
// Rotate the turtle
|
||||
TransformRotateZLens {
|
||||
start: start.value(),
|
||||
end: end.value(),
|
||||
start: start.to_radians().value(),
|
||||
end: end.to_radians().value(),
|
||||
},
|
||||
)
|
||||
.with_completed_event(state.index as u64);
|
||||
// Dont move and draw
|
||||
let line = TurtleGraphElement::Noop;
|
||||
// Update the state
|
||||
state.heading = end % (2. * PI);
|
||||
state.heading = end.limit_smaller_than_full_circle();
|
||||
(Some(animation), Some(line))
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ pub fn turtle_move(
|
||||
EaseFunction::QuadraticInOut,
|
||||
TweeningType::Once,
|
||||
// later to be controlled by speed
|
||||
Duration::from_millis(500),
|
||||
Duration::from_millis(state.speed),
|
||||
// set the start and end of the animation
|
||||
TransformPositionLens {
|
||||
start: start.extend(0.),
|
||||
@@ -74,10 +74,9 @@ pub fn turtle_circle(
|
||||
) -> (Option<Tween<Transform>>, Option<TurtleGraphElement>) {
|
||||
let radius_tuple = Vec2::ONE * radius.abs();
|
||||
let left_right = Angle::degrees(if radius >= 0. { 90. } else { -90. });
|
||||
println!("Heading: {}", state.heading.value());
|
||||
let center = state.start
|
||||
+ (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(
|
||||
@@ -85,7 +84,7 @@ pub fn turtle_circle(
|
||||
EaseFunction::QuadraticInOut,
|
||||
TweeningType::Once,
|
||||
// later to be controlled by speed
|
||||
Duration::from_millis(500),
|
||||
Duration::from_millis(state.speed),
|
||||
// set the start and end of the animation
|
||||
CircleMovementLens {
|
||||
start: Transform {
|
||||
@@ -105,15 +104,16 @@ pub fn turtle_circle(
|
||||
radii: radius_tuple,
|
||||
angle,
|
||||
start: state.start,
|
||||
end: state.start + 200.,
|
||||
end: state.start,
|
||||
}
|
||||
} else {
|
||||
TurtleGraphElement::Noop
|
||||
};
|
||||
let end_pos = center
|
||||
+ 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.heading = state.heading + angle;
|
||||
(Some(turtle_movement_animation), Some(line))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user