Касательная параметрической дискретной кривой - PullRequest
3 голосов
/ 31 марта 2010

У меня есть параметрическая кривая, скажем, два вектора двойников, где параметр является индексом, и мне нужно вычислить угол касательной к этой кривой в любой заданной точке (индекс).

Любое предложение или ссылка о том, как это сделать?

Спасибо.

Ответы [ 6 ]

6 голосов
/ 04 апреля 2010

Вот короткая формула, эквивалентная (я думаю) ответу pau.estalella:

m[i] = (y[i+1] - y[i-1]) / (x[i+1] - x[i-1])

это достаточно хорошо приблизительно соответствует наклону в точке (x[i], y[i]).

В вашем вопросе упоминается "угол касательной". Касательная, имеющая наклон m[i], составляет угол arctangent(m[i]) с положительной осью x. Если это то, что вам нужно, вы можете использовать арктангенс с двумя аргументами, если он доступен:

angle[i] = atan2(y[i+1] - y[i-1], x[i+1] - x[i-1])

это будет работать правильно, даже если x[i+1] == x[i-1].

3 голосов
/ 31 марта 2010

Я предлагаю вам проверить статью в Википедии о численном дифференцировании для начала. Прежде чем идти дальше, решите, для каких целей вы хотите использовать касательную, и решите, стоит ли вам пробовать более сложные схемы, чем простые, описанные в статье.

3 голосов
/ 31 марта 2010

Первая проблема, с которой вы столкнетесь, - это четное определение касательной в одной из вершин кривой. Рассмотрим, например, что у вас есть два массива:

x = { 1.0, 2.0, 2.0 };
y = { 1.0, 1.0, 2.0 };

Тогда во второй вершине у вас есть 90-градусное изменение направления линии. В этом месте касательная даже математически не определена.

Ответ на комментарий Грегсета ниже

Полагаю, что в вашем примере "касательная" во второй точке - это линия, параллельная (P0, P2), проходящая через P1 ... что даст мне ответ: для любой точки индекса N параллель к (N-1, N + 1), проходящая через N. Это было бы неплохим приближением?
Это зависит от того, для чего вы его используете. Рассмотрим для примера:

x = { 1.0, 2.0, 2.0 };
y = { 1.0, 1000000, 1000000 };

Это в основном L-образная форма с очень высокой вертикальной линией. В вашем предложении это даст вам почти вертикальную касательную. Это то, что вы хотите, или вы предпочитаете касательную в 45 градусов в этом случае? Это также зависит от ваших входных данных, как вы можете определить это.

Одним из решений является соединение двух векторов с вершиной, их нормализация и использование алгоритма. Таким образом, вы получите тангенс в 45 градусов в приведенном выше примере.

2 голосов
/ 31 марта 2010

Вычислить первую производную: dy / dx. Это дает вам касательную.

1 голос
/ 31 марта 2010

Касательная к гладкой кривой в точке P - это параметрическая прямая линия P + tV, где V - производная кривой по «параметру». Но здесь параметр - это просто индекс массива, а численное дифференцирование - сложная задача, поэтому для аппроксимации касательной я бы использовал (взвешенный) приближение наименьших квадратов .

Другими словами, выберите три или пять точек кривой вокруг интересующей вас точки P (т. Е. P [i-2], P [i-1], P [i], P [i + 1] и P [i + 2], если P == P [i]), и аппроксимируйте их прямой линией в смысле наименьших квадратов. Чем больше веса вы назначите средней точке P, тем ближе будет линия к P; с другой стороны, чем больше веса вы назначаете экстремальным точкам, тем более «касательной» будет прямая линия, то есть, тем приятнее будет аппроксимировать вашу кривую в окрестности P.

Например, в отношении следующих пунктов:

x = [-1, 0, 1]
y = [ 0, 1, 0]

, для которого касательная не определена (как в ответе Андерса Абеля), этот подход должен привести к горизонтальной прямой линии, близкой к точке (0,1).

0 голосов
/ 31 марта 2010

Вы можете попытаться вычислить касательную интерполирующей кривой, которая проходит через заданные точки (я имею в виду кубический сплайн, который довольно легко вывести) или вычислить касательную непосредственно из точек данных.

Вы можете найти грубое приближение производной следующим образом Пусть кривая C проходит через точки p1, p2 и p3. В точке p2 у вас есть две возможные касательные: t1 = p2-p1 и t2 = p3-p2. Вы можете объединить их, просто вычислив их среднее значение: 0,5 * (t1 + t2) или вы можете объединить их в соответствии с их длиной (или их 1 / длина)

Не забудьте нормализовать полученную касательную.

Чтобы вычислить угол между касательной и кривой, помните, что скалярное произведение двух единичных векторов дает косинус угла между ними. Возьмем результирующий тангенс t и единичный вектор v2 = | p3-p2 |, а acos (точка (t, v2)) дает нужный вам угол.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...