我目前对以下问题感到沮丧:
我有轨迹数据(即:经度和纬度数据),我进行插值以找到线性拟合(在matlab中使用polyfit和polyval)。
我想做的是以x轴(经度1)最终位于最佳拟合线上的方式旋转轴,因此我的数据现在应该位于此(旋转)轴。
我试过的是从拟合线的斜率(一级多项式y=mx+q
的公式中的m)评估旋转矩阵
[cos(m) -sin(m);sin(m) cos(m)]
然后将我的原始数据乘以此矩阵......无济于事!
我不断获得一个情节,我的数据位于中间,而不是x轴,我希望它们在那里。
我错过了什么?
感谢您的帮助!
最诚挚的问候,
Wintermute
答案 0 :(得分:1)
有几件事:
如果您有线性函数y = mx + b,则该线的角度为atan(m)
,而不是m
。对于小m', but very different for large
m`,这些大致相同。
2+阶polyfit的线性分量不同于1阶polyfit的线性分量。您需要两次拟合数据,一次是在工作级别,一次是第一次订购。
给定斜率m
,有比使用trig函数更好的计算旋转矩阵的方法(例如cos(atan(m))
)。我总是在执行几何体时尝试避免触发函数,并用线性代数运算替换它们。这通常更快,并且导致奇点问题更少。请参阅以下代码。
这种方法会导致某些轨迹出现问题。例如,考虑北/南轨迹。但这是一个较长时间的讨论。
使用上述方法,加上上面的注释,下面是一些实现此目的的示例代码:
%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')
答案 1 :(得分:0)
您在旋转矩阵中查找的角度是线条与水平线的角度。这可以作为斜率的反正切来找到:
tan(\theta) = Opposite/Adjacent = Rise/Run = slope
所以t = atan(m)
并注意到您想要将线条旋转回水平,将旋转矩阵定义为:
R = [cos(-t) sin(-t)
sin(-t) cos(-t)]
现在,您可以使用R