2013-04-03 2 views
1

У меня возникли проблемы с кругом для разрешения столкновения круга.Разрешение столкновений между кругами - медленное скольжение

Во-первых, я обнаруживаю столкновение, то, если шары сталкиваются, я разделяю их на сумму их радиусов и устанавливаю скорости. Это легко.

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

Что такое hapning - это разрешение резолюции, гравитация толкает мяч и вызывает другое столкновение. Я пробовал разделять шар на сумму их радиусов + x, но он просто скользит немного быстрее.

Вы можете посмотреть видео по адресу http://www.youtube.com/watch?v=tk7qQ9KDFp0&feature=youtu.be.

А вот код, который hadles colision:

for p in world.particle_list: 

     if not p == self: 

      if self.pos.sub(p.pos).get_length() <= self.radius * ppm + p.radius * ppm: 

       p_mass_ratio = float(self.mass)/(self.mass + p.mass) 
       self_mass_ratio = float(p.mass)/(self.mass + p.mass) 

       rel_pos = p.pos.sub(self.pos) 
       shift = rel_pos.set_length(- rel_pos.get_length() + self.radius * ppm + p.radius * ppm) 
       p.pos = p.pos.add(shift.scale(0.50)) 
       self.pos = self.pos.add(shift.scale(-0.50)) 

       p_speed = p.speed 
       self_speed = self.speed 

       self.speed = p_speed.add(self.speed.norm_reflect(rel_pos.set_angle(rel_pos.get_angle() + 90).scale(-self.friction))).scale(0.50 * self_mass_ratio) 
       p.speed = self_speed.add(p.speed.norm_reflect(rel_pos.set_angle(rel_pos.get_angle() + 90).scale(self.friction))).scale(0.50 * p_mass_ratio) 

Я сделал вектор класса справиться с этим:

def dcos(x): 

    return cos(radians(x)) 

def dsin(x): 

    return sin(radians(x)) 

def dtan(x): 

    return tan(radians(x)) 

class Vec(object): 

    def __init__(self, x, y): 

     self.x = float(x) 
     self.y = float(y) 

     self.length = self.get_length() 
     self.angle = self.get_angle() 

    def get_length(self): 

     return sqrt(self.x ** 2 + self.y ** 2) 

    def get_angle(self): 

     return atan2(self.y, self.x) * 180/pi 

    def add(self, vec1): 

     new_x = self.x + vec1.x 
     new_y = self.y + vec1.y 

     return Vec(new_x, new_y) 

    def sub(self, vec1): 

     new_x = self.x - vec1.x 
     new_y = self.y - vec1.y 

     return Vec(new_x, new_y) 

    def scale(self, k): 

     return Vec(self.x * k, self.y * k) 

    def set_angle(self, a): 

     new_x = self.length * dcos(a) 
     new_y = self.length * dsin(a) 

     if a == -90 or a == 90: 

      new_x = 0 

     if a == 180 or a == 0 or a == -180: 

      new_y = 0 

     return Vec(new_x, new_y) 

    def set_length(self, l): 

     new_x = l * dcos(self.angle) 
     new_y = l * dsin(self.angle) 

     return Vec(new_x, new_y) 

    def inverse(self): 

     return Vec(- self.x, - self.y) 


    def norm_reflect(self, vec1): 

     if self.get_angle == vec1.get_angle(): 

      return Vec(self.x, self.y) 

     if vec1.get_angle() >= 0: 

      return self.set_angle(vec1.get_angle() - self.get_angle() + 90) 

    else: 

     return self.set_angle(vec1.get_angle() - self.get_angle() - 90) 
+0

Является ли законным устанавливать длину отрицательного значения? Отражает ли направление вектора? – Beta

+0

Да, метод set_length() изменит направление, если аргумент отрицательный. – alexpinho98

ответ

0

(я не знаю, питона, но я знаю физику и вы Арен «т получать другие ответы, так что я возьму трещину в этом.)

Посмотрите на

if self.pos.sub(p.pos).get_length() <= self.radius * ppm + p.radius * ppm: 
    ... 
    rel_pos = p.pos.sub(self.pos) 
    shift = rel_pos.set_length(- rel_pos.get_length() + self.radius * ppm + p.radius * ppm) 
    p.pos = p.pos.add(shift.scale(0.50)) 
    self.pos = self.pos.add(shift.scale(-0.50)) 

Вы устанавливаете длину на отрицательное число, поэтому вы перемещаете объекты в сторону друг друга.

Функция norm_reflect() не имеет большого смысла, и я подозреваю, что она делает что-то другое, чем то, что вы намерены (в этом случае вы не тестируете свой код).

Эти две линии:

self.speed = p_speed.add(self.speed.norm_reflect(rel_pos.set_angle(rel_pos.get_angle() + 90).scale(-self.friction))).scale(0.50 * self_mass_ratio) 
p.speed = self_speed.add(p.speed.norm_reflect(rel_pos.set_angle(rel_pos.get_angle() + 90).scale(self.friction))).scale(0.50 * p_mass_ratio) 

, кажется, вызывая norm_reflect() только с одним аргументом, и вы чего трение и массовых соотношений в картину до простого случая работает, и вас Повторное использование rel_pos после нескольких преобразований, и Физика является неньютоновской (т. е. недостаточно для того, чтобы начать с чистого листа).

+0

Во-первых, как вы можете видеть в видео на YouTube, я не перемещаю шары друг к другу, во-вторых, если вы считаете, что функция norm_reflect неверна, пожалуйста, сообщите, как это неправильно и в-третьих, каждый метод моего векторного класса возвращает другой метод, поэтому я не использую преобразованные векторы. – alexpinho98

+0

Возвращает другой векторный класс, а не метод. – alexpinho98

+0

1) Попробуйте вещи 'shift' в изоляции, если вы мне не верите, не полагайтесь на видео, в котором * происходит много других вещей *. 2) Что вы намерены выполнять 'norm_reflect()'? Отразить один вектор по другому? Что вы ожидаете, если оба аргумента совпадают? 3) Считаете ли вы, что 'rel_pos' не изменяется по строке' self.speed = ... '? – Beta

Смежные вопросы