Bridges

Official forum for the Chipmunk2D Physics Library.
Post Reply
pokeyman
Posts: 6
Joined: Wed May 13, 2009 4:08 am
Contact:

Bridges

Post by pokeyman »

I've been fiddling around with code and searching Google/these forums for awhile now, and haven't figured out how to do what I'm trying to do.

I'd like to simulate a train crossing a bridge. The bridge is made of beams that are connected to one another at their endpoints. The train is to cross a particular row of beams, stressing the beams and the joints between the beams. (One day, too much stress will break the beams/joints, sending the train to its doom, etc. etc., but that's another post.)

I've considered (and attempted the first two of) a few ways to do this:
  1. Make one body at the middle of each beam, then add to it a line segment/rectangular polygon. Use pin/pivot joints between beams.
    Benefit: Train runs along the beam.
    Problem: The beams pivot around their midpoints, not their endpoints. This is how the bridge demo is set up, and it makes a nice rope bridge but isn't my goal.
  2. Make two bodies, one at each endpoint of the beam, and connect them with a pin joint.
    Benefit: The beams interact as intended.
    Problem: There are no collision shapes between the two bodies, so the train only collides with the endpoints; train falls every time.
  3. Make three bodies: one at each endpoint, and one in the middle. Connect the endpoints with a pin joint, and connect each endpoint with the midpoint with a pin joint (so the three bodies always form a line). Add a segment shape to the midpoint body, and manually update its endpoints every step to match the endpoint bodies.
    Benefit: Best of both worlds?
    Problem: I have no idea how to do this, or even if this makes any sense.
I want the benefits of the first two with neither problem. Is idea 3 likely fruitful? Is there a better idea worth consideration? Or am I using the wrong library?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Bridges

Post by slembcke »

What do you mean that you want the beams to pivot around their endpoints instead of the midpoints? The center of gravity is going to be in the middle of the beam. You said that the bridge demo pivoted around the endpoints, but that is not the case. They pivot around the center of gravity which is in the middle of the beam. They are connected by pin joints at the endpoints.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
pokeyman
Posts: 6
Joined: Wed May 13, 2009 4:08 am
Contact:

Re: Bridges

Post by pokeyman »

Right, the center of gravity is the middle of the beam, so it makes the most sense to me to have one body and place it at the center. I'm guessing I was doing something wrong or goofy when trying to joint things together.

Let me have a few more attempts, and if I'm still stumbling I'll post some code or a demonstration.

edit: Rereading, I believe I said the bridge demo rotates around the midpoints. I haven't done much physics in awhile, so my understanding of how this works and how Chipmunk does its thing is likely quite off. I meant to say that my simulation would have pins where two beams meet. I think the bridge demo does what I want (or very close to it). Let me fiddle some more and return.
pokeyman
Posts: 6
Joined: Wed May 13, 2009 4:08 am
Contact:

Re: Bridges

Post by pokeyman »

I've drawn this glorious diagram to illustrate what's happening and what I want to happen. The red dot is the pivot point.
Glorious Diagram.png
In "obtained", the pivot point is the midpoint between the two centres of gravity. In "desired", the pivot point is a pin through the endpoints of the two beams.

I want the two beams to be attached by the endpoints, not by their centres. Does this make sense?
pokeyman
Posts: 6
Joined: Wed May 13, 2009 4:08 am
Contact:

Re: Bridges

Post by pokeyman »

Sorry to triple post, but here's a video of an old game that's very similar to what I'm trying to do. See how the bridge reacts under the train's mass moving across it? I'm trying to figure out how to achieve a similar effect. Any ideas are quite welcome!

http://www.youtube.com/watch?v=r4qXl2736YU
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Bridges

Post by slembcke »

Can you post the code where you are specifying the shape and joint? I'm guessing that you are doing one or the other incorrectly, but it's hard to say anything more without seeing the code.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
pokeyman
Posts: 6
Joined: Wed May 13, 2009 4:08 am
Contact:

Re: Bridges

Post by pokeyman »

Sure! Here I'm using very tiny pin joints; other types of joints have similar or less helpful effects. Segments are 50 units wide.

Code: Select all

    staticBody = cpBodyNew(INFINITY, INFINITY);
    staticBody->p = cpv(0, 0);
	
    cpResetShapeIdCounter();
    space = cpSpaceNew();
    space->iterations = 10;
    space->gravity = cpv(0, -300);

    BridgeSegment *seg1 = [[BridgeSegment alloc] initWithSpace:space a:cpv(50, 160) b:cpv(100, 160)];
    BridgeSegment *seg2 = [[BridgeSegment alloc] initWithSpace:space a:cpv(100, 160) b:cpv(150, 160)];
    
    cpJoint *joint;
    
    joint = cpPinJointNew(staticBody, seg1.shape->body, cpv(25, 160), cpv(-25, 0));
    cpSpaceAddJoint(space, joint);
    
    joint = cpPinJointNew(seg1.shape->body, seg2.shape->body, cpv(25, 0), cpv(-25, 0));
    cpSpaceAddJoint(space, joint);
And here's the Chipmunk code in [BridgeSegment initWithSpace:a:b:].

Code: Select all

        cpVect center = cpvmult(cpvadd(a, b), 0.5);
        
        // verts is an instance variable; assuming horizontal bridge segments here, which is fine for testing.
        verts = malloc(sizeof(cpVect) * 4);
        verts[0] = cpv(-25, -1);
        verts[1] = cpv(-25, 1);
        verts[2] = cpv(25, 1);
        verts[3] = cpv(25, -1);
        
        cpBody *body = cpBodyNew(1.0, cpMomentForPoly(1.0, 4, verts, cpv(0, 0)));
        body->p = center;
        cpSpaceAddBody(space, body);
        
        // shape is an instance variable, and is used to retrieve the body for joints.
        shape = cpPolyShapeNew(body, 4, verts, cpv(0, 0));
        shape->e = 1.0;
        shape->u = 0.0;
        shape->group = 1;
        cpSpaceAddShape(space, shape);
Post Reply

Who is online

Users browsing this forum: No registered users and 14 guests