传送带运动学python
我正在尝试为带有对象的传送带创建一个模拟,以了解行为的方式。我正在玩耍,但在传送带的功能上挣扎。目前,我尝试在物体与皮带发生碰撞时将冲动或速度添加到这些物体时,但我还没有得到很好的效果。但是,这只是我尝试如何将脉冲脉冲给对象的一个示例,但是,每当我添加一个新对象(使用鼠标事件)时,新的脉冲仅适用于最新对象。
import pygame
import pymunk
import pymunk.pygame_util
import math
import sys
pygame.init()
space = pymunk.Space()
WIDTH, HEIGHT = 1920,800
mu = 2
window = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Kinematics approximation ")
def calculate_distance(p1, p2):
return math.sqrt((p2[1] - p1[1])**2 + (p2[0] - p1[0])**2)
def calculate_angle(p1, p2):
return math.atan2(p2[1] - p1[1], p2[0] - p1[0])
def draw(space, window,draw_options):
window.fill("white")
space.debug_draw(draw_options)
pygame.display.update()
def create_belt(space):
belts = [
[(0,500), (600,500), 5],
[(600,500), (800,400), 6],
[(800,400), (WIDTH,400), 6]
]
for pos_1, pos_2, width in belts:
shape = pymunk.Segment(space.static_body,pos_1, pos_2, width)
shape.body.position = 0,0
shape.friction = mu
space.add(shape)
def create_object(space, mass, pos):
body = pymunk.Body(body_type = pymunk.Body.DYNAMIC)
body.position = pos
shape = pymunk.Poly.create_box(body, size = (20,10))
shape.mass = mass
shape.color = (255,0,0, 100)
shape.body.friction = mu
#shape.body.velocity = (80,0)
space.add(body,shape)
return shape
def run(window, width, height):
run = True
clock = pygame.time.Clock()
fps = 240
dt = 1/fps
space = pymunk.Space()
space.gravity = (0,981)
create_belt(space)
def coll_begin(arbiter, space, data):
print(arbiter)
#angle = calculate_angle(*)
#force = calculate_distance(*line) * 50
#fx = math.cos(angle) * force
#fy = math.sin(angle) * force
return True
def coll_pre(arbiter, space, data):
for object in objects:
object.body.apply_impulse_at_local_point((12, 0),(0,0))
return True
def coll_post(arbiter, space, data):
#print(velocity_at_local_point)
pass
def coll_separate(arbiter, space, data):
pass
handler = space.add_default_collision_handler()
handler.begin = coll_begin
handler.pre_solve = coll_pre
handler.post_solve = coll_post
handler.separate = coll_separate
draw_options = pymunk.pygame_util.DrawOptions(window)
pressed_pos = None
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
pressed_pos = pygame.mouse.get_pos()
objects = []
objects.append(create_object(space,10, pressed_pos))
draw(space,window, draw_options)
space.step(dt)
clock.tick(fps)
pygame.quit()
sys.exit()
if __name__ == "__main__":
run(window, WIDTH, HEIGHT)
I'm trying to create a simulation for a conveyor belt with objects on it, to see how the behaviour would be. I am playing around but struggling with the functionality of the conveyor belt. Right now, I try to add impulse or velocity to the objects whenever they have a collision with the belt, but I have yet to get a good result. Here is just an example of how I tried to give impulse to the objects, however, whenever I add a new object (with mouse event), the new impulse only applies to the newest object.
import pygame
import pymunk
import pymunk.pygame_util
import math
import sys
pygame.init()
space = pymunk.Space()
WIDTH, HEIGHT = 1920,800
mu = 2
window = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Kinematics approximation ")
def calculate_distance(p1, p2):
return math.sqrt((p2[1] - p1[1])**2 + (p2[0] - p1[0])**2)
def calculate_angle(p1, p2):
return math.atan2(p2[1] - p1[1], p2[0] - p1[0])
def draw(space, window,draw_options):
window.fill("white")
space.debug_draw(draw_options)
pygame.display.update()
def create_belt(space):
belts = [
[(0,500), (600,500), 5],
[(600,500), (800,400), 6],
[(800,400), (WIDTH,400), 6]
]
for pos_1, pos_2, width in belts:
shape = pymunk.Segment(space.static_body,pos_1, pos_2, width)
shape.body.position = 0,0
shape.friction = mu
space.add(shape)
def create_object(space, mass, pos):
body = pymunk.Body(body_type = pymunk.Body.DYNAMIC)
body.position = pos
shape = pymunk.Poly.create_box(body, size = (20,10))
shape.mass = mass
shape.color = (255,0,0, 100)
shape.body.friction = mu
#shape.body.velocity = (80,0)
space.add(body,shape)
return shape
def run(window, width, height):
run = True
clock = pygame.time.Clock()
fps = 240
dt = 1/fps
space = pymunk.Space()
space.gravity = (0,981)
create_belt(space)
def coll_begin(arbiter, space, data):
print(arbiter)
#angle = calculate_angle(*)
#force = calculate_distance(*line) * 50
#fx = math.cos(angle) * force
#fy = math.sin(angle) * force
return True
def coll_pre(arbiter, space, data):
for object in objects:
object.body.apply_impulse_at_local_point((12, 0),(0,0))
return True
def coll_post(arbiter, space, data):
#print(velocity_at_local_point)
pass
def coll_separate(arbiter, space, data):
pass
handler = space.add_default_collision_handler()
handler.begin = coll_begin
handler.pre_solve = coll_pre
handler.post_solve = coll_post
handler.separate = coll_separate
draw_options = pymunk.pygame_util.DrawOptions(window)
pressed_pos = None
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
pressed_pos = pygame.mouse.get_pos()
objects = []
objects.append(create_object(space,10, pressed_pos))
draw(space,window, draw_options)
space.step(dt)
clock.tick(fps)
pygame.quit()
sys.exit()
if __name__ == "__main__":
run(window, WIDTH, HEIGHT)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
代码中有两个问题:
首先,每次创建新对象时,您都在重置对象列表。这意味着,当您将脉冲应用于对象列表中的所有对象时,仅将脉冲应用于创建的最后一个对象。通过将
Objects = []
行从游戏循环中移出,可以轻松修复这一点。修复此操作后,您可能已经注意到,无论是否触摸皮带,所有物体都会发生冲动。这是由以下内容引起的:每当任何物体与输送带碰撞时,您都会向所有物体应用脉冲。这会导致所有物体向前移动,而不仅仅是与传送带相撞的物体。
您可以使用
arbiter.shapes
元组来修复上述两个错误,该元素作为参数提供给coll_pre
函数的参数。该元组包含两个对方碰撞的对象,因此您要移动的对象。第二个对象是要移动的新对象。此更改还使对象
列表毫无用处,因为您不再使用它来应用脉冲。这是代码:
我还建议增加给出的冲动,因为现在这些物体慢慢传播以抵抗皮带倾斜部分的重力。 40的价值对我有用。
There are two problems in your code:
First, you are resetting the objects list every time a new object is created. This means that when you apply impulse to all objects in the objects list, only impulse is applied to the last object created. This can be easily fixed by moving the
objects = []
line out of the game loop.After fixing this, you might have noticed that all objects are getting impulse, whether they touch the belt or not. This is caused by the following: whenever any object is colliding with the conveyor belt, you apply an impulse to all objects. This causes all objects to move forward, not only the one that collides with the conveyor belt.
You can fix the two above errors using the
Arbiter.shapes
tuple that is provided as an argument to thecoll_pre
function. This tuple contains the two objects colliding with eachother, and thus also the object you want to move. The second object is the new object you want to move. This change also makes theobjects
list useless, as you don't use it anymore to apply the impulse.Here's the code:
I would also recommend increasing the impulse given, as now the objects travel to slowly to resist to gravity on the inclined part of the belt. A value of 40 worked for me.