Skip to content

feat: added physics directory and ground to ground projectile motion algorithm #2279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Oct 25, 2022
Merged
3 changes: 3 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@
* [Tower Of Hanoi](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/tower_of_hanoi.cpp)
* [Vector Important Functions](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/vector_important_functions.cpp)

## Physics
* [Ground To Ground Projectile Motion](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/physics/ground_to_ground_projectile_motion.cpp)

## Probability
* [Addition Rule](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/probability/addition_rule.cpp)
* [Bayes Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/probability/bayes_theorem.cpp)
Expand Down
139 changes: 139 additions & 0 deletions physics/ground_to_ground_projectile_motion.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* @file
* @brief Ground to ground [projectile
* motion](https://en.wikipedia.org/wiki/Projectile_motion) equation
* implementations
* @details Ground to ground projectile motion is when a projectile's trajectory
* starts at the ground, reaches the apex, then falls back on the ground.
*
* @author [Focusucof](https://github.com/Focusucof)
*/

#include <cassert> /// for assert()
#include <cmath> /// for std::pow(), std::sin(), and std::cos()
#include <iostream> /// for IO operations

/**
* @namespace physics
* @brief Physics algorithms
*/
namespace physics {
/**
* @namespace ground_to_ground_projectile_motion
* @brief Functions for the Ground to ground [projectile
* motion](https://en.wikipedia.org/wiki/Projectile_motion) equation
*/
namespace ground_to_ground_projectile_motion {
/**
* @brief Convert radians to degrees
* @param radian Angle in radians
* @param PI The definition of the constant PI
* @returns Angle in degrees
*/
double degrees_to_radians(double radian, double PI = 3.14) {
return (radian * (PI / 180));
}

/**
* @brief Calculate the time of flight
* @param initial_velocity The starting velocity of the projectile
* @param angle The angle that the projectile is launched at in degrees
* @param gravity The value used for the gravity constant
* @returns The time that the projectile is in the air for
*/
template <typename T>
T time_of_flight(T initial_velocity, T angle, double gravity = 9.81) {
double Viy = initial_velocity * (std::sin(degrees_to_radians(angle))); // calculate y component of the initial velocity
return 2.0 * Viy / gravity;
}

/**
* @brief Calculate the horizontal distance that the projectile travels
* @param initial_velocity The starting velocity of the projectile
* @param time The time that the projectile is in the air
* @returns Horizontal distance that the projectile travels
*/
template <typename T>
T horizontal_range(T initial_velocity, T angle, T time) {
double Vix = initial_velocity * (std::cos(degrees_to_radians(angle))); // calculate x component of the initial velocity
return Vix * time;
}

/**
* @brief Calculate the max height of the projectile
* @param initial_velocity The starting velocity of the projectile
* @param angle The angle that the projectile is launched at in degrees
* @param gravity The value used for the gravity constant
* @returns The max height that the projectile reaches
*/
template <typename T>
T max_height(T initial_velocity, T angle, double gravity = 9.81) {
double Viy = initial_velocity * (std::sin(degrees_to_radians(angle))); // calculate y component of the initial velocity
return (std::pow(Viy, 2) / (2.0 * gravity));
}
} // namespace ground_to_ground_projectile_motion
} // namespace physics

/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
// initial input variables
double initial_velocity = 5.0; // double initial_velocity input
double angle = 40.0; // double angle input

// 1st test
double expected_time_of_flight = 0.655; // expected time output
double flight_time_output =
std::round(physics::ground_to_ground_projectile_motion::time_of_flight(initial_velocity, angle) * 1000.0) /
1000.0; // round output to 3 decimal places

std::cout << "Projectile Flight Time (double)" << std::endl;
std::cout << "Input Initial Velocity: " << initial_velocity << std::endl;
std::cout << "Input Angle: " << angle << std::endl;
std::cout << "Expected Output: " << expected_time_of_flight << std::endl;
std::cout << "Output: " << flight_time_output << std::endl;
assert(flight_time_output == expected_time_of_flight);
std::cout << "TEST PASSED" << std::endl << std::endl;

// 2nd test
double expected_horizontal_range = 2.51; // expected range output
double horizontal_range_output =
std::round(physics::ground_to_ground_projectile_motion::horizontal_range(initial_velocity, angle,
flight_time_output) *
100.0) /
100.0; // round output to 2 decimal places

std::cout << "Projectile Horizontal Range (double)" << std::endl;
std::cout << "Input Initial Velocity: " << initial_velocity << std::endl;
std::cout << "Input Angle: " << angle << std::endl;
std::cout << "Input Time Of Flight: " << flight_time_output << std::endl;
std::cout << "Expected Output: " << expected_horizontal_range << std::endl;
std::cout << "Output: " << horizontal_range_output << std::endl;
assert(horizontal_range_output == expected_horizontal_range);
std::cout << "TEST PASSED" << std::endl << std::endl;

// 3rd test
double expected_max_height = 0.526; // expected height output
double max_height_output =
std::round(physics::ground_to_ground_projectile_motion::max_height(initial_velocity, angle) * 1000.0) /
1000.0; // round output to 3 decimal places

std::cout << "Projectile Max Height (double)" << std::endl;
std::cout << "Input Initial Velocity: " << initial_velocity << std::endl;
std::cout << "Input Angle: " << angle << std::endl;
std::cout << "Expected Output: " << expected_max_height << std::endl;
std::cout << "Output: " << max_height_output << std::endl;
assert(max_height_output == expected_max_height);
std::cout << "TEST PASSED" << std::endl << std::endl;
}

/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
test(); // run self-test implementations
return 0;
}