   2D Verlet Segment-Particle Collision Response
  I want to create a game like Soldat and Worms but instead ofstatic or destructable terrain, I want movable terrain.So I have the verlet integration put in and I want to make it sothat I can anchor a "rope" and have the objects move alongthe rope.  The landscape for the game would be consisted purelyof these ropes.  So to make static geometry all I have to do isanchor all the points of the rope, or if I want something like abridge I just anchor the ends of the rope.Here's a screenshot.  This is the "bridge" effect I'm talkingabout.  BTW, the GREEN segments are the collision segments,so as you may notice the objects are themselves just a collectionof collision segments.  Objects and landscapes are one and thesame.DemoUse the mouse to move the points.ImageLib(DevIL) DLLs here.SDL 1.2 DLLs here.msvcp70d DLL here.msvcr70d DLL here.Sorry for all the DLLs, but you guys SHOULD have SDL and ImageLib already.  I'll switch over to Dev-C++ soon to avoid the MSVC7 DLLs.I'm having trouble with the collision response.  It works if theobjects are going slow, but once they start moving quickly theybecome penetrated and spring off.  /*ParticleSystem member variable -> vector<Particle> particles;ParticleSystem member variable -> vector<Segment> collisionSegments;struct Particle{Vector2 x; // Current position.Vector2 oldX;// Old position.Vector2 a; // Force accumulator.float mass;Particle(){}Particle(Vector2 x_, Vector2 oldX_, Vector2 a_, float mass_): x(x_), oldX(oldX_), a(a_), mass(mass_){}void render();};struct Segment{int pA, pB; // Indices of the pair of points from ParticleSystem::particles;Segment(){}Segment(int pA_, int pB_): pA(pA_), pB(pB_){}};*/void ParticleSystem::collideParticlesWithSegments(){for(unsigned i = 0; i < particles.size(); i++){Vector2 Pi = particles[i].oldX;Vector2 P = particles[i].x;for(unsigned j = 0; j < collisionSegments.size(); j++){if(collisionSegments[j].pA == i)continue;if(collisionSegments[j].pB == i)continue;int pA = collisionSegments[j].pA;int pB = collisionSegments[j].pB;Vector2 A = particles[pA].x;Vector2 B = particles[pB].x;Vector2 AB = B - A;Vector2 AP = P - A;float distance = perp(AP, AB) / AB.magnitude();// collision equations.  Test if circle collides with segment.// Got this equation from some math messageboard.bool collide = false;float u = ((B.x-A.x)*(P.x-A.x)+(B.y-A.y)*(P.y-A.y)) / ((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));float radius = 15.0f;float distanceSquared;float iX, iY; // Intersection points.if(u >= 0.0f && u <= 1.0f){iX = A.x + (B.x-A.x)*u;iY = A.y + (B.y-A.y)*u;distanceSquared = (iY-P.y)*(iY-P.y)+(iX-P.x)*(iX-P.x);collide = distanceSquared < radius * radius;}if(collide){float cosineBetween = cosine(AB, P - Pi);Vector2 normal(B.y - A.y, A.x - B.x);if(cosineBetween < 0)normal *= -1.0f;normal.normalize();// Got this from Olivier Renault's rigid body demo.//-----------------------------------------------------------// the amount of friction//-----------------------------------------------------------const float friction = 0.5f;//-----------------------------------------------------------// Move particle away from plane//-----------------------------------------------------------particles[i].x += normal * sqrt(distanceSquared);Vector2 V = (particles[i].x - particles[i].oldX);//-----------------------------------------------------------// calculate velcity along normal, and collision plane//-----------------------------------------------------------Vector2 Vn = normal * dot(V, normal);Vector2 Vt = (V - Vn);//-----------------------------------------------------------// apply friction.//-----------------------------------------------------------particles[i].x -= Vt * friction;}}}}  ===========================================================Net Death -- 2D Deathmatch -- http://kyc-bats.sf.net[edited by - kyc on February 14, 2004 4:34:56 PM]
  you need to do some kind of swept test to check wether the particle crossed the edge. either, a swept sphere vs segment test, or just a particle. here's what I've got as an example. using a particle with radius would be better though. I tried it for random particles, from great velocities to zeroed velocities, against static segments, and it behaves itself.   bool collide(const Vector& e0, const Vector& e1, const Vector& p0, Vector& p1){Vector e = e1 - e0;// edge directionVector d = p1 - p0;// dispalcement of the particleVector n = Vector(-e.y, e.x);// edge normalfloat m  = e0 * n;// edge distance from origin along edge normalfloat s0 = p0 * n;// start position distance from origin along edge normalfloat s1 = p1 * n;// end   position distance from origin along edge normalif (sgn(s1 - m) == sgn(s0 - m))// did the particle crossed the edgereturn false;float t = (m - s0) / (s1 - s0);// calculate time of intersectionn.Normalise();Vector pcoll;pcoll = p0 + d * t + (n * threshold);// poisiton of the particle on the edge, with extra threshold to make surefloat e2 = e*e;// edge length squaredfloat le = (p1 - e0) * e;// projection of the particle on the edgeif (le < 0.0f || le > e2)// particle not on the edge, return no intersectionreturn false;p1 = pcoll;return true;} [edited by - oliii on February 14, 2004 6:34:59 PM];  Thanks Oliii, I've made a better version using the snippet yougave.  The response is better now, except the impulse is greaterthan what it needs to be, and there's still penetration.Here's the binary only.  Use the same data from the previous version.oliii_better.zipI want the objects to be able to "stand" leveled on the "bridge."I also want the objects to be carried correctly when I drag thebridge around.  Sort of like a ball rolling on a blanket.  Whenyou yank or tilt the blanket, the ball should roll around softlynot jump up like crazy and fall off.   [edited by - kyc on February 14, 2004 10:13:40 PM];  you''ve got some weird jumping here...In the demo, I never test particle against constraints. Only particle against particle, and particle against solid geometry. Yeah, you''re gonna have problems with particles and constraints, since the segments change when you apply the constraint. So a segment could go through a particle. That''s why I only did particle vs particles ok, so what you need, is a radius around the particle, possibly a thickness on the segment, to be extra sure, and do a capsule / moving sphere intersection, which boils down to a ray-capsule test. Since the segment will still move, it won;t be perfect, but better. Or build the bridge like a pearl necklace, and fill the box and triangle with interconnected sphere. Then it''s just particle vs particle collision tests. That''s what Bouncer does.  ;  also, I noticed that the segments on the box face the wrong way.  