Куля потрапляє в кут, куди вона відхилиться?


46

Мені потрібно підкреслити свою тригонометрію і сподіваюся, що ви можете допомогти тут простою математичною моделлю. Ось моя модель поки що на зображенні, що додається. Я знаю, що в анімації кадрів є інші проблеми, коли м'яч рухається дуже швидко, але поки що мені просто потрібно обчислити ballDx і ballDy. Можливо також, що ballDx = 0 (тільки вертикальний рух), але коли куля відхиляється ballDx може отримати інше значення.

2D зіткнення між кулькою та кутовим краєм суцільного непорушного предмета


22
Це те, що вони називають "кутовим випадком"?
Ендрю Грімм

2
Безумовно, як ідуть справи, незабаром ми можемо використати теорію відносності для її вирішення - проблема набуває маси (ive).
Луміс

Відповіді:


45

Примітка. Усі наведені нижче припущення передбачають, що поверхня м'яча не тертя (тому він не почне крутитися чи відскокувати інакше, тому що є).

У момент зіткнення м'яч буде торкатися кута. Коли тверді предмети стикаються, сила буде діяти уздовж так званої поверхні в нормі, тобто перпендикулярно поверхні в точці зіткнення.

Оскільки це кулька, перпендикулярна поверхні спрямована до центру кулі. Гаразд, ми знаємо напрямок сили, а як бути з її величиною? Припускаючи пружне зіткнення (і щоб прямокутник не міг рухатися), м'яч повинен відскочити з тією ж швидкістю, з якою він вплинув.

Нехай (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. Очевидно, що це не рішення, яке нас цікавить, оскільки загалом напрямок кулі зміниться в результаті зіткнення. Щоб отримати інше рішення, розділимо обидві сторони на c і ​​отримаємо:

(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;

1
це заслуговує +1
динамічний

1
Не соромтесь подати заявку, тоді :-)
меритон - страйкуйте

3
Ви говорите дуже рано, At the moment of collision, the ball will be touching the cornerале я не бачу виправдання цього наближення (і це повинно бути наближенням, оскільки це неправда - куля торкається в двох місцях, жодне з яких не є кутом).
Пітер Тейлор

1
@ Петер Тейлор: Ви помітили, що ОП витягнув кулю за межами прямокутника, і формула виявлення зіткнення, наведена у запитанні, передбачає і це? Ви повинні задуматися тут :-)
meriton - страйкуйте

1
Люблю цю відповідь, але вона могла використовувати деяку розмітку $ \ LaTeX $ математики.
Мартін Вікман

13

Ось візуальний спосіб розгляду проблеми.

Оригінальний набір задач - коло проти прямокутника (сірий на зображенні нижче). Це еквівалентно прямоточній та округлої прямої (показано чорним кольором).

Отже, це проблема багатоскладової. Ви випробовуєте точковий зіткнення проти 4 ліній (витиснених з краю коробки радіусом початкового кола) та 4 кіл (у кутах прямокутника з однаковим радіусом вихідного кола).

З приблизною швидкістю у вихідному зображенні точка потрапить у нижнє право кутове коло. Все, що вам потрібно зробити, - це розібрати точку на кутовому колі, в яку ви вдаритеся, обчислити кут цього і відбити його.

введіть тут опис зображення

Виявлення цього я залишу читачеві як вправу.


2

Я працюю над грою, а також застряг тут. Але я думаю, що йде так:

введіть тут опис зображення

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


Моя точка зору відрізняється від тієї, що знаходиться у 2-му посиланні, тому що я не думаю, що новий вектор швидкості залежить від такого центру блоку. Мій брат сказав мені, що м'яч відскочить у старий напрямок (dx = -dx && dy = - dy), але я не думаю, що так.
Різа

Якщо м'яч потрапив у кут, а відстань кутаX від кутаX менше 1/4 кулі, то вона відскочить назад, інакше відхилиться вперед праворуч. Це проста модель, якою я зараз користуюсь, яка не точно налаштована, щоб знайти точний кут.
Луміс

0

Кінематика полягає у виборі правильної, як у найбільш зручній для розрахунків, системі відліку.

Тут ми спочатку визначимо перетворення T, яке розв’язує наші осі на компоненти, паралельні ( x ' ) та перпендикулярні ( y' ) до лінії між центром кулі та кутом. Зворотне перетворення T * відновить нашу початкову систему координат.

У цій новій системі відліку за допомогою відображення (та часової та просторової симетрії фізики) ми маємо перетворення швидкості контакту M ( точковий імпульс ) як таке, яке перевертає x ' компонент і залишає незмінним y' компонент. У матричному відношенні це діагональна матриця з -1 і 1 на діагоналі.

Тоді швидкість після зіткнення проста: V ' = T * . M . T . Во .

Час удару т потім тільки розчин для ( T . Do ) + ( Х . Т . По ) ( т ) = г , де Х є оператором проекції осі Х і г є радіус кулі. Переставлені, отримаємо
т = ( г - ( т . Do )) / (( Х . Т . По ) ( т ))

Це має виразну перевагу - закопувати всю складну математику в жорстко написаних, перевірених та налагоджених стандартних графічних бібліотеках. Це рішення також ідентичне для 2D та 3D ситуацій - просто переключіть графічну бібліотеку. Нарешті, він підкреслює, що спочатку слід подумати про відповідні орієнтири, перш ніж вирішувати будь-яку фізичну проблему. Завжди є спокуса NIH, але насправді це лише рецепт помилок, коли доступні більш лаконічні рішення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.