Skip to content

Commit 1476e1a

Browse files
Piripantsunjay
authored andcommitted
Fixed turn_towards (#40)
* Added comments and test * Updated turn_towards test * Fixed test * Cleaning code
1 parent e58c6e2 commit 1476e1a

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/turtle.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -989,9 +989,6 @@ impl Turtle {
989989
///
990990
/// If the coordinates are the same as the turtle's current position, no rotation takes place.
991991
/// Always rotates the least amount necessary in order to face the given point.
992-
///
993-
/// ## UNSTABLE
994-
/// This feature is currently unstable and completely buggy. Do not use it until it is fixed.
995992
pub fn turn_towards(&mut self, target: Point) {
996993
let target_x = target[0];
997994
let target_y = target[1];
@@ -1000,19 +997,24 @@ impl Turtle {
1000997
let x = position[0];
1001998
let y = position[1];
1002999

1000+
// If the target is (approximately) on the turtle don't turn
10031001
if (target_x - x).abs() < 0.1 && (target_y - y).abs() < 0.1 {
10041002
return;
10051003
}
10061004

10071005
let heading = self.window.fetch_turtle().heading;
10081006

1007+
// Calculate the target angle to reach
10091008
let angle = (target_y - y).atan2(target_x - x);
10101009
let angle = Radians::from_radians_value(angle);
1010+
// Calculate how much turning will be needed (angle - heading)
1011+
// And clamp it make sure the turtle doesn't turn more than 360 degrees
10111012
let angle = (angle - heading) % radians::TWO_PI;
10121013
// Try to rotate as little as possible
10131014
let angle = if angle.abs() > radians::PI {
1014-
// Using signum to deal with negative angles properly
1015-
angle.signum()*(radians::TWO_PI - angle.abs())
1015+
// Use signum to make sure the angle has the right sign
1016+
// And the turtle turns the right way
1017+
-angle.signum()*(radians::TWO_PI - angle.abs())
10161018
}
10171019
else {
10181020
angle
@@ -1156,4 +1158,22 @@ mod tests {
11561158
assert_eq!(turtle.position()[1].round(), 100.0);
11571159
assert_eq!(turtle.heading(), 51.0);
11581160
}
1161+
1162+
#[test]
1163+
fn turn_towards() {
1164+
let mut turtle = Turtle::new();
1165+
1166+
// Turn from each cardinal direction to each cardinal direction
1167+
for n in 0..16 as u32 {
1168+
let original_angle = radians::TWO_PI * n as f64 / 16.0;
1169+
for i in 0..16 as u32 {
1170+
turtle.turn_towards([original_angle.cos(), original_angle.sin()]);
1171+
assert_eq!(turtle.heading().ceil(), original_angle.to_degrees().ceil());
1172+
1173+
let target_angle = radians::TWO_PI * i as f64 / 16.0;
1174+
turtle.turn_towards([target_angle.cos(), target_angle.sin()]);
1175+
assert_eq!(turtle.heading().ceil(), target_angle.to_degrees().ceil());
1176+
}
1177+
}
1178+
}
11591179
}

0 commit comments

Comments
 (0)