Coordinate system confusion with apply_impulse()

Official forum for the Chipmunk2D Physics Library.
Post Reply
dwelch91
Posts: 2
Joined: Thu Mar 06, 2014 10:11 pm
Contact:

Coordinate system confusion with apply_impulse()

Post by dwelch91 »

I have searched throughout this forum for an answer to this, but am confused with the topics that address this. I'm using Pymunk and have a rectangular shape (with "nose cone") with these initial vertices:

Code: Select all

vertices = [(CX, CY), (CX, CY+50), (CX+100, CY+50), (CX+125, CY+25), (CX+100, CY)]
where CX and CY are the center of my window.
I'd like to have an impulse act on the vertex at (CX, CY+50) or the "rear driver's side corner". So, I've setup an impulse:

Code: Select all

 | 500
 |
\ /
+------------------------+
|                          \
|                           +
|                          /
+------------------------+
I expect this impulse force to move the body down, but also rotate the body counter-clockwise as well.

Code: Select all

angle = ship.body.angle
v = Vec2d(0, -500).rotated(angle)
I think this part is correct. The trouble comes with the offset position. I've tried every combination of things I can think of they all seem to not work as expected (shape is pushed in incorrect directions). Some of what I've tried:

Code: Select all

# (1)
p = Vec2d(-50, 25)
ship.body.apply_impulse(v, p)

Code: Select all

# (2)
p = Vec2d(-50, 25).rotated(angle)
ship.body.apply_impulse(v, p)

Code: Select all

# (3)
p = ship.body.local_to_world(Vec2d(-50, 25).rotated(angle))
ship.body.apply_impulse(v, p)

Code: Select all

# (4)
p = ship.body.local_to_world(Vec2d(-50, 25)).rotated(angle)
ship.body.apply_impulse(v, p)

Code: Select all

# (5)
px = shape.body.position.x
py = shape.body.position.y
p = ship.body.local_to_world(Vec2d(px-50, py+25)).rotated(angle)
ship.body.apply_impulse(v, p)
From my understanding of viewtopic.php?f=1&t=59&hilit=coordinate+local+world, #4 seems like the correct way to go, but I get very strange results with it just like the others.

Thanks for the help!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Coordinate system confusion with apply_impulse()

Post by slembcke »

So this is sort of a weird function, and it confuses a lot of people. I'm changing the way it works in Chipmunk 7 to help fix that.

Here's how it works. It's an offset from the center of gravity in world coordinates. So the impulse is applied to the body at (body.position + offset) in world coordinates. The impulse itself is also in world coordinates.

Also keep in mind that the shape's vertex coordinates are specified in body local coordinates where (0, 0) is the center of gravity of the body. Passing window coordinates into that is probably not what you want. You probably want to set the body's position to the center of the window and then make your shape's vertexes centered around (0, 0).
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
dwelch91
Posts: 2
Joined: Thu Mar 06, 2014 10:11 pm
Contact:

Re: Coordinate system confusion with apply_impulse()

Post by dwelch91 »

Thanks for the assistance. Your comment about the vertices was the main issue, I was doing that completely wrong. For the impulse, I ended up with something like:

Code: Select all

ship.body.apply_impulse(Vec2d(0, -ROTATE_THRUST).rotated(angle), Vec2d(-50, 25).rotated(angle))
which seems to work properly, but somehow doesn't capture the idea of "world coordinates" unless you mean that the engine applies them that way internally? I tried converting these to world coordinates using local_to_world() and that makes things go haywire.
Post Reply

Who is online

Users browsing this forum: No registered users and 22 guests