// https://phys.libretexts.org/Bookshelves/University_Physics/Physics_(Boundless)/3%3A_Two-Dimensional_Kinematics/3.3%3A_Projectile_Motion
#pragma once
class ClassicalBallistics
{
public:
ClassicalBallistics(void);
~ClassicalBallistics(void);
// analytical formula for maximum height
double H(double V0, double theta0, double g);
// analytical formula for flight time
double T(double H, double g);
// analytical formula for velocity at apex
double Va(double V0, double theta0);
// analytical formula for the range
double L(double Va, double T);
// analytical formula for time to apex
double ta(double T);
// analytical formula for range to apex
double xa(double L);
double xa(double H, double L, double theta0);
double Theta1(double theta0);
double Theta1(double H, double L, double xa);
double ClassicalBallistics::V1(double V0);
};
#include "StdAfx.h"
#include "ClassicalBallistics.h"
#include <math.h>
ClassicalBallistics::ClassicalBallistics(void)
{
}
ClassicalBallistics::~ClassicalBallistics(void)
{
}
// analytical formula for maximum height
double ClassicalBallistics::H(double V0, double theta0, double g)
{
double V02 = V0 * V0, sinTheta0 = sin(theta0);
double sinTheta02 = sinTheta0 * sinTheta0;
return V02 * sinTheta02 / (g * 2.0);
}
// analytical formula for flight time
double ClassicalBallistics::T(double H, double g)
{
return 2.0 * sqrt(2.0 * H / g);
}
// analytical formula for velocity at apex
double ClassicalBallistics::Va(double V0, double theta0)
{
double cosTheta0 = cos(theta0);
double V02 = V0 * V0;
return V0 * cosTheta0;
}
// analytical formula for the range
double ClassicalBallistics::L(double Va, double T)
{
return Va * T;
}
// analytical formula for time to apex
double ClassicalBallistics::ta(double T)
{
return 0.5 * T;
}
// analytical formula for range to apex
double ClassicalBallistics::xa(double L)
{
return 0.5 * L;
}
double ClassicalBallistics::xa(double H, double L, double theta0)
{
return sqrt(L * H / tan(theta0));
}
double ClassicalBallistics::Theta1(double theta0)
{
return -theta0;
}
double ClassicalBallistics::Theta1(double H, double L, double xa)
{
return atan(L * H / pow(L - xa, 2.0));
}
double ClassicalBallistics::V1(double V0)
{
return V0;
}
// http://www.lajpe.org/sep13/04-LAJPE-782_Chudinov.pdf
#pragma once
const double g = 9.81;
// accleration due to gravity in Metric (SI) Units
const double k = 0.000625;
// k is typical for a baseball
class DragBallistics
{
public:
DragBallistics(void);
~DragBallistics(void);
double f(double theta);
// analytical formula for maximum height
double H(double V0, double theta0, double g, double k);
// analytical formula for flight time
double T(double H, double g);
// analytical formula for velocity at apex
double Va(double V0, double theta0, double k);
// analytical formula for the range
double L(double Va, double T);
double ta(double H, double T, double Va, double k);
double xa(double H, double L, double theta0);
double Theta1(double H, double L, double xa);
double V1(double V0, double theta0, double theta1, double k);
};
#include "StdAfx.h"
#include "DragBallistics.h"
#include <math.h>
DragBallistics::DragBallistics(void)
{
}
DragBallistics::~DragBallistics(void)
{
}
double DragBallistics::f(double theta)
{
double pi = 4.0 * atan(1.0);
double sinTheta = sin(theta), cosTheta = cos(theta),
cosTheta2 = cosTheta * cosTheta;
return (sinTheta / cosTheta2) + log(tan(0.5 * theta + pi / 4.0));
}
// analytical formula for maximum height
double DragBallistics::H(double V0, double theta0, double g, double k)
{
double V02 = V0 * V0, sinTheta0 = sin(theta0),
sinTheta02 = sinTheta0 * sinTheta0;
return V02 * sinTheta02 / (g * (2.0 + k * V02 * sinTheta0));
}
// analytical formula for flight time
double DragBallistics::T(double H, double g)
{
return 2.0 * sqrt(2.0 * H / g);
}
// analytical formula for velocity at apex
double DragBallistics::Va(double V0, double theta0, double k)
{
double pi = 4.0 * atan(1.0);
double cosTheta0 = cos(theta0), cosTheta02 = cosTheta0 * cosTheta0;
double V02 = V0 * V0, sinTheta0 = sin(theta0);
return V0 * cosTheta0 / sqrt(1.0 + k * V02 * (sinTheta0 +
cosTheta02 * log(tan(0.5 * theta0 + pi / 4.0))));
}
// analytical formula for the range
double DragBallistics::L(double Va, double T)
{
return Va * T;
}
double DragBallistics::ta(double H, double T, double Va, double k)
{
return 0.5 * (T - k * H * Va);
}
double DragBallistics::xa(double H, double L, double theta0)
{
return sqrt(L * H / tan(theta0));
}
double DragBallistics::Theta1(double H, double L, double xa)
{
return -atan(L * H / pow(L - xa, 2.0));
}
double DragBallistics::V1(double V0, double theta0, double theta1, double k)
{
double V02 = V0 * V0;
double sinTheta0 = sin(theta0), cosTheta0 = cos(theta0),
cosTheta02 = cosTheta0 * cosTheta0;
return V0 * cosTheta0 / (cos(theta1) * sqrt(1.0 + k *
V02 * cosTheta02 * (f(theta0) - f(theta1))));
}
// BaseballBallisticsWin32Console.cpp
// Translated from August 2017 C# application
// May 21, 2025 (c) James Pate Williams, Jr.
#include "stdafx.h"
#include "ClassicalBallistics.h"
#include "DragBallistics.h"
#include <iomanip>
#include <iostream>
#include <math.h>
void PrintResults(char title[],
double H, double T, double Va,
double L, double Ta, double xa,
double Theta1, double V1)
{
std::cout << title << std::endl;
std::cout << std::fixed << std::setprecision(2);
std::cout << "H = " << H << std::endl;
std::cout << "T = " << T << std::endl;
std::cout << "Va = " << Va << std::endl;
std::cout << "L = " << L << std::endl;
std::cout << "Ta = " << Ta << std::endl;
std::cout << "xa = " << xa << std::endl;
std::cout << "theta1 = " << Theta1 << std::endl;
std::cout << "V1 = " << V1 << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
while (true)
{
char line[128] = { };
std::cout << "V0 (m / s) or 0 to quit: ";
std::cin.getline(line, 128);
double V0 = atof(line);
if (V0 == 0)
{
break;
}
std::cout << "Enter angle in degrees: ";
std::cin.getline(line, 128);
double theta0 = atof(line);
double pi = 4.0 * atan(1.0);
theta0 *= pi / 180.0;
ClassicalBallistics cBall;
DragBallistics dBall;
double cH = cBall.H(V0, theta0, g);
double dH = dBall.H(V0, theta0, g, k);
double cT = cBall.T(cH, g);
double dT = dBall.T(dH, g);
double cVa = cBall.Va(V0, theta0);
double dVa = dBall.Va(V0, theta0, k);
double cL = cBall.L(cVa, cT);
double dL = dBall.L(dVa, dT);
double cta = cBall.ta(cT);
double dta = dBall.ta(dH, dT, dVa, k);
double cxa = cBall.xa(cL);
double dxa = dBall.xa(dH, dL, theta0);
double cTheta1 = 180.0 * cBall.Theta1(theta0) / pi;
double dTheta1 = 180.0 * dBall.Theta1(dH, dL, dxa) / pi;
double cV1 = cBall.V1(V0);
double dV1 = dBall.V1(V0, theta0, pi * dTheta1 / 180.0, k);
PrintResults("Classical Ballistics",
cH, cT, cVa, cL, cta, cxa, cTheta1, cV1);
PrintResults("Drag Ballistics",
dH, dT, dVa, dL, dta, dxa, dTheta1, dV1);
}
return 0;
}
Author: jamespatewilliamsjr
My whole legal name is James Pate Williams, Jr. I was born in LaGrange, Georgia approximately 70 years ago. I barely graduated from LaGrange High School with low marks in June 1971. Later in June 1979, I graduated from LaGrange College with a Bachelor of Arts in Chemistry with a little over a 3 out 4 Grade Point Average (GPA). In the Spring Quarter of 1978, I taught myself how to program a Texas Instruments desktop programmable calculator and in the Summer Quarter of 1978 I taught myself Dayton BASIC (Beginner's All-purpose Symbolic Instruction Code) on LaGrange College's Data General Eclipse minicomputer. I took courses in BASIC in the Fall Quarter of 1978 and FORTRAN IV (Formula Translator IV) in the Winter Quarter of 1979. Professor Kenneth Cooper, a genius poly-scientist taught me a course in the Intel 8085 microprocessor architecture and assembly and machine language. We would hand assemble our programs and insert the resulting machine code into our crude wooden box computer which was designed and built by Professor Cooper. From 1990 to 1994 I earned a Bachelor of Science in Computer Science from LaGrange College. I had a 4 out of 4 GPA in the period 1990 to 1994. I took courses in C, COBOL, and Pascal during my BS work. After graduating from LaGrange College a second time in May 1994, I taught myself C++. In December 1995, I started using the Internet and taught myself client-server programming. I created a website in 1997 which had C and C# implementations of algorithms from the "Handbook of Applied Cryptography" by Alfred J. Menezes, et. al., and some other cryptography and number theory textbooks and treatises.
View all posts by jamespatewilliamsjr