Skip to content

Commit

Permalink
physics: Add horizontal projectile motion
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Aug 1, 2023
1 parent c33102c commit 7beca55
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
74 changes: 74 additions & 0 deletions physics/src/horizontal_projectile_motion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) 2023 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
// Use of this source is governed by General Public License that can be found
// in the LICENSE file.

//! Horizontal Projectile Motion problem in physics.
//!
//! [Projectile motion](https://en.wikipedia.org/wiki/Projectile_motion)

/// Acceleration Constant on Earth (unit m/s^2)
pub const G: f64 = 9.80665;

// Check that the arguments are valid
#[must_use]
fn check_args(init_velocity: f64, angle: f64) -> bool {
init_velocity >= 0.0 && (1.0..=90.0).contains(&angle)
}

/// Returns the horizontal distance that the object cover
#[must_use]
pub fn horizontal_distance(init_velocity: f64, angle: f64) -> f64 {
debug_assert!(check_args(init_velocity, angle));
let radians = (2.0 * angle).to_radians();
init_velocity.powi(2) * (radians).sin() / G
}

/// Returns the maximum height that the object reach
#[must_use]
pub fn max_height(init_velocity: f64, angle: f64) -> f64 {
debug_assert!(check_args(init_velocity, angle));
let radians = angle.to_radians();
init_velocity.powi(2) * radians.sin().powi(2) / (2.0 * G)
}

/// Returns total time of the motion
#[must_use]
pub fn total_time(init_velocity: f64, angle: f64) -> f64 {
debug_assert!(check_args(init_velocity, angle));
let radians = angle.to_radians();
2.0 * init_velocity * radians.sin() / G
}

pub trait Round2 {
#[must_use]
fn round2(self) -> Self;
}

impl Round2 for f64 {
fn round2(self) -> Self {
(self * 100.0).round() / 100.0
}
}

#[cfg(test)]
mod tests {
use super::{horizontal_distance, max_height, total_time, Round2};

#[test]
fn test_horizontal_distance() {
assert_eq!(horizontal_distance(30.0, 45.0).round2(), 91.77);
assert_eq!(horizontal_distance(100.0, 78.0).round2(), 414.76);
}

#[test]
fn test_max_height() {
assert_eq!(max_height(30.0, 45.0).round2(), 22.94);
assert_eq!(max_height(100.0, 78.0).round2(), 487.82);
}

#[test]
fn test_total_time() {
assert_eq!(total_time(30.0, 45.0).round2(), 4.33);
assert_eq!(total_time(100.0, 78.0).round2(), 19.95);
}
}
1 change: 1 addition & 0 deletions physics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod archimedes_principle;
pub mod casimir_effect;
pub mod centripetal_force;
pub mod grahams_law;
pub mod horizontal_projectile_motion;
pub mod hubble_parameter;
pub mod ideal_gas_law;
pub mod kinetic_energy;
Expand Down

0 comments on commit 7beca55

Please sign in to comment.