29.09.2012 - 23:20
Я створив git Repo тут:
https://github.com/ArthurWulfWhite/Bezier-Distance/
Ви можете завантажити вихідні файли у вигляді поштового індексу. Сюди також входить демонстрація, яку можна скласти за допомогою FlashDevelop. Щоб використовувати демонстраційну версію, відкрийте проект у програмі Flash Developer та натисніть «Тестувати проект». Під час запуску демонстрації натисніть на LMB, щоб рандомізувати нову криву Безьє та нове коло.
Удачі!
Посилання на zip важко помітити - просто використовуйте Ctrl + F і введіть zip. Це джерело представляє пару тижнів дослідження та програмування, сподіваюся, вам сподобається.
Якщо ви плануєте розділити безір рекурсивно на сегменти і перевірити на предмет зіткнень з ними, я пропоную зробити 100 100 масивів (сітку) та розмістити кожен сегмент у чотирьох найближчих квадратиках, тому вам доведеться перевірити лише на зіткнення з 4/1000 сегментує кожен кадр.
Я думаю, що ви отримаєте користь від box2d і як програміста, і як творця ігор, оскільки існує багато прихованих маленьких перешкод у створенні «простого» фізичного двигуна, який робить рух здається трохи грубішим і менш рідким, ніж це може бути.
Стара відповідь: Чистий шлях.
Ви дійсно можете побачити, чи коло стикається з кривою Безьє, перевіривши відстань між відстань між центром кола та найближчою точкою на кривій.
Рівняння відстані (загалом)
пояснив:
Рівняння Безьє:
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Це можна підсумувати (з деякою алгеброю) - я пропущу. (X, y) для читабельності (це все-таки точки, а не одне число)
q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start
Відстань від точки (x, y) дорівнює:
sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)
Щоб знайти найближчу точку на безьє до кулі, потрібно вивести і знайти всі точки, де похідна дорівнює нулю (коріння). Це поліном третього ступеня, тому ви можете використовувати закриту формулу, але це може бути ненадійним, оскільки точність комп'ютерної плаваючої точки, представленої дробами, може бути недостатньою. Набагато краще використовувати Newton або щось подібне.
Похідна, для якої потрібно знайти корені:
Припустимо: a = старт b = контроль c = кінець d = центральна точка кола
Хитра частина - це множення цих точок, ви повинні використовувати крапковий продукт.
Якщо вам подобається, у мене є код для цього, і я можу поділитися ним тут у вигляді функції, яка просто повертає булеву форму, якщо виникає зіткнення чи ні та кут зіткнення. Деякі проблеми можуть виникнути при наївній реалізації двигуна зіткнення, наприклад, наприклад, що швидко рухається кулька може потрапити між двома кривими.
Я рекомендую поки уникати цього, просто підсумуйте коефіцієнти для осі x та осі y та додайте їх.
Використовуйте будь-який надійний метод, який ви можете обрати, як Ньютон, щоб знайти корені, перевірте відстань від кореневих точок на безьє, 0 <= t <= 1 до центру кола і перевірте відстань для двох кінців безьє (початок і кінець) до центру кола, який із найближчих, скаже вам, чи має місце зіткнення.
Якщо радіус менший, ніж мінімальна відстань, відбувається зіткнення.
Кут приблизно такий, який знаходиться між центром кола та найближчою точкою на безьє.
Це, як сказано, якщо ви справді хочете зробити гру з фізикою зіткнення, я пропоную вам просто переглядати безьє
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Розділіть кожен фрагмент на середині рекурсивно, поки він не буде достатньо малим, скажімо 10 пікселів або менше, а потім побудуйте безьє грубо з полів і використовуйте Box2d для фізики, тому що можливо, що написання всього цього коду виявлення зіткнення виявиться чудовим раковина часу, що не дуже покращує ігровий процес. Використання Box2d зарекомендувало себе в безлічі проектів у минулому.