Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Point to Line Collision response and Mass (Verlet)

  1. #1

    Point to Line Collision response and Mass (Verlet)

    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

  2. #2

    Re: Point to Line Collision response and Mass (Verlet)

    Just in case a few screen shots would help, below is a series of 4 shots (left to right, top to bottom) showing just before collision, the initial collision, a few steps further, and even further. As you can see, you would expect the bar to drop right and down, but instead its moving left and up.



  3. #3

    Re: Point to Line Collision response and Mass (Verlet)

    hmmm....Have you read this article about using Verlet with character physics?

    http://www.teknikus.dk/tj/gdc2001.htm

    You probably have, but I will post it anyway

    cheers,
    Paul

  4. #4

    Re: Point to Line Collision response and Mass (Verlet)

    Yep, read that article several times.

    In fact, I managed to figure out what my problem is, just can't figure out how to solve for it. The basic issue is that when a point (p) moves past a segment (s) it is moved to the "corrected path". But p's last position isn't updated properly so that the verlet system can utilize the last position to create the next frames movement vector.

    Need to figure out a way to calculate angle of incidence and angle of reflection using vectors instead of algebra . Also need to find the proper last position for p using vector math. If I have time I'll post up an image showing what I'm talking about.

    - Jeremy

  5. #5

    Re: Point to Line Collision response and Mass (Verlet)

    Ok, here is a quick capture of two simulations that show the problem better. On the left is a single particle striking a static bar and bouncing in the wrong direction. Given the angle of the line you would expect it to follow (sort of) the green arrows, instead it follows the red (as seen).

    The right contains a bar falling and striking a single point. Instead of the right side of the bar moving upwards with the left continuing downward (as expected and shown with the green and blue arrows) it always moves up and left. No matter what every time a bar and a point collide the result is to move left .

    Any ideas now?


  6. #6

    Re: Point to Line Collision response and Mass (Verlet)

    The line
    [pascal]
    procedure TVerletSystem.Update
    ...
    Item[i].Force := Item[i].Mass * Force;
    ...
    [/pascal]
    looks susopicious to me (units don't match ). Since the force acting on the item is multiplied by its mass, the acceleration ( calculated in the TVerletItem.Integrate procedure) is the same for all items. That is why mass does not affect the motion.
    I think You should remove multiplication by mass.

  7. #7

    Re: Point to Line Collision response and Mass (Verlet)

    I think you might be misreading the code;
    • The initial Item.Force = Force * Item.Mass calculation is using the global force to perform a scale on the local mass of the object.
    • Thus presenting a basic force vector to representing basic gravity (if in affect).
    • Then inside of the item.gatherforces all other local (constraint) forces are added to this initial value.
    • Integrate utilizes this final force along with the objects mass, last-position, and the time-step to calculate the actual movement of the object for the frame.


    Of course, that's if I understand the theory properly

  8. #8

    Re: Point to Line Collision response and Mass (Verlet)

    Oh wait, I'm an idiot who misread the theory LOL. Your right, the division by mass inside the integration step isn't necessary. By removing it you get proper reaction of a V2=M1*2*V1 (or an object with twice the mass should have twice the velocity as another object).

    Ok, well that fixes that. Now, back to the problem of the bouncing balls and sticks

  9. #9

    Re: Point to Line Collision response and Mass (Verlet)

    Quote Originally Posted by jdarling
    Oh wait, I'm an idiot who misread the theory LOL. Your right, the division by mass inside the integration step isn't necessary. By removing it you get proper reaction of a V2=M1*2*V1 (or an object with twice the mass should have twice the velocity as another object).

    Ok, well that fixes that. Now, back to the problem of the bouncing balls and sticks
    Good to see you got that bit working

    Now back to reflection rays you were wanting...

    Here is the code I use in my raytracer for calculating a reflection ray, and it doesn't use any trigonometry at all

    [pascal] // calculate reflection
    refl := prim.Material.Reflection;
    If refl > 0.0 Then
    Begin
    If ADepth < FMaxTraceDepth Then
    // spawn secondary rays
    Begin
    N := prim.GetNormalAt(pi);
    R := VectorSub(ARay.Direction,VectorScale(N,2.0 * DotProduct(ARay.Direction,N)));
    rcol := Color4f(0, 0, 0);
    reflray.Origin := VectorAdd(pi,VectorScale(R,cEpsilon));
    reflray.Direction := R;
    Raytrace(reflray, rcol, ADepth + 1, ARIndex, dist);
    AAcc.r := AAcc.r + refl * rcol.r * primColor.r;
    AAcc.g := AAcc.g + refl * rcol.g * primColor.g;
    AAcc.b := AAcc.b + refl * rcol.b * primColor.b;
    End;
    End;
    [/pascal]

    I hope it helps
    cheers,
    Paul

  10. #10

    Re: Point to Line Collision response and Mass (Verlet)

    Making minor changes to your code, it would appear that the parts I actually need would be:
    [pascal]
    // calculate reflection
    N := prim.GetNormalAt(pi);
    R := VectorSub(ARay.Direction,VectorScale(N,2.0 * DotProduct(ARay.Direction,N)));
    reflray.Origin := VectorAdd(pi,VectorScale(R,cEpsilon));
    [/pascal]


    That would suggest that I first need to know pi (and I'm guessing that isn't 3.1415). In this case, is pi the intersection of the point on the surface?

    Lets go to a visual aid:


    Given your above code I think that the following mapping is appropriate:
    N - Normal of the intersection point of [V-1]->V to A->B
    A.RayDirection - V - [V-1]
    cEpsilon - Proper Scaled Epsilon (please tell me you arn't using static 0.0000001 in a ray tracer)

    My response (using dts as Delta Time Step difference) [nV-dts]->nV would then be equal to reflray.Origin->R correct?

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •