Optimizing gravitation calculation for particles in a zero gravity 2d space

前端 未结 5 955
北荒
北荒 2021-01-13 07:28

I\'ve have created a small visualisation of particles in python. I\'m caclulation the movement of particels in a 2D space with zero gravity. As each particle attracts all o

5条回答
  •  不思量自难忘°
    2021-01-13 07:38

    Not sure if this will help you out much but it's part of a solution I've been working on for the same problem. I didn't notice a huge gain in performance doing it this way, still starting to grind to a halt around 200 particles, but maybe it'll give you some ideas.

    C++ module for calculating the x and y components of gravitational attraction on a 2d plane:

    #include 
    #include 
    
    double _acceleration(double &Vxa, double &Vya, double &Vxb, double &Vyb, double xa, double ya, double xb, double yb, double massa, double massb)
    {
       double xdiff = xa - xb;
       double ydiff = ya - yb;
       double distance = sqrt(xdiff*xdiff + ydiff*ydiff) * pow(10, 5);
    
       if (distance <= 0)
          distance = 1;
    
       double force = (6.674 * pow(10, -11))*(massa*massb)/(distance*distance);
    
       double acca = force / massa;
       double accb = force / massb;
       double xcomponent = xdiff/distance;
       double ycomponent = ydiff/distance;
    
       Vxa -= acca * xcomponent;
       Vya -= acca * ycomponent;
       Vxb += accb * xcomponent;
       Vyb += accb * ycomponent;
    
       return distance;
    }
    
    static PyObject* gforces(PyObject* self, PyObject* args)
    {
       double Vxa, Vya, Vxb, Vyb, xa, ya, xb, yb, massa, massb, distance;
    
       if (!PyArg_ParseTuple(args, "ffffdffffdffffdd", &Vxa, &Vya, &Vxb, &Vyb, &xa, &ya, &xb, &yb, &massa, &massb))
          return NULL;
    
       distance = _acceleration(Vxa, Vya, Vxb, Vyb, xa, ya, xb, yb, massa, massb);
    
       return Py_BuildValue("ffffffffd", Vxa, Vya, Vxb, Vyb, distance);
    }
    
    static PyMethodDef GForcesMethods[] = {
    {"gforces", gforces, METH_VARARGS, "Calculate the x and y acceleration of two masses and the distance between the two."},
    {NULL, NULL, 0, NULL}
    };
    
    PyMODINIT_FUNC
    initgforces(void)
    {
    (void) Py_InitModule("gforces", GForcesMethods);
    }
    

    If you compile this as a pyd file you should get a python object that you can import. You do have to get all your compiler and linker options correct though. I'm using dev-C++ and have my compiler options set to -shared -o gforces.pyd and linker set to -lpython27 (make sure you use the same version you have installed) and add your python directory path to the includes and libraries tabs.

    The object takes the arguments ( p1.speedx, p1.speedy, p2.speedx, p2.speedy, p1.x, p1.y, p2.x, p2.y, p1.mass, p2.mass ) and returns the new p1.speedx, p1.speedy, p2.speedx, p2.speedy, and distance between p1 p2.

    Using the above module, I've also tried to cut out a few steps for the collision detection by comparing the returned distance to the sum of the particles' radii as such:

    def updateForces(self):         #part of a handler class for the particles
        prevDone = []
        for i in self.planetGroup:  #planetGroup is a sprite group from pygame
            prevDone.append(i.ID)
            for j in self.planetGroup:
                if not (j.ID in prevDone):               #my particles have unique IDs
                    distance = i.calcGForce( j )         #calcGForce just calls the above  
                    if distance <= i.radius + j.radius:  #object and assigns the returned 
                        #collision handling goes here    #values for the x and y speed
                                                         #components to the particles
    

    Hope this helps a bit. Any further advice or pointing out of gross errors on my part is welcome, I'm new to this as well.

提交回复
热议问题