Speedup Pymunk 碰撞处理

问题描述 投票:0回答:0

我想用 Python Arcade 和 Pymunk 实现粒子模拟。虽然 Arcade 即使在绘图/处理方面也非常快,例如。 10000 个粒子与 Pymunk 的碰撞处理变得非常慢。我假设 Pymunk 正在检查每个可能的粒子对是否发生碰撞。

在粒子碰撞模拟中,窗口上通常有一个网格,粒子碰撞只检查相邻网格单元中的粒子。这要快得多。

编辑:到目前为止,这是我的代码:

import arcade
import pymunk
import random

SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 800
PARTICLE_COUNT = 3000
PARTICLE_RADIUS = 4
GRAVITY = (0, -981)

class Particle:
    def __init__(self, space, position, velocity, weight):
        self.body = pymunk.Body()
        self.body.position = position
        self.body.velocity = velocity
        self.shape = pymunk.Circle(self.body, radius=PARTICLE_RADIUS)
        self.shape.density = weight
        self.shape.elasticity = 0.8
        self.color = arcade.color.WHITE
        if weight > 1:
            self.color = arcade.color.RED
        elif weight < 1:
            self.color = arcade.color.BLUE      
        space.add(self.body, self.shape)

    def draw(self):
        x, y = self.body.position
        arcade.draw_circle_filled(x, y, PARTICLE_RADIUS, self.color)

class Simulation(arcade.Window):
    def __init__(self, width, height):
        super().__init__(width, height, "Particle Simulation")
        arcade.set_background_color(arcade.color.BLACK)

        self.space = pymunk.Space()
        self.space.gravity = GRAVITY
        
        wThick = 50
        dv     = 49
        walls = [
            pymunk.Segment(self.space.static_body, (-dv, 0), (-dv, height), wThick),
            pymunk.Segment(self.space.static_body, (0, height+dv), (width, height+dv), wThick),
            pymunk.Segment(self.space.static_body, (width+dv, height), (width+dv, 0), wThick),
            pymunk.Segment(self.space.static_body, (0, 0-dv), (width, 0-dv), wThick)
        ]
        for wall in walls:
            wall.elasticity = 1
            wall.friction = 0.5
            wall.color = arcade.color.RED
        self.space.add(*walls)

        walls = [
            pymunk.Segment(self.space.static_body, (0,height//2-dv), (width//2, 0-dv), wThick),
        ]
        for wall in walls:
            wall.elasticity = 1
            wall.friction = 1
            wall.color = arcade.color.RED
        self.space.add(*walls)

        self.particles = []
        for i in range(PARTICLE_COUNT):
            position = random.uniform(PARTICLE_RADIUS, width//2 - PARTICLE_RADIUS), \
                       random.uniform(height//2+PARTICLE_RADIUS, height - PARTICLE_RADIUS)
            velocity = random.uniform(-200, 200), random.uniform(-200, 200)
            weight = random.uniform(0.1, 2)
            self.particles.append(Particle(self.space, position, velocity, weight))

    def on_draw(self):
        arcade.start_render()
        for particle in self.particles:
            particle.draw()
        # Draw the FPS counter in the bottom-left corner of the window
        fps = arcade.get_fps()
        fps_text = "FPS: %.2f" % (fps)
        arcade.draw_text(fps_text, 10, 10, arcade.color.WHITE, 14)            

    def on_update(self, delta_time):
        self.space.step(1/120)
        

def main():
    sim = Simulation(SCREEN_WIDTH, SCREEN_HEIGHT)
    arcade.enable_timings()
    arcade.run()

if __name__ == '__main__':
    main()

用Pymunk可以实现吗?

performance collision-detection pymunk
© www.soinside.com 2019 - 2024. All rights reserved.