Physical modeling gives a (very) inaccurate position for calculating simple trajectories

I want to implement a physical engine in a game to calculate the trajectories of bodies with the forces applied to them. This engine will calculate each state of an object based on its previous state. Of course, this means that a large calculation between two units of time will be fairly accurate.

To do this correctly, I wanted to first find out how large the differences are between this method of obtaining positions and with kinematic equations. So I made this code that stores the positions (x, y, z) given by simulations and equations in a file.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "header.h"


Body nouveauCorps(Body body, Vector3 force, double deltaT){
    double m = body.mass;
    double t = deltaT;

    //Newton second law:
    double ax = force.x/m;
    double ay = force.y/m;
    double az = force.z/m;

    body.speedx += ax*t;
    body.speedy += ay*t;
    body.speedz += az*t;

    body.x +=t*body.speedx;
    body.y +=t*body.speedy;
    body.z +=t*body.speedz;

    return body;
}

int main()
{
    //Initial conditions:
    double posX = 1.4568899;
    double posY = 5.6584225;
    double posZ = -8.8944444;
    double speedX = 0.232323;
    double speedY = -1.6565656;
    double speedZ = -8.6565656;
    double mass = 558.74;

    //Force applied:
    Vector3 force = {5.8745554, -97887.568, 543.5875};

    Body body = {posX, posY, posZ, speedX, speedY, speedZ, mass};

    double duration = 10.0;
    double pointsPS = 100.0; //Points Per Second
    double pointsTot = duration * pointsPS;

    char name[20];
    sprintf(name, "BN_%fs-%fpts.txt", duration, pointsPS);

    remove(name);
    FILE* fichier = NULL;
    fichier = fopen(name, "w");

    for(int i=1; i<=pointsTot; i++){
        body = nouveauCorps(body, force, duration/pointsTot);
        double t = i/pointsPS;

        //Make a table: TIME | POS_X, Y, Z by simulation | POS_X, Y, Z by modele (reference)
        fprintf(fichier, "%e \t %e \t %e \t %e \t %e \t %e \t %e\n", t, body.x, body.y, body.z, force.x*(t*t)/2.0/mass + speedX*t + posX, force.y*(t*t)/2.0/mass + speedY*t + posY, force.z*(t*t)/2.0/mass + speedZ*t + posZ);
    }
    return 0;
}

, (, -9.81) , ( ) .

?

. (: , Temps = Time).

  • + :
  • : 100
  • : 1000
  • : 10000
+4
1

. , , .

, , ODE, .

, Forward Euler. , , . , .

-, . O(Δt²). , . , , 1/4 .

, . , , . O(Δt). , , .

- , . , 10 , 10 : 10 , 10 .


, Forward Euler , . , . , , ODE:

x' = -k * x

k - . x(t) = x(0) * exp( -k * t ). k , x 0 .

, Forward Euler, - :

x(t + Δt) = x(t) + Δt * ( -k * x[n] )
          = ( 1 - k * Δt ) * x(t)

, :

x(t) = ( 1 - k * Δt )^(t / Δt) * x(0)

0 t. Forward Euler , |1 - k * Δt| < 1. , , k ODE. k , , , . : .

, , .

+6

Source: https://habr.com/ru/post/1681824/


All Articles