How to preserve distance between 3d objects in order that they won't collide?!

Hi, I was wondering if someone could check this method based on shiffman's nature of code's one. In my sketch some spheres rotate in a 3d space and I try to force them to stay at a certain distance that they won't collide and stick together... Here is just the method below...Thanks a lot in advance ;))

void separate (Sphere[]planets) {
    float desiredDist = radius*6;
    PVector sum = new PVector();
    int count = 0;
    if (planets != null) {
      if (level > 0 ) {
        for (int i = 0; i <planets.length; i++) {
          int j=1;
          for (j+=i; j<planets.length; j++) {
            float d = PVector.dist(planets[i].location, planets[j].location);
            if ((d >0) && (d<desiredDist)) {
              PVector diff = PVector.sub(planets[i].location, planets[j].location);
              diff.normalize();
              diff.div(d);
              sum.add(diff);
              count++;
            }

            if (count > 0) {
              sum.div((float)count);
            }
            if (sum.mag() > 0) {
              sum.setMag(maxSpeed);
              PVector steer = PVector.sub(sum, velocity);
              steer.limit(maxForce);
              applyForce(steer);
            }
          }
        }
      }
    }
  }

Answers

  • @lolonulu -- is your goal to create a 3D sphere effect like the Bouncing Bubbles example for ellipses -- collision detection that affects direction and speed?

  • Dera Jeremy, thank you for your answer, yes this is my goal, but with 3d spheres...

  • Notice line 11 d>0, d is always positive. In this line, you are excluding the case d==0 which probly you don't want to... In other words, this checking is redundant and not needed.


    For lines 8 and 9 should become:

    for (int j=i+1; j<planets.length; j++) {


    Line 13 and 14 are doing the same thing, so you are normalizing twice. You need only one of them so keep the first line.


    There is something that I don't understand with on your code and it is regarding the count variable. The count variable never gets reset. I don't think this is a desirable design in your case.


    Vector velocity showed up in your code with no warning. How is this vector related to the current planet as pointed out by the index i?

    Also, I think line 10 should read:

    float d = PVector.dist(planets[j].location, planets[i].location); //Indices switched!

    I suggest you do the debugging of your core code in a simple sketch, maybe a universe confined in a square box and study the bouncy of spheres in this space.

    Kf

  • Also, I think line 10 should read: ... // Indices switched!

    Surely the distance between a and b is the same as the distance between b and a. It's commutative - order doesn't matter.

  • Answer ✓

    Runable examples are always better.

  • I agree with koogs -- add a very short runnable example showing how you are using separate in a simple sketch.

  • Thank you very much Kfrajer, koogs and Jeremy, yes I will try with a short runnable example to debugg my code, then I'll post it. Tomorrow I think...Thank you guys for your replies

  • Answer ✓

    You are right @koogs, The dist() function returns a scalar and I was thinking in vectorial space. The distance is only required to check for the closeness between any two spheres. @lolonulu is taking care of the vectorial calculation in line 12.

    You can always explore code available online: https://www.google.ca/search?q=java+collision+3D&rlz=1C1CHWA_enCA688CA688&oq=java+collision+3D&aqs=chrome..69i57j0l5.3502j0j8&sourceid=chrome&ie=UTF-8#q=processing+collision+3D

    Kf

  • Dear kfrjer, koogs and jeremydouglas,

    I think I found the solution in a code available online: https://www.openprocessing.org/sketch/397053 Here is the part of the method that I used to calculate the distance detween the 3d spheres:

              for(Particle p1: particles){ // declare two lists of particles
                for(Particle p2: particles){
                  if(p1 == p2){continue;} // if the same go on
                  float d = PVector.dist(p1.loc, p2.loc); // calculate the dist between locations
                  if(d <= p1.radius + p2.radius){
                    PVector p12 = PVector.sub(p2.loc, p1.loc);// sub. loc. 1 from loc.2
                    PVector n = PVector.div(p12, p12.mag()); // divide this vector by its magnitude
                    PVector v12 = PVector.sub(p2.vel, p1.vel); // now do the same for velocity: substract p1 velocity from P2 velocity
                    PVector vn1 = PVector.mult(n, PVector.dot(p1.vel, n)); // multiply n(p12 div. by its own magnitude) by the dot product of vel.p1 by n!
                    PVector vt1 = PVector.sub(p1.vel, vn1); // substract the result from velocity of p1
                    PVector t = PVector.div(vt1, vt1.mag()); // divide this vector by its magnitude
                    float spring = -k * (p1.radius + p2.radius - d); // we pass a negative value (-2=-k) in order to multiply the distance/spring
                    float j = (1 + e) * (p1.mass * p2.mass / (p1.mass + p2.mass)) * PVector.dot(v12, n); 
                    // e and mass=1, so here it's 2 multiply by the dot product of the vectors V12 and n
                    PVector impulse = PVector.mult(n, j + spring); // this last vector impulse
                    equals to n multiply by j+spring
                    p1.nvel.add(impulse); // finally we add this vector impulse to our new velocity (: nvel) in order the speheres will repulse each other
                  }
                }
              }
    
          for(Particle p: particles){
            p.updateVel();
          }
    
        /////////////////////////////////////////////////////////////////////////
    
        void updateVel(){
            vel = nvel;
            nvel = new PVector(vel.x, vel.y, vel.z);
    
          }
    

    I hope it will be helpful to anyone. The best is to check out the original sketch off course! Thanks a lot guys for your help. I appreciate ;) best, l

Sign In or Register to comment.