适合MATLAB线的旋转轴

时间:2013-03-11 17:56:53

标签: matlab rotational-matrices cartesian-coordinates

我目前对以下问题感到沮丧:

我有轨迹数据(即:经度和纬度数据),我进行插值以找到线性拟合(在matlab中使用polyfit和polyval)。

我想做的是以x轴(经度1)最终位于最佳拟合线上的方式旋转轴,因此我的数据现在应该位于此(旋转)轴。

我试过的是从拟合线的斜率(一级多项式y=mx+q的公式中的m)评估旋转矩阵

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

然后将我的原始数据乘以此矩阵......无济于事!

我不断获得一个情节,我的数据位于中间,而不是x轴,我希望它们在那里。

我错过了什么?

感谢您的帮助!

最诚挚的问候,

Wintermute

2 个答案:

答案 0 :(得分:1)

有几件事:

  1. 如果您有线性函数y = mx + b,则该线的角度为atan(m),而不是m。对于小m', but very different for large m`,这些大致相同。

  2. 2+阶polyfit的线性分量不同于1阶polyfit的线性分量。您需要两次拟合数据,一次是在工作级别,一次是第一次订购。

  3. 给定斜率m,有比使用trig函数更好的计算旋转矩阵的方法(例如cos(atan(m)))。我总是在执行几何体时尝试避免触发函数,并用线性代数运算替换它们。这通常更快,并且导致奇点问题更少。请参阅以下代码。

  4. 这种方法会导致某些轨迹出现问题。例如,考虑北/南轨迹。但这是一个较长时间的讨论。

  5. 使用上述方法,加上上面的注释,下面是一些实现此目的的示例代码:

    %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

旋转您的积分