Відповіді:
Ось моя спроба. Наступні алгоритми далеко не ідеальні , але вони прості, і я вважаю, що ви повинні почати з цього, перевірити, чи працюють вони у вашій ситуації, і пізніше перейти на щось швидше та / або точніше.
Ідея така:
Крива Безьє параметризується функцією, що F(t)використовує набір контрольних точок і змінний параметрt . Кількість генеруючих точок неважлива.
Рядок параметризований на дві точки Aі B.
Нехай, SAMPLES = 10наприклад
Почніть з t0 = 0іt1 = 1
Дозволяти dt = (t1 - t0) / SAMPLES
Якщо dt < 1e-10(або будь-який інший стан точності, який ви вважаєте за потрібне), алгоритм закінчений, і відповідь єF(t0) .
Обчисліть список SAMPLES + 1точок на кривій Безьє:
L[0] = F(t0)L[1] = F(t0 + dt)L[2] = F(t0 + 2 * dt)L[SAMPLES] = F(t0 + SAMPLES * dt)Знайдіть, який пункт Lіз індексом iє найближчим до рядка. Використовуйте будь- який відомий вам метод відстані точки / лінії , наприклад квадратну відстань, ||AB^L[i]A||² / ||AB||²де ^позначають поперечний добуток, і ||…||це відстань.
Якщо i == 0, встановити i = 1; якщо i == SAMPLES, встановитиi = SAMPLES - 1
Нехай t1 = t0 + (i + 1) * dtіt0 = t0 + (i - 1) * dt
Поверніться до кроку 3.
На цей раз у нас є дві криві Безьє, параметризовані по F(t)та G(t).
Нехай, SAMPLES = 10наприклад
Почніть з t0 = 0, t1 = 1, s0 = 0іs1 = 1
Дозволяти dt = (t1 - t0) / SAMPLES
Дозволяти ds = (s1 - s0) / SAMPLES
Якщо dt < 1e-10(або будь-який інший стан точності, який ви вважаєте за потрібне), алгоритм закінчений, і відповідь єF(t0) .
ЯКЩО це перший запуск циклу:
6.1. Обчисліть список SAMPLES + 1пунктів F( див. Вище ).
6.2. Обчисліть список SAMPLES + 1пунктів на G.
6.3. Знайдіть, яка пара точок є найближчою одна до одної.
6.4. Оновлення t0, t1, s0, s1як показано вище.
ELSE : альтернативно обчислити список точок на F АБО списку пунктів G, потім знайти, яка точка Fнаближається до G(s0)оновлення t0та t1, АБО, яка точка Gє найближчою до F(t0)оновлення s0та s1.
Поверніться до кроку 3.
За задумом ці алгоритми завжди збігаються до локального мінімуму. Однак немає гарантії, що вони сходиться до найкращого рішення. Зокрема, алгоритм кривої Безьє зовсім не дуже хороший, і якщо дві криві знаходяться близько один до одного в багатьох місцях, ви, на жаль, можете пропустити рішення довгим пострілом.
Але, як я вже сказав, перш ніж почати думати про більш надійні рішення, спершу слід експериментувати з тими простими.
1) Перекладіть все на одну вісь, тож замість того, щоб обчислювати довжину однієї точки до 'лінії', 'лінія' - це, скажімо, вісь Y.
Тоді, е-е, з урахуванням кривої Безьє, я б сказав, що це відповідає кількості контрольних точок.
Якщо їх є три (початок, "контроль" і кінець), я б здійснив певну перевірку (скажіть кожен на пару відсотків, а потім уточнити між найближчими (скажімо, "двійковий" підхід).
Більше балів, я б спробував пару, яка була найближче до (перекладено Y-Axis).
Я впевнений, що математик може дати вам точне рішення (з математики), але якщо ви хочете знайти / рішення у відеоігри, вам може бути краще злегка рішення, оскільки реальне рішення може містити кілька відповідей ( Я навіть не кажу про потужність обробки).
Деякі відповіді зі сторінки блогу Algorithmist , яка правильно знаходить найближчу точку на заданій квадратичній кривій Безьє.
Демо .

Для кривої Безьє - прямолінійного випадку, найбільш точним способом знайти відповідь є наступне: