围绕原点旋转坐标时出现问题

Trouble rotating coordinates about origin

我在使用简单的脚本时遇到了一些困难。目标是使用某个角度围绕原点旋转一组点。但是,我使用的代码似乎无法保持向量的大小。

我正在使用一个数组,其中第一列是 x 坐标,第二列是 y 坐标:

for ii=1:1000
    angleRads=rand()*2*pi;
    randRotPoints(ii,1)=1*cos(angleRads)-0*sin(angleRads);
    randRotPoints(ii,2)=0*cos(angleRads)+1*sin(angleRads);
end
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths1=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);

for ii=1:1000
    angleRads=rand()*2*pi;
    randRotPoints(ii,1)=randRotPoints(ii,1)*cos(angleRads)-randRotPoints(ii,2)*sin(angleRads);
    randRotPoints(ii,2)=randRotPoints(ii,2)*cos(angleRads)+randRotPoints(ii,1)*sin(angleRads);
end
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths2=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);

在第一个循环之后,有一个数量级为 1 且方向随机的坐标。这通过散点图得到证实,lengths1 数组全为 1。

但是,尝试将这些坐标旋转第二个随机角度的第二个循环导致看似随机定位的坐标(基于散点图),并且长度不再全部为 1。

请帮我找出这个轮换代码哪里出了问题。我知道就性能或行数而言,这不是最有效的代码,如果您想提供一种更好的方法来提高效率,那很好,但也请说明修复问题所需的内容也是当前格式的代码。

谢谢。

在你的第二个循环中你有

randRotPoints(ii,1)=randRotPoints(ii,1)*cos(angleRads)-randRotPoints(ii,2)*sin(angleRads);

randRotPoints(ii,2)=randRotPoints(ii,2)*cos(angleRads)+randRotPoints(ii,1)*sin(angleRads);

即您在计算 y 时使用覆盖(旋转)的 x 坐标。尝试在旋转之前保存 randRotPoints(ii,:) 矢量,并在右侧使用保存的值。

至于提高效率:

可读解决方案

您可以通过显式定义每个点的旋转矩阵来提高代码的可读性

for ii=1:1000
    angleRads=rand()*2*pi;
    rotmat=[cos(angleRads) -sin(angleRads); sin(angleRads) cos(angleRads)];
    randRotPoints(ii,:)=rotmat*[1; 0];
    %note that this is equivalent to
    %randRotPoints(ii,:)=[cos(angleRads); sin(angleRads)];
end
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths1=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);

for ii=1:1000
    angleRads=rand()*2*pi;
    rotmat=[cos(angleRads) -sin(angleRads); sin(angleRads) cos(angleRads)];
    randRotPoints(ii,:)=rotmat*(randRotPoints(ii,:).');
end
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths2=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);

为了避免一些代码重复,您还可以定义一个 rotmatfun=@(angleRads) [cos(angleRads) -sin(angleRads); sin(angleRads) cos(angleRads); 函数,然后您可以在循环中说 rotmat=rotmatfun(angleRads);

高效解决方案

您可以通过使用矢量化符号完全取消循环:

N=1000; %number of points

angleRads=rand(N,1)*2*pi;
randRotPoints=[1*cos(angleRads)-0*sin(angleRads), ...
               0*cos(angleRads)+1*sin(angleRads)]; %matrix of size [N,2]
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths1=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);

angleRads=rand(N,1)*2*pi;
randRotPoints=[randRotPoints(:,1).*cos(angleRads)-randRotPoints(:,2).*sin(angleRads), ...
               randRotPoints(:,2).*cos(angleRads)+randRotPoints(:,1).*sin(angleRads)];
figure;
scatter(randRotPoints(:,1),randRotPoints(:,2));
lengths2=sqrt(randRotPoints(:,1).^2+randRotPoints(:,2).^2);