Я тот, кто написал исходный код возврата мяча, на который вы ссылались. Если вы скачаете и попробуете этот код, вы увидите, что он работает нормально.
Следующий код правильный (как у вас изначально):
// collision impulse
float i = (-(1.0f + RESTITUTION_CONSTANT) * vn) / (im1 + im2);
CGPoint impulse = ccpMult(mtd, i);
Это очень распространенный физический код, и вы можете увидеть, что он почти точно реализован следующим образом:
Это правильно, и это не создает CoR более 1.0, как предлагали другие. Это вычисление относительного вектора импульса на основе массы и коэффициента реституции.
Игнорируя трение, простой 1d пример выглядит следующим образом:
J = -Vr(1+e) / {1/m1 + 1/m2}
Где e - ваш CoR, Vr - нормализованная скорость, а J - скалярное значение импульсной скорости.
Если вы планируете делать что-то более сложное, чем это, я предлагаю вам использовать одну из множества уже имеющихся библиотек физики. Когда я использовал приведенный выше код, он был хорош для нескольких шаров, но когда я увеличил его до нескольких сотен, он начал задыхаться. Я использовал физический движок Box2D, и его решатель мог обрабатывать больше шаров, и он намного точнее.
В любом случае, я просмотрел ваш код, и на первый взгляд он выглядит хорошо (это довольно точный перевод). Вероятно, это небольшая и неуловимая ошибка передачи неправильного значения или проблема векторной математики.
Я не знаю ничего, касающегося разработки iPhone, но я бы предложил установить точку останова в верхней части этого метода и отслеживать итоговое значение каждого шага и определять, где происходит взрыв. Убедитесь, что MTD рассчитан правильно, скорости удара и т. Д., И т. Д., Пока вы не увидите, где вводится большое увеличение.
Сообщите значения каждого шага в этом методе, и мы увидим, что у нас есть.