chore: import upstream snapshot with attribution
Awesome CI Workflow / Code Formatter (push) Has been cancelled
Awesome CI Workflow / Compile checks (macOS-latest) (push) Has been cancelled
Awesome CI Workflow / Compile checks (ubuntu-latest) (push) Has been cancelled
Awesome CI Workflow / Compile checks (windows-latest) (push) Has been cancelled
Awesome CI Workflow / Code Formatter (push) Has been cancelled
Awesome CI Workflow / Compile checks (macOS-latest) (push) Has been cancelled
Awesome CI Workflow / Compile checks (ubuntu-latest) (push) Has been cancelled
Awesome CI Workflow / Compile checks (windows-latest) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
|
||||
# with full pathname. The RELATIVE flag makes it easier to extract an executable's name
|
||||
# automatically.
|
||||
|
||||
file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
|
||||
foreach( testsourcefile ${APP_SOURCES} )
|
||||
string( REPLACE ".cpp" "" testname ${testsourcefile} ) # File type. Example: `.cpp`
|
||||
add_executable( ${testname} ${testsourcefile} )
|
||||
|
||||
set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX)
|
||||
if(OpenMP_CXX_FOUND)
|
||||
target_link_libraries(${testname} OpenMP::OpenMP_CXX)
|
||||
endif()
|
||||
install(TARGETS ${testname} DESTINATION "bin/physics") # Folder name. Do NOT include `<>`
|
||||
|
||||
endforeach( testsourcefile ${APP_SOURCES} )
|
||||
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @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()
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath> /// for std::pow(), std::sin(), and std::cos()
|
||||
#include <iostream> /// for IO operations
|
||||
|
||||
/**
|
||||
* @namespace physics
|
||||
* @brief Physics algorithms
|
||||
*/
|
||||
|
||||
// Define gravity as a constant within guidelines
|
||||
constexpr double GRAVITY = 9.80665; ///< Standard gravity (m/s^2)
|
||||
|
||||
|
||||
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
|
||||
* @returns Angle in degrees
|
||||
*/
|
||||
|
||||
double degrees_to_radians(double degrees){
|
||||
double radians = degrees * (M_PI / 180);
|
||||
return radians;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 = GRAVITY) {
|
||||
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 = GRAVITY) {
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user