Мяч попадает в угол, где он будет отклоняться?

Мне нужно освежить мою тригонометрию и надеюсь, что вы можете помочь здесь с простой математической моделью. Вот моя модель до сих пор в прикрепленном изображении. Я знаю, что анимация кадра имеет другие проблемы, когда мяч движется очень быстро, но пока мне просто нужно вычислить ballDx и ballDy. Также возможно, что ballDx = 0 (только вертикальное движение), но когда мяч отклоняет ballDx, может получиться другое значение.

Двустороннее столкновение между шаром и краевым краем твердого неподвижного объекта

42 голоса | спросил Lumis 10 PMpSun, 10 Apr 2011 13:37:50 +040037Sunday 2011, 13:37:50

3 ответа


40

Примечание. Все следующие предполагают, что поверхность шара не имеет трения (поэтому он не начнет вращаться или отскочить по-другому, потому что это так).

В момент столкновения мяч будет касаться угла. Когда сплошные объекты сталкиваются, сила будет действовать вдоль так называемой поверхностной нормали, то есть перпендикулярно поверхности в точке столкновения.

Так как это шар, перпендикулярный поверхности, он направлен к центру шара. Итак, мы знаем направление силы, как насчет ее величины? Предполагая упругое столкновение (и что прямоугольник не может двигаться), мяч должен отскочить с той же скоростью, с которой он воздействовал.

Пусть (nDx, nDy) - скорость после столкновения, (oDx, oDy) скорость до столкновения, а (x, y) положение шара в точке столкновения. Предположим далее, что угол, с которым сталкивается шар, равен (0,0).

Выражая наши идеи как формулы, мы имеем:

(nDx, nDy) = (oDx, oDy) + c * (x, y)
length (nDx, nDy) = length (oDx, oDy)

Что эквивалентно:

nDx = oDx + c * x
nDy = oDy + c * y
nDx^2 + nDy^2 = oDx^2 + oDy^2

Подставляя первые два уравнения в последнее, получим:

(oDx + c * x)^2 + (oDy + c * y)^2 = oDx^2 + oDy^2

Расширение с помощью биномиального торема

(a+b)^2 = a^2 + 2ab + b^2 

дает:

oDx^2 + 2 * oDx * c * x + (c * x) ^ 2 + oDy^2 + 2 * oDy * c * y + (c * y) ^ 2 = oDx^2 + oDy^2
2 * oDx * c * x + 2 * oDy * c * y + (c * x) ^ 2 + (c * y) ^ 2 = 0
(2 * oDx * x + 2 * oDy * y) * c + (x^2 + y^2) * c^2 = 0

Это квадратичное уравнение для c имеет два решения, один из которых равен 0. Очевидно, что это не то решение, которое нас интересует, так как обычно направление шара будет меняться в результате столкновение. Чтобы получить другое решение, мы разделим обе стороны на с и получим:

(2 * oDx * x + 2 * oDy * y) + (x^2 + y^2) * c = 0

То есть:

 c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)

Подводя итог, мы имеем:

c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
nDx = oDx + c * x
nDy = oDy + c * y

Изменить : в коде:

if (collision) {
    float x = ballX - cornerX;
    float y = ballY - cornerY;
    float c = -2 * (ballDx * x + ballDy * y) / (x * x + y * y);
    ballDx = ballDx + c * x;
    ballDy = ballDy + c * y;
}

Несколько соображений по реализации. Хотя вы можете приблизить (x, y) позицию шара после этапа моделирования, это приближение изменит угол отклонения и, следовательно, станет очень заметным, поэтому ваши шаги моделирования должны быть очень хорошими ( возможно, таким образом, чтобы мяч не двигался более чем на 1/20 его диаметра на шаг). Для более точного решения вы можете вычислить время столкновения и разделить этот шаг моделирования в это время, т. Е. Сделать частичный шаг до точки столкновения и еще один частичный шаг для остальной части шага.

Редактировать 2: Вычислить точку удара

Пусть r - радиус, (x0, y0) - положение и (dx, dy) - скорость шара в начале шага моделирования. Для простоты предположим далее, что данный угол находится в (0,0).

Мы знаем:

(x,y) = (x0, y0) + (dx, dy) * t

Мы хотим

length(x,y) = r

Это

(x0 + dx * t) ^ 2 + (y0 + dy * t) ^ 2 = r^2
x0^2 + 2 * x0 * dx * t + dx^2 * t^2 + y0^2 + 2 * y0 * dy * t + dy^2 * t^2 = r ^ 2
(dx^2 + dy^2) * t^2 + (2 * x0 * dx + 2 * y0 * dy) * t + (x0^2 + y0^2 - r^2) = 0
\____  _____/         \____________  ___________/       \_______  ________/
     \/                            \/                           \/
     a                             b                            c

Это квадратичное уравнение в t. Если его дискриминант

D = b^2 - 4 * a * c

отрицательный, у него нет решений, т. е. мяч никогда не ударит в угол по текущему курсу. В противном случае его два решения даются выражением

t1 = (-b - sqrt(D)) / (2 * a)
t2 = (-b + sqrt(D)) / (2 * a)

Нас интересует время начала столкновения, которое является более ранним временем t1.

Ваш метод станет следующим:

    // compute a,b,c and D as given above

    if (D >= 0) {
        t = (-b - sqrt(D)) / (2 * a);
        if (0 < t && t <= ts) {
            // collision during this timestep!

            x = x + t * dx;
            y = y + t * dy;
            ts = ts - t;

            // change dx and dy using the deflection formula 
        }
    }

    x = x + ts * dx;
    y = y + ts * dy;
ответил meriton 10 PMpSun, 10 Apr 2011 17:24:53 +040024Sunday 2011, 17:24:53
12

Вот визуальный способ поиска проблемы.

Исходным заданием является круг или прямоугольник (серый на изображении ниже). Это эквивалентно точке vs. rounded rect (показано черным).

Итак, это проблема с несколькими частями. Вы проверяете свое точечное столкновение против 4 линий (выдавливается из края коробки радиусом исходного круга) и 4 круга (в углах прямоугольника с тем же радиусом исходного круга).

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

введите описание изображения здесь>> </p>

<p> Я оставлю вывод этого как упражнение для читателя. </p></body></html>

ответил Tetrad 10 PMpSun, 10 Apr 2011 21:38:50 +040038Sunday 2011, 21:38:50
1

Я работаю над игрой, а также застрял здесь. Но я думаю, что так:

//Изображение в следующем комментарии

Есть другое представление Моя проблема в том, что я не знаю, как быстро вычислить новый dx, dy (для меня с использованием традиционной математики требуется слишком много вычислений).

ответил Risa 10 PMpSun, 10 Apr 2011 14:16:08 +040016Sunday 2011, 14:16:08

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132