在高度到时间的计算中实现角度

  • 本文关键字:实现 计算 高度 时间 c++
  • 更新时间 :
  • 英文 :


我正在编写一个程序,计算物体以给定速度直线向上投掷时的行进距离。

现在我需要实现角度,看看与直接向上投掷时相比,这会如何影响每秒的高度损失。

我被告知要使用数学图书馆,但我不知道从这里到哪里去。

//The following calculation can be used to calculate the correlation between time and height
//h(t )=−0.5⋅G⋅t^2+V⋅T+H

#include <iostream> 
#include <limits>
using namespace std;
int main() {
//Falling speed
const double G = 9.81;
//Starting height
double H = 0;
//Velocity/Speed
double V = 0;
//End product
double Ht = 0;
//Seconds that result is displayed on the screen
double T = 0;
//t^2
double Tt = 0;
int S;
int s = 1;
cout << "nGive me the starting height: ";
while(!(cin >> H)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), 'n');
cout << "False input. Try again: ";
}
cout << "nGive me the starting speed: ";
while(!(cin >> V)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), 'n');
cout << "False input. Try again: ";
}
cout << "nHow often do you want the current height to be displayed (In seconds)n";
while(!(cin >> S)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), 'n');
cout << "False input. Try again: ";
}
for (int i = 0; i < 10; i = i + S) {
Tt = i*i;
Ht = -0.5 * G * Tt + V * i + H;
if (Ht >= 0){
cout << "Second " << s << " the height is " <<  Ht << " Meters" << endl;
s += 1;
} else {
Ht = 0;
cout << "Second " << s << " the height is " << Ht << " Meters" << endl;
i = 9;
}
}
}

感谢您的帮助。

您正朝着正确的方向起步,但在尝试实现"特殊情况";保持你的算术符号正确。不要那样做。在运动学和动力学中,每个位置、速度或加速度都相对于您选择的坐标系。如果你的矢量方向是一致的,你就再也不用担心特殊情况了。

嗯?你是什么意思

以你的重力项const double G = 9.81;为例。除非您将Y坐标定义为向下的正坐标,否则G上的符号是错误的(陷阱…)。大多数正常的笛卡尔坐标系都将Y定义为向上的正坐标(屏幕坐标和机身坐标除外)。当Y轴向上为正时,重力的作用方向是什么?(如果感到困惑,"扔石头"——我的一位老教授:)的建议

重力以向下的方向作用,因此应声明为负值,Y向上为正值。因为随着代码的增长,几乎所有的计算函数都需要这个术语,所以你也可以将其全局化:

static const double G = -9.81;  /* global constant is fine, pay attention to sign */

然后,对于基于加速度和时间进行的每个位置计算,只需使用标准公式:

X = Xo + Vo * t + 0.5 * a * t * t;

无需在计算中插入伪'-'符号,也无需为输出划分特殊情况。当你增加作用在你的投射物上的力时,保持你的力的方向是至关重要的。所有的力都是矢量,都有一个方向。如果你总是把正确的方向赋予每一个力,你就不必再调整公式或担心特殊情况了。

对于您的计算,这意味着您可以简单地使用:

for (int i = 0; i < 15; i = i + S) {

double  Tt = i * i,                     /* seconds squared */
Ht = H + V * i + 0.5 * G * Tt,  /* pos based on acceleration & time */
Vt = V + G * i;                 /* vel based on acceleration & time */
...

(注意:基本迭代次数增加到15,这是充分观察以100 m/s或更低速度向上发射的物体的高度反转所需的——任何更快的速度和大气可压缩性都会成为一个因素)

考虑输入的连续循环

当您想要求用户提供有效的输入时,使用连续循环并在满足条件时中断读取循环会更方便。(这允许您在循环中完全包含提示和错误报告)。例如,你可以做:

while (true) {  /* loop continually until valid input (prompt within) */
std::cout << "nStarting height        : ";
if (std::cin >> H)
break;
std::cin.clear();
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), 'n');
std::cerr << "False input. Try again: ";        /* error output on cerr */
}

(注意:正确使用std::cin.ignore()做得好,您可能还想区分稍后设置的eofbitfailbit,但您做得很好)

在最终输入之后,您可以添加一个std::cout.put ('n');来提供分隔输入值和输出值的换行符。

举个例子,保存std::cout的格式化标志,然后将fixed的输出精度设置为2,你可以这样做:

#include <iostream>
#include <iomanip>
#include <limits>
static const double G = -9.81;  /* global constant is fine, pay attention to sign */
int main () {

double H = 0;               /* starting height */
double V = 0;               /* initial velocity */
int S;                      /* time step (seconds) */
while (true) {  /* loop continually until valid input (prompt within) */
std::cout << "nStarting height        : ";
if (std::cin >> H)
break;
std::cin.clear();
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), 'n');
std::cerr << "False input. Try again: ";        /* error output on cerr */
}
while (true) {
std::cout << "Starting speed         : ";
if (std::cin >> V)
break;
std::cin.clear();
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), 'n');
std::cerr << "False input. Try again: ";
}
while (true) {
std::cout << "Time Step (In seconds) : ";
if (std::cin >> S) {
std::cout.put ('n');               /* tidy up with additional newline */
break;
}
std::cin.clear();
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), 'n');
std::cerr << "False input. Try again: ";
}

std::ios_base::fmtflags f = std::cout.flags();      /* save format flags */
std::cout << std::fixed;                            /* set fixed precision */
std::cout.precision(2);                             /* of 2 */

for (int i = 0; i < 15; i = i + S) {

double  Tt = i * i,                     /* seconds squared */
Ht = H + V * i + 0.5 * G * Tt,  /* pos based on acceleration & time */
Vt = V + G * i;                 /* vel based on acceleration & time */

std::cout   << "Second: "  << std::setw(3) << i 
<< "    Height: " << std::setw(6) << Ht
<< "    Velocity: " << std::setw(6) << Vt << 'n';
}

std::cout.flags(f);                         /* restore default precision */
}

(注意:在计算或输出格式中没有"特殊情况"。还可以考虑将S设置为double类型,以便您可以输入,例如.2.1作为时间步长,以便在输出中获得更精细的粒度。您还可以添加StartTimeStopTime的输入,这将允许在短(或长)时间内对输出进行非常精细的检查周期)

示例使用/输出

例如,如果你以一枚初始高度为10米、初始向上速度为100 m/s的炮弹为例,你可以观察到速度在哪里降到零,然后随着它落回地球而开始增加。你会看到同样的高度反转。

$ ./bin/kinematic_h+v
Starting height        : 10
Starting speed         : 100
Time Step (In seconds) : 1
Second:   0    Height:  10.00    Velocity: 100.00
Second:   1    Height: 105.09    Velocity:  90.19
Second:   2    Height: 190.38    Velocity:  80.38
Second:   3    Height: 265.86    Velocity:  70.57
Second:   4    Height: 331.52    Velocity:  60.76
Second:   5    Height: 387.38    Velocity:  50.95
Second:   6    Height: 433.42    Velocity:  41.14
Second:   7    Height: 469.65    Velocity:  31.33
Second:   8    Height: 496.08    Velocity:  21.52
Second:   9    Height: 512.69    Velocity:  11.71
Second:  10    Height: 519.50    Velocity:   1.90
Second:  11    Height: 516.50    Velocity:  -7.91
Second:  12    Height: 503.68    Velocity: -17.72
Second:  13    Height: 481.05    Velocity: -27.53
Second:  14    Height: 448.62    Velocity: -37.34

如果你想要两个时间步长,你可以这样做:

$ ./bin/kinematic_h+v
Starting height        : 10
Starting speed         : 100
Time Step (In seconds) : 2
Second:   0    Height:  10.00    Velocity: 100.00
Second:   2    Height: 190.38    Velocity:  80.38
Second:   4    Height: 331.52    Velocity:  60.76
Second:   6    Height: 433.42    Velocity:  41.14
Second:   8    Height: 496.08    Velocity:  21.52
Second:  10    Height: 519.50    Velocity:   1.90
Second:  12    Height: 503.68    Velocity: -17.72
Second:  14    Height: 448.62    Velocity: -37.34

(注意:要求解炮弹达到最大高度的确切时间,只需在正常的V = Vo + a * t方程中将最终速度设置为0,然后求解t,例如t = -Vo / a。这里有一个很好的运动学计算器-Physics Catalyst,它还提供了供您使用的螺母和螺栓运动方程。)

最后,看看为什么"使用命名空间std;"被认为是不好的做法?。早养成好习惯要比晚改掉坏习惯容易得多。。。

移动到三维空间

在处理三维问题的方式上几乎没有区别。代替使用HV,使用保持double x, y, z;坐标和速度的struct变得更容易。然后,您的函数只需使用完全相同的公式独立地对xyz成员进行操作。然后,对于最终值,仅为平方和的平方根和所得角度的atan2()

此外,在三维中工作时,可以使用矢量点积和叉积,当您开始使用角速率和度量时,这些积会变得越来越有用。

仔细看看,如果你还有问题,请告诉我。

最新更新