Як можна визначити довжину шляху?


11

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

ОНОВЛЕННЯ:

Шлях представлений декартовою площиною (2D).


На ваше запитання відповіли внизу цієї відповіді
BlueRaja - Danny Pflughoeft

Відповіді:


7

Як говорилося в попередніх відповідях, обчислити довжину кривої Безьє важко ( неможливо ?). Я б сказав, що 100% ігор використовують наближення довжини, що майже завжди є досить точним.

Кілька місяців тому я реалізував його, використовуючи запропонований підхід розбиття кривої на "маленькі" сегменти та додавання їх довжини. Там приклад реалізації C ++ тут .


11

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


Я можу це врахувати, але як я можу визначити, скільки сегментів я повинен мати і як я можу відобразити сегменти, щоб вони мали свою початкову та кінцеву точку на своєму шляху? Чи має ця методика назву? (тому я шукаю його в Google)
Валентин Раду

Простим підходом було б просто використовувати лінійний розподіл точок від B (0) до B (1) ... так, як щось, що ви використовуєте, щоб насправді побудувати криву. Подивіться на вихідний код у відповіді Дана.
bummzack

Я буду вдячний за пояснення про голосування, щоб знати, що я міг би покращити у своїй відповіді ...
bummzack

7

Параметризація довжини сплайну вищого порядку (тобто більша, ніж 1-й порядок) повинна бути наближена; вона не може бути представлена ​​безпосередньо, звідси й той факт, що нелегко знайти прямі рішення для цього.

Деякі існуючі реалізації (копіювати-вставити код):

Використовуючи наближення Чебишева , на думку авторів, точність зростає зі збільшенням розміру кривої. Подивіться п. 7–8 псевдокоду, решта - це опис інших алгоритмів, на яких вони ґрунтуються на своєму підході, який ви можете ігнорувати. Ряд посилань в Інтернеті називають цей метод хорошим.

Дивіться також ці стислі підходи.


5

Це почалося як коментар до коментаря до відповіді @ bummzack, але росло занадто довго.

як я можу визначити, скільки сегментів я повинен мати

Є два підходи. Перший - це лише стандартний алгоритм відображення кривої Безьє: контрольні точки утворюють обмежувальне поле кривої, тож якщо всі контрольні точки знаходяться в межах епсилона відрізка лінії від початкової точки до кінцевої точки, ви наближаєтесь до лінії; в іншому випадку ви підрозділяєте, використовуючи алгоритм де Кастелау. Епсілон вибирається відповідно до помилки, яку ви бажаєте в кінцевому результаті. (Для візуалізації зазвичай це 0,5 пікселя).

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

Один звичайно підрозділяє на t = 0,5, але алгоритм де Кастелау дозволяє розділити в будь-якій точці, тому якщо у вас кубічний Безьє з контрольними точками C_0 до C_3 і C_2 набагато ближче до відрізка лінії між кінцевими точками, ніж C_1, ви можете виявити, що розщеплення на один з 1/3 або 2/3 дає більш жорсткі межі. Я не працював над алгеброю, щоб виправдати, що було б краще, але ви можете експериментувати і звітувати, якщо хочете. Якщо нічого іншого, я хотів зазначити, що варіант є.


3

Обчислення довжини параметризованої кривої можна здійснити, взявши інтеграл sqrt ((dx / dt) ² + (dy / dt) ²), де dx / dt є похідною x-складової кривої, і dy / dt є похідною y-складової кривої. У разі Безьє-сплайна ці два однакові, оскільки рівняння можна поширити на будь-який вимір.

Формула кубічного Безьє-сплайна є такою: B (t) = (1 - t³) * P0 + 3 (1 - t) ²t * P1 + 3 (1 - t) t² * P2 + t³ P3, де P0 через P3 - контрольні точки.

Відповідно до Вольфрама | Альфи, похідна цієї формули: d (B (t)) / dt = 3 (t (t (P3 - P0) + P2 (2 - 3t) + P1 (3t² - 4t + 1))

Тепер ви можете поставити це назад у рівняння для довжини кривої та обчислити інтеграл від t = 0 до t = 1. На жаль, Вольфрам | Альфа разів випадає, коли я намагаюся це зробити. Однак ви можете зробити чисельну інтеграцію.

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