在我的简单Python物理引擎中建模摩擦

时间:2020-08-02 07:48:38

标签: python python-3.x 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()

1 个答案:

答案 0 :(得分:1)

好像您要加倍加速。一旦我取出多余的添加,抖动就停止了。

circ.vel_x += circ.acc_x
#circ.vel_x += circ.acc_x
circ.vel_y += circ.acc_y
#circ.vel_y += circ.acc_y