Refine bullet tracing in FCS extension

Gradually increase simulation step as the projectile approaches the
target and improve the calculation of the final bullet drop.

Untested.

(#65)
This commit is contained in:
KoffeinFlummi 2015-02-17 10:24:03 +01:00
parent d3f4f2883f
commit 075d1d6d9e

View File

@ -21,7 +21,6 @@
#include <string> #include <string>
#define MAXELEVATION 20 #define MAXELEVATION 20
#define SIMULATIONSTEP 0.05
#define MAXITERATIONS 120 #define MAXITERATIONS 120
#define PRECISION 0.1 #define PRECISION 0.1
#define RADIANS(X) (X / (180 / M_PI)) #define RADIANS(X) (X / (180 / M_PI))
@ -45,7 +44,7 @@ std::vector<std::string> splitString(std::string input) {
} }
double traceBullet(double initSpeed, double airFriction, double angle, double angleTarget, double distance) { double traceBullet(double initSpeed, double airFriction, double angle, double angleTarget, double distance) {
double velX, velY, posX, posY, posTargetX, posTargetY, velMag; double velX, velY, posX, posY, lastPosX, lastPosY, posTargetX, posTargetY, velMag;
velX = cos(RADIANS(angle)) * initSpeed; velX = cos(RADIANS(angle)) * initSpeed;
velY = sin(RADIANS(angle)) * initSpeed; velY = sin(RADIANS(angle)) * initSpeed;
posX = 0; posX = 0;
@ -53,18 +52,24 @@ double traceBullet(double initSpeed, double airFriction, double angle, double an
posTargetX = cos(RADIANS(angleTarget)) * distance; posTargetX = cos(RADIANS(angleTarget)) * distance;
posTargetY = sin(RADIANS(angleTarget)) * distance; posTargetY = sin(RADIANS(angleTarget)) * distance;
double simulationStep = 0.05;
int i = 0; int i = 0;
while (i < MAXITERATIONS) { while (i < MAXITERATIONS) {
lastPosX = posX;
lastPosY = posY;
simulationStep = 0.1 - 0.049 * (posX / posTargetX);
velMag = sqrt(pow(velX, 2) + pow(velY, 2)); velMag = sqrt(pow(velX, 2) + pow(velY, 2));
velX += SIMULATIONSTEP * (velX * velMag * airFriction); velX += simulationStep * (velX * velMag * airFriction);
velY += SIMULATIONSTEP * (velY * velMag * airFriction - 9.81); velY += simulationStep * (velY * velMag * airFriction - 9.81);
posX += velX * SIMULATIONSTEP; posX += velX * simulationStep;
posY += velY * SIMULATIONSTEP; posY += velY * simulationStep;
if (posX >= posTargetX) { break; } if (posX >= posTargetX) { break; }
i++; i++;
} }
return posY - posTargetY; double coef = (posTargetX - lastPosX) / (posX - lastPosX);
return (lastPosY + (posY - lastPosY) * coef) - posTargetY;
} }
double getSolution(double initSpeed, double airFriction, double angleTarget, double distance) { double getSolution(double initSpeed, double airFriction, double angleTarget, double distance) {