Skip to content

Commit 39b7553

Browse files
Enhance projectile motion calculations with validation
Added input validation and constants for rounding precision in projectile motion calculations. Fixed some typos Updated test function for self testing
1 parent b9c118f commit 39b7553

File tree

1 file changed

+39
-35
lines changed

1 file changed

+39
-35
lines changed

physics/ground_to_ground_projectile_motion.cpp

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,7 @@
1-
/**
2-
* @file
3-
* @brief Ground to ground [projectile
4-
* motion](https://en.wikipedia.org/wiki/Projectile_motion) equation
5-
* implementations
6-
* @details Ground to ground projectile motion is when a projectile's trajectory
7-
* starts at the ground, reaches the apex, then falls back on the ground.
8-
*
9-
* @author [Focusucof](https://github.com/Focusucof)
10-
*/
11-
12-
#include <cassert> /// for assert()
1+
#include <cassert> ///< for assert()
132
#define _USE_MATH_DEFINES
14-
#include <cmath> /// for std::pow(), std::sin(), and std::cos()
15-
#include <iostream> /// for IO operations
3+
#include <cmath> ///< for std::pow(), std::sin(), and std::cos()
4+
#include <iostream> ///< for IO operations
165

176
/**
187
* @namespace physics
@@ -22,23 +11,34 @@
2211
// Define gravity as a constant within guidelines
2312
constexpr double GRAVITY = 9.80665; ///< Standard gravity (m/s^2)
2413

14+
// New constants for rounding precision
15+
constexpr double ROUND_PRECISION_3 = 1000.0; ///< Precision for rounding to 3 decimal places
16+
constexpr double ROUND_PRECISION_2 = 100.0; ///< Precision for rounding to 2 decimal places
17+
constexpr double EPSILON = 0.001; ///< Tolerance for floating-point comparison
2518

2619
namespace physics {
2720
/**
2821
* @namespace ground_to_ground_projectile_motion
29-
* @brief Functions for the Ground to ground [projectile
30-
* motion](https://en.wikipedia.org/wiki/Projectile_motion) equation
22+
* @brief Functions for the Ground to ground [projectile motion](https://en.wikipedia.org/wiki/Projectile_motion) equation
3123
*/
3224
namespace ground_to_ground_projectile_motion {
3325
/**
34-
* @brief Convert radians to degrees
35-
* @param radian Angle in radians
36-
* @returns Angle in degrees
26+
* @brief Convert degrees to radians
27+
* @param degrees Angle in degrees
28+
* @returns Angle in radians
3729
*/
38-
3930
double degrees_to_radians(double degrees){
40-
double radians = degrees * (M_PI / 180);
41-
return radians;
31+
return degrees * (M_PI / 180);
32+
}
33+
34+
/**
35+
* @brief Validate input parameters for projectile motion
36+
* @param velocity Initial velocity of the projectile
37+
* @param angle Launch angle in degrees
38+
* @returns True if inputs are valid, false otherwise
39+
*/
40+
bool is_valid_input(double velocity, double angle) {
41+
return velocity >= 0.0 && angle >= 0.0 && angle <= 90.0;
4242
}
4343

4444
/**
@@ -50,19 +50,20 @@ double degrees_to_radians(double degrees){
5050
*/
5151
template <typename T>
5252
T time_of_flight(T initial_velocity, T angle, double gravity = GRAVITY) {
53-
double Viy = initial_velocity * (std::sin(degrees_to_radians(angle))); // calculate y component of the initial velocity
53+
double Viy = initial_velocity * std::sin(degrees_to_radians(angle)); // calculate y component of the initial velocity
5454
return 2.0 * Viy / gravity;
5555
}
5656

5757
/**
5858
* @brief Calculate the horizontal distance that the projectile travels
5959
* @param initial_velocity The starting velocity of the projectile
60+
* @param angle The angle that the projectile is launched at in degrees
6061
* @param time The time that the projectile is in the air
6162
* @returns Horizontal distance that the projectile travels
6263
*/
6364
template <typename T>
6465
T horizontal_range(T initial_velocity, T angle, T time) {
65-
double Vix = initial_velocity * (std::cos(degrees_to_radians(angle))); // calculate x component of the initial velocity
66+
double Vix = initial_velocity * std::cos(degrees_to_radians(angle)); // calculate x component of the initial velocity
6667
return Vix * time;
6768
}
6869

@@ -75,8 +76,8 @@ T horizontal_range(T initial_velocity, T angle, T time) {
7576
*/
7677
template <typename T>
7778
T max_height(T initial_velocity, T angle, double gravity = GRAVITY) {
78-
double Viy = initial_velocity * (std::sin(degrees_to_radians(angle))); // calculate y component of the initial velocity
79-
return (std::pow(Viy, 2) / (2.0 * gravity));
79+
double Viy = initial_velocity * std::sin(degrees_to_radians(angle)); // calculate y component of the initial velocity
80+
return std::pow(Viy, 2) / (2.0 * gravity);
8081
}
8182
} // namespace ground_to_ground_projectile_motion
8283
} // namespace physics
@@ -90,49 +91,52 @@ static void test() {
9091
double initial_velocity = 5.0; // double initial_velocity input
9192
double angle = 40.0; // double angle input
9293

94+
// Validate inputs
95+
assert(physics::ground_to_ground_projectile_motion::is_valid_input(initial_velocity, angle));
96+
9397
// 1st test
9498
double expected_time_of_flight = 0.655; // expected time output
9599
double flight_time_output =
96-
std::round(physics::ground_to_ground_projectile_motion::time_of_flight(initial_velocity, angle) * 1000.0) /
97-
1000.0; // round output to 3 decimal places
100+
std::round(physics::ground_to_ground_projectile_motion::time_of_flight(initial_velocity, angle) * ROUND_PRECISION_3) /
101+
ROUND_PRECISION_3; // round output to 3 decimal places
98102

99103
std::cout << "Projectile Flight Time (double)" << std::endl;
100104
std::cout << "Input Initial Velocity: " << initial_velocity << std::endl;
101105
std::cout << "Input Angle: " << angle << std::endl;
102106
std::cout << "Expected Output: " << expected_time_of_flight << std::endl;
103107
std::cout << "Output: " << flight_time_output << std::endl;
104-
assert(flight_time_output == expected_time_of_flight);
108+
assert(std::abs(flight_time_output - expected_time_of_flight) < EPSILON);
105109
std::cout << "TEST PASSED" << std::endl << std::endl;
106110

107111
// 2nd test
108112
double expected_horizontal_range = 2.51; // expected range output
109113
double horizontal_range_output =
110114
std::round(physics::ground_to_ground_projectile_motion::horizontal_range(initial_velocity, angle,
111115
flight_time_output) *
112-
100.0) /
113-
100.0; // round output to 2 decimal places
116+
ROUND_PRECISION_2) /
117+
ROUND_PRECISION_2; // round output to 2 decimal places
114118

115119
std::cout << "Projectile Horizontal Range (double)" << std::endl;
116120
std::cout << "Input Initial Velocity: " << initial_velocity << std::endl;
117121
std::cout << "Input Angle: " << angle << std::endl;
118122
std::cout << "Input Time Of Flight: " << flight_time_output << std::endl;
119123
std::cout << "Expected Output: " << expected_horizontal_range << std::endl;
120124
std::cout << "Output: " << horizontal_range_output << std::endl;
121-
assert(horizontal_range_output == expected_horizontal_range);
125+
assert(std::abs(horizontal_range_output - expected_horizontal_range) < EPSILON);
122126
std::cout << "TEST PASSED" << std::endl << std::endl;
123127

124128
// 3rd test
125129
double expected_max_height = 0.526; // expected height output
126130
double max_height_output =
127-
std::round(physics::ground_to_ground_projectile_motion::max_height(initial_velocity, angle) * 1000.0) /
128-
1000.0; // round output to 3 decimal places
131+
std::round(physics::ground_to_ground_projectile_motion::max_height(initial_velocity, angle) * ROUND_PRECISION_3) /
132+
ROUND_PRECISION_3; // round output to 3 decimal places
129133

130134
std::cout << "Projectile Max Height (double)" << std::endl;
131135
std::cout << "Input Initial Velocity: " << initial_velocity << std::endl;
132136
std::cout << "Input Angle: " << angle << std::endl;
133137
std::cout << "Expected Output: " << expected_max_height << std::endl;
134138
std::cout << "Output: " << max_height_output << std::endl;
135-
assert(max_height_output == expected_max_height);
139+
assert(std::abs(max_height_output - expected_max_height) < EPSILON);
136140
std::cout << "TEST PASSED" << std::endl << std::endl;
137141
}
138142

0 commit comments

Comments
 (0)