# Sphere-Cloth Collision

This topic is 3018 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I am trying to simulate cloth and sphere collision. What I am trying to do is to calculate Vector3d offset = Cloth.Particle[] - ball; float len = offset.length(); if(len < radius_of_ball) { //collision is there //Since the shpere is moving along the z direction I tried to cut out the particle velocity around that direction //then the particle should be along the surface of the sphere Cloth.Particle[].velocity.z = 0.0; } But what happens is that, the sphere passes in and out of the cloth without any realistic behaviour. Is the approach right or what should I try and calculate to make it work. All suggestions are welcome...

##### Share on other sites
Quote:
 Original post by marcus12Hi, I am trying to simulate cloth and sphere collision. What I am trying to do is to calculateVector3d offset = Cloth.Particle[] - ball;float len = offset.length();if(len < radius_of_ball){//collision is there //Since the shpere is moving along the z direction I tried to cut out the particle velocity around that direction //then the particle should be along the surface of the sphereCloth.Particle[].velocity.z = 0.0;}But what happens is that, the sphere passes in and out of the cloth without any realistic behaviour.Is the approach right or what should I try and calculate to make it work.All suggestions are welcome...

Hi,

Its strange that no one replied :-(

##### Share on other sites
What you might try doing, if you don't already have this, is make it render the sphere and the points of the cloth.

From here you should be able to see if something is wrong with your code and it isn't working right (cloth balls are going into the sphere), or if something else is going on, such as the "holes" in your cloth (ie the places between your cloth points) are too big and the sphere goes through without much of a problem.

Something else you might try doing is instead of testing the sphere against the points in the cloth, instead test the sphere against the TRIANGLES of the cloth.

that will give you a more realistic result, at the cost of a little more computation time.

##### Share on other sites
oh also something else to try...

If the point on the cloth is less than the radius of the sphere, instead of just setting the z velocity to 0 what you should try doing is...

#1 - Get a vector from the center of the sphere to the cloth ball.
#2 - normalize that vector
#3 - multiply that vector by the sphere radius
#4 - move the ball to that position (ie sphere center + new vector)

That should give you a lot better results I think

##### Share on other sites
Finding if a point is inside a sphere is easy. I also assume that your cloth particles have a 'mass' associated with them.

Here's something you can try.

Quote:
 bool particleInSphere(const Vector& particle, const Vector& centre, float radius, Vector& ncoll, float& dcoll){ Vector delta = (particle - centre); float distance_squared = delta.dotProduct(delta); if(distance_squared > (radius*radius)) return false; float distance = sqrt(distance_squared); ncoll = delta; if(distance > 0.0001f) ncoll /= distance; dcoll = (radius - distance); return true;}bool collideParticleAndSphere(Vector& particle_pos, Vector& particle_vel, float particle_inverse_mass, Vector& sphere_pos, Vector& sphere_vel, float sphere_radius, float sphere_inverse_mass){ Vector ncoll; float dcoll; if(!particleInSphere(particle_pos, sphere_pos, sphere_radius, ncoll, dcoll)) return false; // resolve intersection. push sphere and particle away from each other. // the lighter of the two will be pushed more. particle_pos += ncoll * (dcoll * particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); sphere_pos -= ncoll * (dcoll * sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); // combined velocity Vector v = (particle_vel - sphere_vel); // impact velocity float vn = v.dotProduct(ncoll); // objects moving from each other already. add no impulse. if(vn > 0.0f) return true; // coefficient of restitution (how much bounce you want). const float cor = 0.5f; // collision impulse between the objects. Vector impulse = ncoll * (-(1.0f + cor) * vn); // apply impulse to change their velocity. // the lighter of the two will have more of its momentum changed. particle_vel += impulse * (particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); sphere_vel -= impulse * (sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); return true;}

##### Share on other sites
Quote:
Original post by oliii
Finding if a point is inside a sphere is easy. I also assume that your cloth particles have a 'mass' associated with them.

Here's something you can try.

Quote:
 bool particleInSphere(const Vector& particle, const Vector& centre, float radius, Vector& ncoll, float& dcoll){ Vector delta = (particle - centre); float distance_squared = delta.dotProduct(delta); if(distance_squared > (radius*radius)) return false; float distance = sqrt(distance_squared); ncoll = delta; if(distance > 0.0001f) ncoll /= distance; dcoll = (radius - distance); return true;}bool collideParticleAndSphere(Vector& particle_pos, Vector& particle_vel, float particle_inverse_mass, Vector& sphere_pos, Vector& sphere_vel, float sphere_radius, float sphere_inverse_mass){ Vector ncoll; float dcoll; if(!particleInSphere(particle_pos, sphere_pos, sphere_radius, ncoll, dcoll)) return false; // resolve intersection. push sphere and particle away from each other. // the lighter of the two will be pushed more. particle_pos += ncoll * (dcoll * particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); sphere_pos -= ncoll * (dcoll * sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); // combined velocity Vector v = (particle_vel - sphere_vel); // impact velocity float vn = v.dotProduct(ncoll); // objects moving from each other already. add no impulse. if(vn > 0.0f) return true; // coefficient of restitution (how much bounce you want). const float cor = 0.5f; // collision impulse between the objects. Vector impulse = ncoll * (-(1.0f + cor) * vn); // apply impulse to change their velocity. // the lighter of the two will have more of its momentum changed. particle_vel += impulse * (particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); sphere_vel -= impulse * (sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); return true;}

Hi,
Particles position should get updated with change in force, so is it right to move the particles by giving specific positions? like
Quote:
  particle_pos += ncoll * (dcoll * particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));
[/quote]

Also my cloth simulation seems to work properly like the cloth behaves properly under wind and gravity, but as soon as the cloth comes in contact with the rigid body it explodes.
I tested with the Oliii logic for collision it works properly around the edges nicely but not at the centre of clothes, also after couple of collision tests the cloth explodes.

Does it because the spring are not working properly? I have used Hooks law and given all the structural and sheer springs equal forces in the begining.

What are the things I should consider to test whether the springs are working correctly as the spring behaves unrealistic only under collision?

All suggestions are welcome....

##### Share on other sites
Have you tried your cloth with simulated wind and movement? Does it breaks up under tension and compression?

##### Share on other sites
Quote:
 Original post by oliiiHave you tried your cloth with simulated wind and movement? Does it breaks up under tension and compression?

It does not break under the wind force and behaves quite normally, the problem only comes when it comes in touch with a rigid body then the whole particles tries to go in a zig zag pattern in any direction.

##### Share on other sites
try without the response.

Quote:
 bool collideParticleAndSphere(Vector& particle_pos, Vector& particle_vel, float particle_inverse_mass, Vector& sphere_pos, Vector& sphere_vel, float sphere_radius, float sphere_inverse_mass){ Vector ncoll; float dcoll; if(!particleInSphere(particle_pos, sphere_pos, sphere_radius, ncoll, dcoll)) return false; // resolve intersection. push sphere and particle away from each other. // the lighter of the two will be pushed more. particle_pos += ncoll * (dcoll * particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass)); sphere_pos -= ncoll * (dcoll * sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));}

1. 1
2. 2
Rutin
22
3. 3
JoeJ
20
4. 4
5. 5

• 27
• 40
• 23
• 13
• 13
• ### Forum Statistics

• Total Topics
631735
• Total Posts
3001940
×