Вращение осей вокруг линии подгонки MATLAB

В настоящее время меня беспокоит следующая проблема:

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

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

То, что я пробовал, - это оценить матрицу вращения по наклону линии соответствия (m в формуле для полинома первой степени y=mx+q) как

[cos(m) -sin(m);sin(m) cos(m)]

а затем умножить мои исходные данные на эту матрицу... безрезультатно!

Я продолжаю получать график, на котором мои данные лежат посередине, а не по оси x, где я ожидаю.

Что мне не хватает?

Спасибо за любую помощь!

Наилучшие пожелания,

Винтермьют


person Mutewinter    schedule 11.03.2013    source источник
comment
Используя эту матрицу вращения, вы уже предполагаете, что ось вращения находится в начале координат. Это правда или нужно еще и данные переводить? Также я не мог понять из того, что вы написали, что не так, можете ли вы привести пример данных\кода, с которым вы работали?   -  person bla    schedule 11.03.2013
comment
На самом деле, как я заметил в Pursuit as Azim, матрица, которую я должен использовать, должна быть построена с помощью atan(m) (или ее эквивалента в линейной алгебре), а не m, и должна быть транспонирована для получения псевдонима вращения. Теперь, когда вы заставили меня заметить, это правда: в задаче вращения я игнорирую +q в уравнении y=mx+q... должен ли я также добавить перевод? Как? Спасибо за вашу помощь!   -  person Mutewinter    schedule 12.03.2013


Ответы (2)


Несколько вещей:

  1. Если у вас есть линейная функция y=mx+b, угол этой линии равен atan(m), а не m. Они примерно одинаковы для малых m', but very different for largem`.

  2. Линейный компонент полифита 2+ порядка отличается от линейного компонента полифита 1-го порядка. Вам нужно будет подобрать данные дважды, один раз на рабочем уровне и один раз с подгонкой первого порядка.

  3. Учитывая наклон m, существуют лучшие способы вычисления матрицы вращения, чем использование триггерных функций (например, cos(atan(m))). Я всегда стараюсь избегать триггерных функций при выполнении геометрии и заменяю их операциями линейной алгебры. Обычно это быстрее и приводит к меньшему количеству проблем с сингулярностями. См. код ниже.

  4. Этот метод приведет к проблемам для некоторых траекторий. Например, рассмотрим траекторию север/юг. Но это более долгая дискуссия.

Используя описанный метод, а также примечания выше, вот пример кода, который это реализует:

%Setup some sample data
long = linspace(1.12020, 1.2023, 1000);
lat  = sin ( (long-min(long)) / (max(long)-min(long))*2*pi  )*0.0001 + linspace(.2, .31, 1000);

%Perform polynomial fit
p = polyfit(long, lat, 4);

%Perform linear fit to identify rotation
pLinear = polyfit(long, lat, 1);
m = pLinear(1);  %Assign a common variable for slope
angle = atan(m);

%Setup and apply rotation
%    Compute rotation metrix using trig functions
rotationMatrix = [cos(angle) sin(angle); -sin(angle) cos(angle)];

%    Compute same rotation metrix without trig
a = sqrt(m^2/(1+m^2));  %a, b are the solution to the system:    
b = sqrt(1/(1+m^2));    %    {a^2+b^2 = 1}, {m=a/b}
%                       %That is, the point (b,a) is on the unit
%                       circle, on a line with slope m
rotationMatrix = [b a; -a b];  %This matrix rotates the point (b,a) to (1,0)

%    Generally you rotate data after removing the mean value
longLatRotated = rotationMatrix * [long(:)-mean(long) lat(:)-mean(lat)]';

%Plot to confirm
figure(2937623)
clf

subplot(211)
hold on
plot(long, lat, '.')
plot(long, polyval(p, long), 'k-')
axis tight
title('Initial data')
xlabel('Longitude')
ylabel('Latitude')

subplot(212)
hold on;
plot(longLatRotated(1,:), longLatRotated(2,:),'.b-');
axis tight
title('Rotated data')
xlabel('Rotated x axis')
ylabel('Rotated y axis')
person Pursuit    schedule 11.03.2013
comment
Спасибо! Это действительно полезно! - person Mutewinter; 12.03.2013
comment
Наконец я добрался до офиса и попробовал код: я вижу, что вы там сделали, и это было моей ошибкой! Ваша линейная матрица эквивалентна тригонометрической интерпретации m как тангенса угла (поэтому cos (угол) = (1/sqrt (1 + tan ^ 2 (угол))) и так далее), и вы использовали так называемое псевдоним вращения ( вращение оси вокруг вектора, транспонированного матрице вращения канонического алиби ... той, которую я неправильно использовал): правильно ли я интерпретировал ее? - person Mutewinter; 12.03.2013
comment
Я называю две версии матрицы вращения поворотами тела (вращением тела в кадре) и поворотами кадра (вращением кадра). Я честно не уверен, какой это; Я делаю это уже много лет, и мне всегда нужно проверять результаты. Обычно на самом деле я выбираю точку (в данном случае (b, a)), решаю, куда я хочу направить эту точку (например, (b, a) -> (1,0)), записываю (надеюсь) правильную матрицу, а затем проверьте ее. Самый мощный метод, который я нашел, — это запланировать написание большого количества тестового кода. - person Pursuit; 12.03.2013

Угол, который вы ищете в матрице поворота, - это угол, который линия образует с горизонталью. Это можно найти как арктангенс наклона, поскольку:

tan(\theta) = Opposite/Adjacent = Rise/Run = slope

поэтому t = atan(m) и отметив, что вы хотите повернуть линию обратно в горизонтальное положение, определите матрицу поворота как:

R = [cos(-t) sin(-t)
     sin(-t) cos(-t)]

Теперь вы можете вращать свои точки с помощью R

person Azim J    schedule 11.03.2013