#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

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

edited June 2017

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) {
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);
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);
}
}
}
}
}
}
``````
Tagged:

• @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.

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

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
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