[我分享] 某一点绕任意点旋转的实现

[复制链接]
iqiukp 发表于 2021-6-11 01:45:59
本帖最后由 iqiukp 于 2021-6-11 02:00 编辑

2in1.png

前言

在数据处理过程中,存在需要某一点绕任意点旋转一定角度的场景。该文章带来基于 MATLAB 语言的“某一点绕任意点进行旋转”的实现过程。

原理

假如有两个点:


要实现“以 为中心,将 点旋转角度"

1. 首先计算仿射变换矩阵

Snipaste_2021-06-11_01-48-13.png


2. 构造 点的齐次坐标:
Snipaste_2021-06-11_01-52-04.png

3. 计算  点旋转后的齐次坐标为:


4. 获取 点旋转后的坐标为:
Snipaste_2021-06-11_01-52-09.png

rotateAround 函数
基于上述原理,编写了一个通用函数, 实现   点 绕   点旋转 angle 度后的新坐标。
  • 角度若用“度”表示,对应的三角函数为 sindcosd
  • 角度若用“弧度”表示,对应的三角函数为 sincos
  1. function A_new = rotateAround(A, B, angle)
  2. % 函数功能: A 点 绕 B 点旋转 angle 度

  3. % 仿射变换矩阵
  4. rotateMatrix = [cosd(angle), -sind(angle), 0;...
  5.                 sind(angle), cosd(angle), 0;...
  6.                 0 0 1];
  7. M1 = [1, 0, B(1, 1);...
  8.       0, 1, B(1, 2);...
  9.       0, 0, 1;];
  10. M2 = [1, 0, -B(1, 1);...
  11.       0, 1, -B(1, 2);...
  12.       0, 0, 1;];
  13. M = M1*rotateMatrix*M2;

  14. % 旋转后的坐标
  15. A_new_ = M*[A, 1]';
  16. A_new = A_new_(1:2)';
  17. end
复制代码

MATLAB 例程


1. 点 A 和点 B 以及旋转的角度设置 (逆时针为正方向)
  1. % 点 A 和点 B
  2. A = [0, 0];
  3. B = [0.5, 1];

  4. % 旋转的角度
  5. angle = 30;
复制代码

2. 计算旋转后的坐标

  1. % A 绕 B 旋转后的坐标
  2. A_new = rotateAround(A, B, angle);
复制代码


3. 可视化

  1. % 可视化
  2. figure
  3. SZ = 16;
  4. color_ = [150, 138, 191; 12, 112, 104; 220, 94, 75]/255;
  5. hold on
  6. grid on
  7. box on

  8. plot(B(1, 1), B(1, 2),...
  9.     'Marker', 'o', 'MarkerSize', SZ ,...
  10.     'MarkerEdgeColor', 'k' ,...
  11.     'MarkerFaceColor', color_(2, :))

  12. plot(A(1, 1), A(1, 2),...
  13.     'Marker', 's', 'MarkerSize', SZ ,...
  14.     'MarkerEdgeColor', 'k' ,...
  15.     'MarkerFaceColor', color_(1, :))

  16. plot(A_new(1, 1), A_new(1, 2),...
  17.     'Marker', 's', 'MarkerSize', SZ,...
  18.     'MarkerEdgeColor', 'k' ,...
  19.     'MarkerFaceColor', color_(3, :))

  20. xlim([-1, 2]);
  21. ylim([-1, 2]);
  22. axis equal

  23. % 连接线
  24. line([A(1, 1), B(1, 1)], [A(1, 2), B(1, 2)], 'Color', 'k')
  25. line([A_new(1, 1), B(1, 1)], [A_new(1, 2), B(1, 2)], 'Color', 'k')

  26. % 第一主轴方向
  27. arrow_ = annotation('arrow', 'Color', [0, 114, 189]/255,...
  28.     'HeadStyle', 'cback2', 'LineWidth', 2, 'HeadWidth', 10, 'HeadLength', 10);
  29. arrow_.Parent = gca;
  30. arrow_.X = [A(1, 1), A_new(1, 1)];
  31. arrow_.Y = [A(1, 2), A_new(1, 2)];
  32. str = ['旋转的角度为: ', num2str(angle)];
  33. % text(xt,yt, str)
  34. annotation('textbox', [0.6, 0.15, 0.1, 0.1], 'String', str,...
  35.            'EdgeColor', 'none','FitBoxToText','on')
  36. legend('B点(中心点)', 'A点', '旋转后的A点')
复制代码
r30.png

其他角度:60度、90度、120度、150度
4in1_1.png

2 条回复


aijunhao 发表于 2021-6-11 09:52:18
本帖最后由 aijunhao 于 2021-6-11 09:54 编辑

很好用,如果是三维旋转的话是否就要考虑theta角和phi角,进行两次旋转了(三维的情况用的比较多一点,我一般是转成极坐标旋转以后在转换回直角坐标)

iqiukp 发表于 2021-6-11 11:09:15
aijunhao 发表于 2021-6-11 09:52
很好用,如果是三维旋转的话是否就要考虑theta角和phi角,进行两次旋转了(三维的情况用的比较多一点,我一 ...

对。三维的仿射变换矩阵就得考虑其他两个角度了,会相对复杂点。感觉用极坐标会更方便点:lol
您需要登录后才可以回帖 登录 | 注册

本版积分规则

相关帖子
热门教程
站长推荐
快速回复 返回顶部 返回列表