如何在 Pymunk 中获取接触力?

How to get contact forces in Pymunk?

我在使用 Pymunk 时遇到了一些问题。考虑以下场景,其中已经创建了一个球和一个表面并且正在接触:

import pymunk
# Create space
space = pymunk.Space()
space.gravity = (0, 900)

# Create the surface
surface_body = pymunk.Body(body_type=pymunk.Body.STATIC)
surface_body.position = (400, 600)
surface_shape = pymunk.Segment(surface_body, (-400, 0), (400, 0), 3)
space.add(surface_body, surface_shape)

# Create ball
ball_body = pymunk.Body()
ball_body.position = (400, 550)
ball_shape = pymunk.Circle(ball_body, 40)
ball_shape.mass = 1
ball_shape.friction = 0
space.add(surface_body, surface_shape)

# Run the simulation a few times in order to get contact between ball and surface
for i in range(50):
    space.step(1/60)

如果我 运行 shapes_collide,我知道存在一个联系点:

print(ball_shape.shapes_collide(surface_shape))
> ContactPointSet(normal=Vec2d(0.0, 1.0), points=[ContactPoint(point_a=Vec2d(400.0, 597.5), point_b=Vec2d(400.0, 597.0), distance=-0.5)])

问题是:有没有一种方法可以使用 Pymunk 来获取表面施加在球上的力?在这种情况下,它应该在接触点应用类似 Vec2D(0, -900) 的东西,但我需要一个类似的功能,用于某些更复杂的情况......

我尝试搜索文档但找不到任何东西(也许解决方案从我身边溜走了)。感谢任何帮助。

谢谢!

您或许可以使用 Arbiter 上的 total_ke 或 total_impulse 来获得您想要的。这两个属性记录在此处:http://www.pymunk.org/en/latest/pymunk.html#pymunk.Arbiter.total_impulse

您可以使用 post-solve 碰撞回调从仲裁器中读取它,或者您通过在您感兴趣的物体上调用 each_arbiter 来“手动”执行。脉冲 * dt 为 900 .

def f(arb):
    print(f"ke: {arb.total_ke}, impulse: {arb.total_impulse}")

ball_body.each_arbiter(e)

# will print ke: 225.0, impulse: Vec2d(-0.0, -15.0)