Hey all, got a question for anyone who knows something about integrators (specifically Verlet, but any should do). I'm having problems with my Point to Line Collision response (code below). Basically if you draw two points with a mass over 0 (0 represents static elements in my implementation) and connect them with a rigid connector (the wooden stick button) then place a static point (circle with a red dot in it) below that and step through you will notice that the line does not react as you would expect. Instead of falling off to the side with the most mass its falling upwards to the side with the least mass .
Full Code: http://www.eonclash.com/physics/Verlet2.zip
Point to Line specific function (from uVerlet.pas)
[code=delphi]
procedure TVerletSystem.SatisfyPointLineCollision(P: TVerletPoint;
L: TVerletConstraint);
var
N : IVector;
massTotal, D1, D2, LineMass,
aLineMass, PM,
dist : TVectorNumber;
begin
if(P=L.P1)or(P=L.P2)then
exit;
dist := DistancePointToSegment(P.Pos, L.P1.Pos, L.P2.Pos);
if dist < P.Radius then
begin
aLineMass := ((L.P1.Mass+L.P2.Mass) / 2);
LineMass := aLineMass;
PM := P.Mass;
if(PM=0)then
PM := 10000000;
if(LineMass=0)then
LineMass := 10000000;
dist := P.Radius - dist;
N := L.P1.Pos - L.P2.Pos;
N := (N - P.Pos).Normal;
massTotal := LineMass+PM;
if(aLineMass>0)then
begin
D1:= PM/massTotal;
if(L.P2.Mass>0)then
L.P2.Pos := L.P2.Pos + (N * D1);
if(L.P1.Mass>0)then
L.P1.Pos := L.P1.Pos + (N * D1);
end;
if(P.Mass>0)then
begin
D2:= LineMass/massTotal;
P.Pos := P.Pos + (N * D2);
end;
end;
end;
[/code]
One other problem I'm having is that is seems that Mass is not affecting integration properly. I can have two points one with a very high mass and one with a lower mass collide. You would expect that the higher mass would tend to stay more on its existing path while pushing the lower mass more in the opposing direction, instead they are both affected equally.
[code=delphi]
// From uVerlet.pas
procedure TVerletSystem.Update;
...
for i := 0 to Count-1 do
begin
Item[i].Force := Item[i].Mass * Force;
Item[i].GatherForces;
end;
for i := 0 to Count-1 do
Item[i].Integrate(TimeFrame);
...
end;
// From uVerletItems.pas
procedure TVerletItem.GatherForces;
var
i : Integer;
tmp : IVector;
begin
tmp := Vector(Force);
for i := 0 to ConstraintCount-1 do
tmp += Constraint[i].GetForce(self);
Force.setto(tmp);
end;
procedure TVerletItem.Integrate(timeStep: TVectorNumber);
var
calc, fm,
last : IVector;
t2 : TVectorNumber;
begin
last := Vector(Pos);
fm := Force / Mass;
calc := Pos-LastPos;
t2 := (timeStep * timeStep);
Pos := Pos + (calc + (fm * t2));
LastPos.setto(last);
end;
[/code]
Any help greatly appreciated.
- Jeremy
Bookmarks