弹丸不会在负角度上向下移动

时间:2016-11-27 04:02:19

标签: c++ math visual-studio-2015 physics

我正在构建一个小物理引擎,用户在一组发射参数上发射射弹(角度,高度,时间间隔和初始速度),然后显示一些信息,如总距离或角度。它每次都在空中间隔:

bool heightCheck = false;
double theta;
double initialVelocity, velocity;
double yNew = 0.0, xNew, xOld = 0.0, yOld = 0.0;
const double time = 0.1;
const double gravitiyHalf = 9.8 / 2;
double velocityX = 0.0, velocityY = 0.0;
double angle = 0.0;
double totalT = 0;
double maxHeight = 0.0;
double thetaDegrees = 0;
#define PI 3.14159265l  // constant for PI

cout << "Insert a lanuch Angle (theta): ";  
cin >> thetaDegrees;    
cout << "Insert a launch height: ";     
cin >> yOld;            
cout << "Insert an initial velocity: ";     
cin >> initialVelocity;     
cout << "Time (DeltaT) in seconds: ";   
cin >> totalT;

for (double deltaTime = 0.0; deltaTime < totalT; deltaTime += 0.1) {

    const double squared = deltaTime * deltaTime;       // squared constant for deltaTime squared

    theta = thetaDegrees * PI / 180;    // converts theta to a degrees value

    velocityX = initialVelocity * cos(theta);   // calculates Vx
    velocityY = initialVelocity * sin(theta);   // calculates Vy

    // apply initialV to velocity
    velocity = initialVelocity + 9.8 * time;

    xNew = xOld + velocity * time;  // works out displacement for X

    yNew = yOld + velocity * deltaTime - gravitiyHalf / 0.5 * (squared);    // calculates Y

    velocityY = velocity - 9.8 * deltaTime; // includes gravity to Y

    angle = atan2(yNew, xNew) * 180 / PI;   // convert angle to degrees

    cout << "\nHeight: " << yNew << endl;
    cout << "Distance in Meters: " << xNew << "m" << endl;
    cout << "Angle: " << angle << endl;
    cout << "Time: " << deltaTime << "s " << endl;

    if (heightCheck == false) {
        maxHeight = yOld;
        // keep maxheight equal to previous height
    }

    if (yNew < yOld && heightCheck == false) {
        heightCheck = true;
        // if projectile is going down, trigger maxheight
    }

    cout << "Maximum height:  " << maxHeight << endl;

    if ((yNew < 0) || (deltaTime == totalT)) {
        getchar();      // stops if delta t = total T or projectile landed
    }

    yOld = yNew;    // refresh x & y
    xOld = xNew;
}

如果我在程序开头输入以下值:

theteDegrees = 45

yOld = 0

initialVelocity = 20

totalT = 10

我的程序显示预期结果,显示我的射弹上升,然后下降。但是,如果我为thetaDegrees输入相同的值 -40 ,我的射弹应该直接向下,而不是它只是上升然后再次下降

我的代码在哪里出错?

2 个答案:

答案 0 :(得分:0)

正如伊戈尔所说,在X和Y的距离计算中,你没有考虑到velocityX和velocityY。

    xNew = xOld + velocity * time;  // works out displacement for X
    yNew = yOld + velocity * deltaTime - gravitiyHalf / 0.5 * (squared);    // calculates Y

涉及一些冗余计算。更简单的版本可能是这样的。

theta = thetaDegrees * PI / 180;    // converts theta to a degrees value

velocityX = initialVelocity * cos(theta);   // calculates Vx
velocityY = initialVelocity * sin(theta);   // calculates Vy

//cout<<velocityX<<endl<<velocityY<<endl;

for (double deltaTime = 0.0; deltaTime < totalT; deltaTime += 0.1) {

const double squared = deltaTime * deltaTime;       // squared constant for deltaTime squared

xNew = xOld + velocityX * time;  // works out displacement for X

yNew = yOld + velocityY * deltaTime - gravitiyHalf / 0.5 * (squared);    // calculates Y

velocityY = velocityY - 9.8 * deltaTime; // includes gravity to Y

angle = atan2(yNew, xNew) * 180 / PI;   // convert angle to degrees

cout << "\nHeight: " << yNew << endl;
cout << "Distance in Meters: " << xNew << "m" << endl;
cout << "Angle: " << angle << endl;
cout << "Time: " << deltaTime << "s " << endl;

if (heightCheck == false) {
    maxHeight = yOld;
    // keep maxheight equal to previous height
}

if (yNew < yOld && heightCheck == false) {
    heightCheck = true;
    // if projectile is going down, trigger maxheight
}

cout << "Maximum height:  " << maxHeight << endl;

if ((yNew < 0) || (deltaTime == totalT)) {
    getchar();      // stops if delta t = total T or projectile landed
}

yOld = yNew;    // refresh x & y
xOld = xNew;
}

答案 1 :(得分:0)

您必须更改

xNew = xOld + velocityX * time;  // works out displacement for X

xNew = xOld + velocityX * deltaTime;  // works out displacement for X

或删除

xOld = xNew;

最后,因为保持两者不变会给你一个二次加速的x坐标,而不是一个恒定速度的线性运动。