Краткий ответ: точно определить, пересекаются ли два объекта, достаточно сложно, чтобы сделать его невозможным для обнаружения столкновений. Дискретизируйте ваш эллипс как n-сторонний многоугольник для некоторого n (в зависимости от того, насколько точным вам нужно быть) и выполните обнаружение столкновений с этим многоугольником.
Длинный ответ: если вы настаиваете на том, чтобы определить, пересекаются ли гладкий эллипс и круг, есть два основных подхода. В обоих случаях необходимо сначала найти ближайшую точку к центру круга на эллипсе, а затем сравнить это расстояние с радиусом круга.
Подход 1 : Используйте параметризацию эллипса. Преобразуйте свои координаты так, чтобы эллипс находился в начале координат, а его оси были выровнены по осям X-Y. То есть:
- Центр эллипса: (0,0)
- Центр круга: c = (cx, cy)
- Радиус круга: r
- Радиус оси эллипса по оси X: a
- Радиус оси Y эллипса: b.
Уравнение эллипса тогда определяется как a cos(t), b sin(t)
. Чтобы найти ближайшую точку, мы хотим минимизировать квадратное расстояние
|| (a cos t, b sin t) - c ||^2
. Как указывает Джин, это «просто исчисление»: возьмите производную и установите ее равной 0. Однако, если я что-то упустил, решение получающегося (довольно неприятного) уравнения для t
аналитически невозможно, и должны быть аппроксимированы с использованием, например, Метод Ньютона.
Подключите t
, который вы найдете в параметрическом уравнении, чтобы получить ближайшую точку.
- Pro: численное решение только в одной переменной,
t
.
- Con: Вы должны быть в состоянии записать параметризацию эллипса или преобразовать свои координаты, чтобы вы могли. Это не должно быть слишком сложно для любого разумного представления эллипса. Однако я собираюсь показать вам второй метод, который гораздо более общий и может быть полезен, если вам нужно обобщить вашу проблему, скажем, в 3D.
Подход 2 : Использовать многомерное исчисление. Нет необходимости менять координаты.
- Центр круга: c = (cx, cy)
- Радиус вихря: r
- Эллипс задается как g (x, y) = 0 для функции g. Например, согласно ответу Творда вы можете использовать g (x, y) = расстояние (x, y) от фокуса 1 + расстояние (x, y) от фокуса 2 - е.
Нахождение точки на эллипсе, ближайшем к центру круга, можно затем сформулировать как ограниченную задачу минимизации :
Minimize ||(x,y) - c||^2 subject to g(x,y) = 0
(Минимизация квадратного расстояния эквивалентна минимизации расстояния, и с ней гораздо приятнее иметь дело, поскольку это квадратичный полином по x, y.)
Чтобы решить задачу минимизации с ограничениями, мы вводим множитель Лагранжа лямбда и решаем систему уравнений
2 * [ (x,y) -c ] + lambda * Jg(x,y) = 0
g(x,y) = 0
Здесь Jg - градиент g. Это система из трех (нелинейных) уравнений с тремя неизвестными: x, y и lambda. Мы можем решить эту систему, используя метод Ньютона, и (x, y), который мы получаем, является ближайшей точкой к центру круга.
- Pro: параметризация не требуется
- Pro: метод очень общий и хорошо работает, когда писать g проще, чем находить параметрическое уравнение (например, в 3D)
- Con: Требуется многовариантное решение Ньютона, которое очень сложно, если у вас нет доступа к пакету численных методов.
Предостережение: оба эти подхода технически решают для точки, которая ограничивает расстояние до центра круга. Таким образом, найденная точка может быть самой дальней точкой от круга, а не самой близкой. Для обоих методов засев вашего решения с хорошим начальным предположением (центр круга хорошо работает для метода 2; вы самостоятельно для метода 1) уменьшит эту опасность.
Потенциальный третий подход? : Возможно, можно напрямую найти корни системы двух квадратных уравнений в двух переменных, представляющих круг и эллипс. Если существует настоящий корень, объекты пересекаются. Самый прямой способ решения этой системы, опять же с использованием численного алгоритма, такого как метод Ньютона, не поможет, потому что отсутствие сходимости не обязательно подразумевает отсутствие реального корня. Однако для двух квадратных уравнений с двумя переменными может существовать специализированный метод, который гарантированно найдет реальные корни, если они существуют. Я сам не могу придумать, как это сделать, но вы, возможно, захотите исследовать это самостоятельно (или посмотреть, может кто-нибудь из стека overflow может уточнить).