在我简单的 Python 物理引擎中模拟摩擦
Modeling friction in my simple Python physics engine
我在 Python 的简单物理引擎中模拟了摩擦,但这不是最好的。我的问题是,物体在一定速度下会受到摩擦并减速并停止,但在停止后它会不断来回振动。我认为问题是因为速度没有像在现实生活中那样平稳地下降,它随着摩擦力引起的加速度的增加而递减。
在尝试制作这个简单的物理引擎时,我 运行 遇到了两个问题,第一个是边界问题,第二个是摩擦问题。我可以解决这些但我的解决方案不是很好,它们很草率,我的解决方案有点像数值解决方案(它是近似的)但你的解决方案就像解析解决方案(它们是完美的)我如何防止这种情况?
这是代码。
import pygame as pyg
# from math import *
pyg.init()
win = pyg.display.set_mode((1500, 900))
pyg.display.set_caption('physics engine')
mainloop = True
jump = False
class Objects:
def __init__(self, x, y, vel_x, vel_y, acc_x, acc_y, mass):
self.x = x
self.y = y
self.vel_x = vel_x
self.vel_y = vel_y
self.acc_x = acc_x
self.acc_y = acc_y
self.mass = mass
circ = Objects(400, 750, 0, 0, 0, 0, 100)
rect = Objects(0, 890, 0, 0, 0, 0, 100)
F_x = 1250
F_y = 1750
coeff_fric = 0.3
friction_x = 0
friction_y = 0
g = 9.8
while mainloop:
pyg.time.delay(50)
for event in pyg.event.get():
if event.type == pyg.QUIT:
mainloop = False
keys = pyg.key.get_pressed()
if keys[pyg.K_LEFT]:
circ.acc_x = -1 * F_x / circ.mass
if keys[pyg.K_RIGHT]:
circ.acc_x = F_x / circ.mass
if keys[pyg.K_UP]:
circ.acc_y = -1 * F_y / circ.mass
if keys[pyg.K_DOWN]:
circ.acc_y = F_y / circ.mass
if keys[pyg.K_SPACE]:
circ.vel_y = 0
circ.vel_x = 0
circ.vel_y += g
circ.vel_x += circ.acc_x
circ.vel_x += circ.acc_x
circ.vel_y += circ.acc_y
circ.vel_y += circ.acc_y
win.fill((0, 0, 0))
circ.x += circ.vel_x
circ.y += circ.vel_y
if circ.x < 50 or circ.x > 1450:
circ.x = max(50, min(1450, circ.x))
circ.vel_x = 0
if circ.y < 50 or circ.y > 840:
circ.y = max(50, min(840, circ.y))
circ.vel_y = 0
F_x = 1250
F_y = 1750
circ.acc_x = 0
circ.acc_y = 0
friction_x = coeff_fric * circ.mass * g
friction_y = coeff_fric * circ.mass * g
fric_force_x = F_x - friction_x
fric_force_y = F_y - friction_y
if circ.y >= 840:
if circ.acc_x == 0:
if round(circ.vel_x) == 0:
circ.vel_x = 0
if round(circ.vel_x) > 0:
circ.acc_x = -1 * friction_x / circ.mass
circ.vel_x += circ.acc_x
if circ.vel_x < 0:
circ.vel_x = 0
circ.acc_x = 0
if round(circ.vel_x) < 0:
circ.acc_x = friction_x / circ.mass
circ.vel_x += circ.acc_x
if circ.vel_x > 0:
circ.vel_x = 0
circ.acc_x = 0
print(circ.vel_x)
objct = pyg.draw.circle(win, (50, 50, 255), (round(circ.x), round(circ.y)), 50)
floor = pyg.draw.rect(win, (150, 75, 0), (rect.x, rect.y, 1500, 10))
pyg.display.update()
pyg.quit()
看来你加倍了加速度。一旦我取出额外的添加,抖动就停止了。
circ.vel_x += circ.acc_x
#circ.vel_x += circ.acc_x
circ.vel_y += circ.acc_y
#circ.vel_y += circ.acc_y
我在 Python 的简单物理引擎中模拟了摩擦,但这不是最好的。我的问题是,物体在一定速度下会受到摩擦并减速并停止,但在停止后它会不断来回振动。我认为问题是因为速度没有像在现实生活中那样平稳地下降,它随着摩擦力引起的加速度的增加而递减。
在尝试制作这个简单的物理引擎时,我 运行 遇到了两个问题,第一个是边界问题,第二个是摩擦问题。我可以解决这些但我的解决方案不是很好,它们很草率,我的解决方案有点像数值解决方案(它是近似的)但你的解决方案就像解析解决方案(它们是完美的)我如何防止这种情况?
这是代码。
import pygame as pyg
# from math import *
pyg.init()
win = pyg.display.set_mode((1500, 900))
pyg.display.set_caption('physics engine')
mainloop = True
jump = False
class Objects:
def __init__(self, x, y, vel_x, vel_y, acc_x, acc_y, mass):
self.x = x
self.y = y
self.vel_x = vel_x
self.vel_y = vel_y
self.acc_x = acc_x
self.acc_y = acc_y
self.mass = mass
circ = Objects(400, 750, 0, 0, 0, 0, 100)
rect = Objects(0, 890, 0, 0, 0, 0, 100)
F_x = 1250
F_y = 1750
coeff_fric = 0.3
friction_x = 0
friction_y = 0
g = 9.8
while mainloop:
pyg.time.delay(50)
for event in pyg.event.get():
if event.type == pyg.QUIT:
mainloop = False
keys = pyg.key.get_pressed()
if keys[pyg.K_LEFT]:
circ.acc_x = -1 * F_x / circ.mass
if keys[pyg.K_RIGHT]:
circ.acc_x = F_x / circ.mass
if keys[pyg.K_UP]:
circ.acc_y = -1 * F_y / circ.mass
if keys[pyg.K_DOWN]:
circ.acc_y = F_y / circ.mass
if keys[pyg.K_SPACE]:
circ.vel_y = 0
circ.vel_x = 0
circ.vel_y += g
circ.vel_x += circ.acc_x
circ.vel_x += circ.acc_x
circ.vel_y += circ.acc_y
circ.vel_y += circ.acc_y
win.fill((0, 0, 0))
circ.x += circ.vel_x
circ.y += circ.vel_y
if circ.x < 50 or circ.x > 1450:
circ.x = max(50, min(1450, circ.x))
circ.vel_x = 0
if circ.y < 50 or circ.y > 840:
circ.y = max(50, min(840, circ.y))
circ.vel_y = 0
F_x = 1250
F_y = 1750
circ.acc_x = 0
circ.acc_y = 0
friction_x = coeff_fric * circ.mass * g
friction_y = coeff_fric * circ.mass * g
fric_force_x = F_x - friction_x
fric_force_y = F_y - friction_y
if circ.y >= 840:
if circ.acc_x == 0:
if round(circ.vel_x) == 0:
circ.vel_x = 0
if round(circ.vel_x) > 0:
circ.acc_x = -1 * friction_x / circ.mass
circ.vel_x += circ.acc_x
if circ.vel_x < 0:
circ.vel_x = 0
circ.acc_x = 0
if round(circ.vel_x) < 0:
circ.acc_x = friction_x / circ.mass
circ.vel_x += circ.acc_x
if circ.vel_x > 0:
circ.vel_x = 0
circ.acc_x = 0
print(circ.vel_x)
objct = pyg.draw.circle(win, (50, 50, 255), (round(circ.x), round(circ.y)), 50)
floor = pyg.draw.rect(win, (150, 75, 0), (rect.x, rect.y, 1500, 10))
pyg.display.update()
pyg.quit()
看来你加倍了加速度。一旦我取出额外的添加,抖动就停止了。
circ.vel_x += circ.acc_x
#circ.vel_x += circ.acc_x
circ.vel_y += circ.acc_y
#circ.vel_y += circ.acc_y