0
\$\begingroup\$

I working on a 2D planetary orbit simulator and I've encountered a problem regarding the collision of planets. Currently, here is what I have

if self._dist_between(p1.pos, p2.pos) <= p1.radius + p2.radius:
    pass

I detect the collisions but I don't know how to resolve them. I don't want the planets to bounce or do anything fancy, I simply want them to not pass through one another. I have tried disabling their movement completely on collision but this fails to work when more than 2 planets are active in the simulation, as when 2 planets collide they freeze in time rather than continue to be affected by the other planets.

This is the code that manages the movement

 def update(self):
    for p1 in self.planets:
        for p2 in self.planets:
            if p1 != p2:

                # Calculate and apply force
                temp_force_vector = [
                    self._gravitational_force(p1.mass, p2.mass, self._dist_between(p1.pos, p2.pos)),
                    self._radians_between(p1.pos, p2.pos)
                ]

                if self._dist_between(p1.pos, p2.pos) > p1.radius + p2.radius:
                    p1.apply_force(temp_force_vector)

                p1.update_pos()

Any suggestions?

\$\endgroup\$
  • 1
    \$\begingroup\$ Have you considered gluing them together into a single body with their combined mass? \$\endgroup\$ – DMGregory Jun 13 at 21:39
  • \$\begingroup\$ Yes, I have. However, quite embarrassingly, I can't think of an efficient way to do so due to my lack of experience. Any suggestions on how? \$\endgroup\$ – Sean Xie Jun 13 at 22:07
  • \$\begingroup\$ i made this recently; might help you sort out the logic: youtube.com/watch?v=YPR5wzbupbc. This is 3D/Unity environment. It comes down to getting a direction vector which always points along the line between the two object centers, and moving them along that line with a force. \$\endgroup\$ – khaverim Jun 13 at 22:13
  • \$\begingroup\$ It would help then if you showed us more of your code, so we understand how to interface with what you have so far. \$\endgroup\$ – DMGregory Jun 13 at 22:17
  • \$\begingroup\$ No problem. I've updated the question \$\endgroup\$ – Sean Xie Jun 13 at 23:09
0
\$\begingroup\$

Maybe you could do something like this:

Let's say we have planet A and planet B.

When A and B collide, a function is executed, and we can use it to set some values.

  1. First we decide which planet is going to be the master and which is going to be the slave. Lets say A is master and B is slave.I'll explain it later.
  2. Then we find the vector between A and B
  3. Then we add the newly recieved vector to the master's position, and set that as the position of the slave (B.pos = A.pos + vector, for example)
  4. Then we set the velocity of the master to the desired value.

This will make B have the same relative position to A as at the moment of the collision and whenever A moves, B will move with it, without changing its relative pos

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Tomake 2 bodies (planets) move together naturally. you need to make it conserve momentum. In this case you need to see inelastic collision When collision happen, both object need to be merge in to single object. velocity of new object can be obtain by v_x = (m1v1_x+m2v2_x)/(m1+m2) v_y = (m1v1_y+m2v2_y)/(m1+m2)

Additionally you should make it conserve angular momentum as well, so it still rotate around new center of mass after collistion.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.