diff --git a/pong/src/geom.rs b/pong/src/geom.rs index b56a4bd..2608d35 100644 --- a/pong/src/geom.rs +++ b/pong/src/geom.rs @@ -28,14 +28,14 @@ pub mod geom { self.y /= length; } - pub fn perpendicular_clockwise(&mut self) { + pub fn orthogonal_clockwise(&mut self) { let updated_x = self.y; let updated_y = -self.x; self.x = updated_x; self.y = updated_y; } - pub fn perpendicular_counter_clockwise(&mut self) { + pub fn orthogonal_counter_clockwise(&mut self) { let updated_x = -self.y; let updated_y = self.x; self.x = updated_x; @@ -80,6 +80,31 @@ pub mod geom { (acos_res * 100.0).round() / 100.0 } + pub fn get_projection(&self, onto: &Vector) -> Vector { + let mut onto_normalized = onto.clone(); + onto_normalized.normalize(); + let dot = self.dot(&onto_normalized); + let mut projected = onto_normalized.clone(); + projected.scalar_multiplication(dot); + projected + } + + pub fn get_opposing_orthogonal(&self, onto: &Vector) -> Vector { + let mut orthogonal1 = onto.clone(); + orthogonal1.orthogonal_clockwise(); + if self.dot(&orthogonal1) < 0. { + return orthogonal1; + } + let mut orthogonal2 = onto.clone(); + orthogonal2.orthogonal_counter_clockwise(); + return orthogonal2; + } + + pub fn scalar_multiplication(&mut self, n: f64) { + self.x *= n; + self.y *= n; + } + pub fn len(&self) -> f64 { let distance = self.x.powi(2) + self.y.powi(2); return (distance as f64).sqrt(); diff --git a/pong/tests/vector_tests.rs b/pong/tests/vector_tests.rs index 0581b10..650af3b 100644 --- a/pong/tests/vector_tests.rs +++ b/pong/tests/vector_tests.rs @@ -49,11 +49,11 @@ pub fn should_calculate_angle_correctly( #[case(Vector::new(1., 0.), Vector::new(0., -1.))] #[case(Vector::new(0., 1.), Vector::new(1., 0.))] #[case(Vector::new(7., 7.), Vector::new(7., -7.))] -pub fn should_get_perpendicular_clockwise( +pub fn should_get_orthogonal_clockwise( #[case] mut vector: Vector, #[case] expected: Vector ) { - vector.perpendicular_clockwise(); + vector.orthogonal_clockwise(); assert_eq!(vector, expected); } @@ -61,11 +61,11 @@ pub fn should_get_perpendicular_clockwise( #[case(Vector::new(0., -1.), Vector::new(1., 0.))] #[case(Vector::new(1., 0.), Vector::new(0., 1.))] #[case(Vector::new(7., 7.), Vector::new(-7., 7.))] -pub fn should_get_perpendicular_counter_clockwise( +pub fn should_get_orthogonal_counter_clockwise( #[case] mut vector: Vector, #[case] expected: Vector ) { - vector.perpendicular_counter_clockwise(); + vector.orthogonal_counter_clockwise(); assert_eq!(vector, expected); } @@ -93,3 +93,32 @@ pub fn should_calculate_dot_product( let dot = vector.dot(&other); assert_eq!(dot, expected); } + +#[rstest] +#[case(Vector::new(0., 1.), Vector::new(1., 0.), Vector::new(0., 0.))] +#[case(Vector::new(1., 0.), Vector::new(1., 0.), Vector::new(1., 0.))] +#[case(Vector::new(-1., 0.), Vector::new(1., 0.), Vector::new(-1., 0.))] +#[case(Vector::new(1., 1.), Vector::new(1., 0.), Vector::new(1., 0.))] +#[case(Vector::new(2., 1.), Vector::new(1., 0.), Vector::new(2., 0.))] +pub fn should_get_projection( + #[case] vector: Vector, + #[case] other: Vector, + #[case] expected: Vector, +) { + let projected = vector.get_projection(&other); + assert_eq!(projected, expected); +} + +#[rstest] +#[case(Vector::new(1., 1.), Vector::new(1., 0.), Vector::new(0., -1.))] +#[case(Vector::new(-1., -1.), Vector::new(1., 0.), Vector::new(0., 1.))] +pub fn should_get_opposing_orthogonal( + #[case] vector: Vector, + #[case] onto: Vector, + #[case] expected: Vector, +) { + let orthogonal = vector.get_opposing_orthogonal(&onto); + assert_eq!(orthogonal, expected); +} + +