Я создал 4-точечную кривую Безье и расстояние. Начиная с начальной точки, как мне найти координаты x, y точки, которая находится на таком расстоянии от начальной точки?
Я просмотрел другие примеры, и, насколько я могу судить, они аппроксимируют значения, разделяя кривую на несколько тысяч точек, а затем находя ближайшую точку. У меня это не сработает. В том, что я делаю, я хотел бы быть точным только до двух десятичных знаков. Ниже приведена простая форма того, что мне нужно для создания кривой Безье. (Значения y произвольны, значения x всегда находятся на расстоянии 352 пикселя). Если важно, я работаю на Java.
path.moveTo(0, 400);
path.curveTo(352, 480, 704, 590, 1056, 550);
Итак, предполагая, что моя начальная точка равна 0,400, как мне найти координаты точки, которая находится на расстоянии 35 расстояний от этой начальной точки (вдоль кривой)? (В идеале что-то, не требующее интенсивного использования процессора. Это может работать 200 раз в секунду)
Ответ 1 · рейтинг 6 · Brandon
Для всех, кто нашел мой вопрос, я решил свою проблему. Чтобы найти общее расстояние вашей кривой, разбейте ее примерно на 1000 частей (все еще довольно точно), найдите расстояние между каждой точкой, затем сложите их все вместе. (вы должны использовать параметрическую формулу)
Теперь найдите процент пути по вашей кривой. = расстояние / totalLengthOfCurve
Используйте этот процент в качестве нового значения t для x и y, и теперь у вас есть новые позиции x и y.
ВАЖНО: Это странный случай, но используйте абсолютное значение, если ваше значение t когда-либо будет больше 1. Когда вы его кубите, это значение будет отрицательным ... = происходят плохие вещи.
Уродливый, но актуальный код показан ниже.
Разбивая кривую на 1000 частей
for (double t = 0.00; t < 1.001; t= t + .001) {
double xValue = Math.pow((1-t), 3) * point1x + 3 * Math.pow((1-t), 2) * t * point2x + 3 * (1-t) * Math.pow(t, 2) * point3x + Math.pow(t, 3) * point4x;
double yValue = Math.pow((1-t), 3) * point1y + 3 * Math.pow((1-t), 2) * t * point2y + 3 * (1-t) * Math.pow(t, 2) * point3y + Math.pow(t, 3) * point4y;
** Теперь, когда вы рассчитываете расстояние между каждой точкой. Я предлагаю поместить вычисленные выше значения в массив и выполнить цикл.
Расчет положений x и y
xPos = Math.abs(Math.pow((1 - percenttraveled), 3)) * point1x + 3 * Math.pow((1 - percenttraveled), 2) * percenttraveled * point2x + 3 * Math.abs((1 - percenttraveled)) * Math.pow(percenttraveled, 2) * point3x + Math.abs(Math.pow(percenttraveled, 3)) * point4x;
yPos = Math.abs(Math.pow((1 - percenttraveled), 3)) * point1y + 3 * Math.pow((1 - percenttraveled), 2) * percenttraveled * point2y + 3 * Math.abs((1 - percenttraveled)) * Math.pow(percenttraveled, 2) * point3y + Math.abs(Math.pow(percenttraveled, 3)) * point4y;
Ответ 2 · рейтинг 1 · Yona Appletree
В библиотеке javagraphics есть MeasuredShape (https://javagraphics.java.net/doc/com/bric/geom/MeasuredShape.html), который предоставляет для этого getPoint метод. Он также имеет несколько очень удобных методов для получения подпутей и касательных углов. Насколько я могу судить, они "правильно" реализуют логику путей, не прибегая к разбиению путей.
Я использовал эту часть библиотеки в проекте, который требует такого рода геометрических вычислений, и, похоже, он отлично работает.