Matlab 绕拟合线旋转轴

Matlab 绕拟合线旋转轴,matlab,rotational-matrices,cartesian-coordinates,Matlab,Rotational Matrices,Cartesian Coordinates,我目前对以下问题感到沮丧: 我得到了轨迹数据(即经度和纬度数据),我通过插值来找到线性拟合(在matlab中使用polyfit和polyval) 我想做的是旋转轴,使x轴(经度)最终位于最佳拟合线上,因此我的数据现在应该位于这个(旋转的)轴上 我尝试的是从拟合线的斜率(一级多项式公式中的my=mx+q)计算旋转矩阵,如下所示: [cos(m)-sin(m);sin(m)cos(m)] 然后用这个矩阵乘以我的原始数据…没用 我一直在寻找一个情节,我的数据放在中间,而不是X轴上。 我错过了什么 谢谢

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

我得到了轨迹数据(即经度和纬度数据),我通过插值来找到线性拟合(在matlab中使用polyfit和polyval)

我想做的是旋转轴,使x轴(经度)最终位于最佳拟合线上,因此我的数据现在应该位于这个(旋转的)轴上

我尝试的是从拟合线的斜率(一级多项式公式中的m
y=mx+q
)计算旋转矩阵,如下所示:

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

然后用这个矩阵乘以我的原始数据…没用

我一直在寻找一个情节,我的数据放在中间,而不是X轴上。 我错过了什么

谢谢你的帮助

致以最良好的祝愿


Wintermute

在旋转矩阵中查找的角度是直线与水平面的角度。这可以作为坡度的切线找到,因为:

tan(\theta) = Opposite/Adjacent = Rise/Run = slope
因此
t=atan(m)
注意,要将直线旋转回水平方向,请将旋转矩阵定义为:

R = [cos(-t) sin(-t)
     sin(-t) cos(-t)]
现在,您可以通过以下几点旋转点:

  • 如果你有一个线性函数y=mx+b,那条线的角度是
    atan(m)
    ,而不是
    m
    。对于较小的
    m',这些值大致相同,但对于较大的
    m',这些值非常不同

  • 2+阶多边形拟合的线性分量与1阶多边形拟合的线性分量不同。您需要对数据进行两次拟合,一次是在工作级别,一次是一阶拟合

  • 给定斜率
    m
    ,计算旋转矩阵的方法比使用三角函数更好(例如
    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')
    

    使用此旋转矩阵,您已经假设旋转轴位于原点。这是真的还是你也需要翻译数据?另外,我也不明白你写的是什么错了,你能给出一些你使用过的示例数据\代码吗?事实上,正如Azim让我注意到的那样,我应该使用的矩阵必须是用atan(m)(或线性代数等价物)而不是m构建的,并且应该进行转置以获得“别名”类型的旋转。现在你让我注意到了,这是真的:在旋转问题中,我忽略了
    y=mx+q
    方程中的
    +q
    ,我是否也应该添加一个平移?怎么用?谢谢你的帮助!谢谢这真的很有帮助!我终于到了办公室,试了一下密码:我知道你在那里做了什么,那是我的错!你的线性矩阵相当于用三角法将m解释为角度的切线(因此cos(angle)=(1/sqrt(1+tan^2(angle)),等等),你采用了所谓的“别名”旋转(轴围绕向量的旋转,这是标准的“alibi”旋转矩阵的转置…我没有正确使用的旋转矩阵):我是否正确解释了它?我将旋转矩阵的两个版本称为“身体”旋转(在帧中旋转身体)和“帧”旋转(旋转帧)。老实说,我不确定这是哪一个;我已经做了很多年了,我总是需要检查结果。通常要做的是选择一个点(在本例中为(b,a)),决定我希望该点的位置(例如(b,a)->(1,0)),写下(希望)正确的矩阵,然后检查它。我发现的最强大的方法是计划编写大量测试代码。