Задача физики мяча Python - PullRequest
4 голосов
/ 10 июня 2011

Я пытаюсь правильно отскочить от мяча внутри коробки, особенно обращаясь с углами под определенными углами и обращая внимание на угол. У меня проблема, потому что мой мяч продолжает выходить из коробки. У меня есть эта функция, которая сообщает, находится ли мой мяч вне коробки, и обрабатывает ли он углы и стены. Код такой:

    if ((self._x > self._Grid.getWidth()) or (self._x < 0)):
        print("RandomNode:outside paramaters: x! self._x = %s , self._velx = %s" % (self._x , self._velx))
    if ((self._y > self._Grid.getLength())  or (self._y < 0)):
        print("RandomNode:outside paramaters: y!")
    if ((self._velx + self._x) > self._Grid.getWidth()):
        diff = self._Grid.getWidth()-self._x
        self._velx *= -1
        if (diff == 0):
            self._x -= self._velx
        else:
            self._x+= diff
        tampered = True
        #print("eqn1: self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

    if (self._velx + self._x < 0):
        diff = self._x
        self._velx *= -1
        if (diff == 0):
            self._x += self._velx
        else:
            self._x-= diff
        tampered = True
        #print("eqn2: self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))


    if ((self._vely + self._y) > self._Grid.getLength()):
        diff = self._Grid.getLength()-self._y
        self._vely *= -1
        if (diff == 0):
            self._y -= self._vely
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn31:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx - diff)
                    self._y += self._vely
                    #print("eqn32:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn33:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))


        else:
            self._y+= diff
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn31:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx - diff)
                    self._y += self._vely
                    #print("eqn32:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn33:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

    if (self._vely + self._y < 0):
        diff = self._y
        self._vely *= -1
        if (diff == 0):
            self._y += self._vely
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn41:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx + diff)
                    self._y += self._vely
                    #print("eqn42:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn43:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))

        else:
            self._y-= diff
            if (tampered == True):
                if ((self._velx * -1 == self._vely) or (self._velx == self._vely)):
                    self._x += self._velx
                    self._y += self._vely
                    #print("eqn41:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
                else:
                    self._x += (self._velx + diff)
                    self._y += self._vely
                    #print("eqn42:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
            else:
                tampered = True
                #print("eqn43:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely))
    return tampered

Я не знаю, почему это не работает. х и у, очевидно, являются его координатами. Velx и Vely - его скорости x и y. Tampered - это логическое значение, которое не позволяет мячу нормально двигаться и перемещается только при проверке.

Вот мой вопрос. Что не так с этим кодом? ИЛИ .... есть ли шаблон, написанный на python где-нибудь в сети или где-либо еще, или код, который вы использовали, который делает именно то, что я пытаюсь обработать и сделать? Пожалуйста, измените код по желанию, просто дайте мне знать. Любые ссылки на это уже решены, было бы здорово. Спасибо.

Ответы [ 2 ]

7 голосов
/ 10 июня 2011

Перепишите этот код.Это слишком сложно для простой проблемы, которую вы пытаетесь решить.

Сначала , двумерное движение шара - это всего лишь 2 одномерные задачи.Вы можете полностью разделить X и Y. Например, удар по углу полностью эквивалентен удару стены по оси X + удар по стене по оси Y.Удар по стене в X просто меняет скорость X (и, возможно, теряет некоторую энергию, если вы хотите смоделировать это).Удар по стене в Y меняет скорость на Y.

Секунда , поскольку обработка X и Y очень похожа, извлеките из нее метод

def handle_axis_movement(location, velocity):
    "returns updated location and velocity"
    ...

self.x, self.vel_x = handle_axis_movement(self.x, self.vel_x)
self.y, self.vel_y = handle_axis_movement(self.y, self.vel_y)

сократит количество кода (и ошибок) пополам.

Третий , вам не нужно обрабатывать diff == 0 и diff <0 отдельно.Оба случая означают, что мяч попал в стену и должен изменить свою скорость.Затем вы должны исправить местоположение, чтобы учесть тот факт, что оно не могло пройти через стену. </p>

location += velocity
if location > max_bound:
    location = max_bound - (location - max_bound)
    velocity *= -1
if location < min_bound:
    location = min_bound - (location - min_bound)
    velocity *= -1       
1 голос
/ 10 июня 2011

Вы не должны заново изобретать это колесо, когда pymunk делает это для вас так хорошо.;)

...