29.09.2012 - 23:20
Я создал репо git здесь:
https://github.com/ArthurWulfWhite/Bezier-Distance/
Вы можете скачать исходные файлы в виде zip оттуда. Он также включает в себя демонстрацию, которую вы можете скомпилировать с помощью FlashDevelop. Чтобы использовать демо, откройте проект во Flash Develop и нажмите «Test Project». Во время запуска демонстрации нажмите ЛКМ, чтобы рандомизировать новую кривую Безье и новый Круг.
Удачи!
Ссылку zip трудно увидеть - просто используйте Ctrl + F и введите zip. Этот источник представляет собой пару недель исследований и программирования, надеюсь, вам понравится.
Если вы планируете рекурсивно делить Безье на сегменты и проверять наличие с ними столкновений, я предлагаю создать массив 100 100 (сетку) и поместить каждый сегмент в четыре ближайших квадрата, так что вам нужно только проверять наличие столкновений с 4/10 000 из сегментирует каждый кадр.
Я действительно думаю, что 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)
Чтобы найти ближайшую точку на безье к мячу, вам нужно вывести и найти все точки, где производная равна нулю (корни). Это многочлен третьей степени, поэтому вы можете использовать закрытую формулу, но это может быть ненадежно, поскольку точность представленных на компьютере дробей с плавающей запятой может быть недостаточной. Гораздо лучше использовать Ньютона или что-то в этом роде.
Производная, для которой нужно найти корни:
Предполагая: 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 зарекомендовало себя в бесчисленных проектах в прошлом.