Моделирование трения в моем простом физическом движке Python - PullRequest
0 голосов
/ 02 августа 2020

Я смоделировал трение в моем простом физическом движке в 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 Ответ

1 голос
/ 02 августа 2020

Похоже, вы вдвое прибавляете ускорение. Как только я убрал лишнее, дрожание прекратилось.

circ.vel_x += circ.acc_x
#circ.vel_x += circ.acc_x
circ.vel_y += circ.acc_y
#circ.vel_y += circ.acc_y
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...