У меня есть игра, в которой каждый игрок должен пройти по указанному пути. Я рисую путь, используя кривые Безье. Как я могу определить общую реальную (не линейную) длину пути и расстояние, пройденное каждым игроком? (Расстояние между начальной точкой и указанной точкой на пути.)
ОБНОВИТЬ:
Путь представлен в декартовой плоскости (2D).
Ответы:
Как говорилось в предыдущих ответах, вычислить длину кривой Безье сложно ( невозможно ?). Я бы сказал, что в 100% игр используется приблизительная длина, которая почти всегда достаточно точна.
Несколько месяцев назад я реализовал это, используя предложенный подход, разбивая кривую на «маленькие» сегменты и добавляя их длину. Там пример реализации C ++ здесь .
источник
Измерение длины кривой Безье сложно. Если вы не возражаете против небольшой неточности, простым решением было бы приблизить кривые Безье прямыми линиями и вычислить сумму длин линий. Чем больше сегментов вы создаете, тем лучше приближение.
источник
Параметрирование длины сплайна более высокого порядка (т.е. более 1-го порядка) должно быть аппроксимировано; оно не может быть представлено напрямую, отсюда тот факт, что не так просто найти прямые решения для этого.
Некоторые существующие реализации (копирование-вставка кода):
Используя чебышевские приближения , по мнению авторов, точность возрастает с увеличением размера кривой. Посмотрите на псевдокод на стр. 7-8, остальное - описание других алгоритмов, на которых они основывают свой подход, которые вы можете игнорировать. Ряд ссылок в Интернете называют этот метод хорошим.
Смотрите также эти краткие подходы.
источник
Это началось как комментарий к комментарию к ответу @ bummzack, но вырос слишком долго.
Есть два подхода. Первый - это просто стандартный алгоритм рендеринга кривой Безье: контрольные точки образуют ограничивающую рамку кривой, поэтому, если все контрольные точки находятся в эпсилоне от отрезка линии от начальной точки до конечной точки, вы приближаетесь к линии; в противном случае вы подразделяете, используя алгоритм де Кастеляу. Эпсилон выбирается в соответствии с ошибкой, которую вы хотите в конечном результате. (Для рендеринга обычно это 0,5 пикселя).
Другой подход - это уточнение с использованием интервальной арифметики. В качестве нижней границы берется длина линии от начала до конца, а в качестве верхней границы - сумма длин линий через контрольные точки. Опять же, подразделите в соответствии с вашими требованиями к окончательной ошибке.
Обычно делится на t = 0.5, но алгоритм де Кастельхау позволяет расщеплять в любой точке, поэтому, если у вас кубический Безье с контрольными точками от C_0 до C_3 и C_2 гораздо ближе к отрезку линии между конечными точками, чем C_1, вы можете обнаружить, что расщепление в одна из 1/3 или 2/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 контрольные точки.
Согласно Wolfram | Alpha, производная этой формулы имеет вид: d (B (t)) / dt = 3 (t (t (P3 - P0) + P2 (2 - 3t) + P1 (3t² - 4t + 1))
Теперь вы можете поместить это обратно в уравнение для длины кривой и вычислить интеграл от t = 0 до t = 1. К сожалению, Wolfram | Alpha истекает, когда я пытаюсь это сделать. Вы можете сделать числовую интеграцию, однако.
источник