EDA365电子论坛网
标题:
绕任意空间轴旋转三维图形的MATLAB实现
[打印本页]
作者:
mytomorrow
时间:
2020-3-2 13:32
标题:
绕任意空间轴旋转三维图形的MATLAB实现
绕任意空间轴旋转三维图形的MATLAB实现
. J# B" N2 N! R& a$ U) Z/ B. R
8 ]* p: j2 A5 W# \0 l
在计算图形学中,会经常涉及两种变化:
$ |+ [5 W( a: n' a& r( O$ R1 z
, d) p2 P. q& W: o) Q# |% i! N
一是:三维几何变换。就是在同一个坐标系中,对图形进行旋转,缩放,平移等,其中任意轴旋转比较麻烦!
: I& z5 A+ i# w5 Q0 @% |
6 T2 }2 j2 o {7 \- e3 m
二是:三维坐标变换。就是在不同的坐标系中观察同一物体,从一个坐标系的坐标转换在另外一个坐标系的坐标。比如我在绘制三维图形的时候有事需要建立局部坐标系,那么这里就涉及到全局坐标系和局部坐标系的数据转换了。
; ]2 i) ~. u: E! n, n- c/ w6 a- y
# \! U9 G/ M4 g! O. }
坐标变换比几何变化复杂很多,这次不讨论哦。另外一个复杂的变换可以通过一些简单的变化组成,比如任意轴旋转就可以分解为平移、绕坐标轴旋转完成。
& @7 H% ]0 W ]+ A+ J8 t
2 a7 U2 H4 U8 u# U1 Z3 Y5 u" X/ ^* H
关于具体的理论推导我们也不讨论了,感兴趣的朋友可以查看相关《计算机图形学》教材。至于平移和缩放就更加简单了,只要右乘一个变换矩阵(矩阵的内容请查看相关书籍)就可以。下面我给出图形绕任意三维轴旋转的MATLAB代码。
& x) q7 y- S8 ], _, I! s9 e" O$ q
function Pr=rot3d(P,origin,dirct,theta)
% 将坐标点P绕着,过origin点,方向为dirct的直线,旋转theta角
% P:需要旋转的做标集合,n×3矩阵
% origin:转轴通过的点,1×3向量
% direct:转轴方向向量,1×3向量
% theta:旋转角度,单位弧度
%
% By LaterComer of MATLAB技术论坛
% See also http://www.matlabsky.com
% Contact me
matlabsky@gmail.com
% Modifid at 2011-07-26 19:51:32
dirct=dirct(:)/norm(dirct);
A_hat=dirct*dirct';
A_star=[0, -dirct(3), dirct(2)
dirct(3), 0, -dirct(1)
-dirct(2), dirct(1), 0];
I=eye(3);
M=A_hat+cos(theta)*(I-A_hat)+sin(theta)*A_star;
origin=repmat(origin(:)',size(P,1),1);
Pr=(P-origin)*M'+origin;
3 d; h( y' M) v9 Z) Y( |# x; i4 P
8 h9 V5 W \ u+ y7 @
# k- Z, U3 T0 ~
我们下面验证下我们的效果,MATLAB中提供了rotate函数进行图形旋转,但是可惜的是不会返回旋转后的坐标数据。
' M0 M, e8 v8 C+ K+ p; O
clc
clear
close all
% 随机生成转轴通过的点
origin=rand(1,3)*10;
% 随机生成转轴方向
direct=rand(1,3)*10;
% 随机生成旋转角度
theta=rand*5;
[x,y,z]=peaks;
%% 图形比较
% 使用MATLAB自带rotate函数
figure
mesh(x,y,z);
hold on
h=mesh(x,y,z);
% rotate函数中角单位是角度
rotate(h,direct,rad2deg(theta),origin)
title('使用MATLAB自带rotate函数')
% 使用自己编写的rot3d函数
figure
mesh(x,y,z)
hold on
P=[x(:),y(:),z(:)];
Pr=rot3d(P,origin,direct,theta);
xr=reshape(Pr(:,1),size(x));
yr=reshape(Pr(:,2),size(x));
zr=reshape(Pr(:,3),size(x));
mesh(xr,yr,zr);
title('使用自己编写rot3d函数')
%% 数据比较
% 使用MATLAB自带rotate函数
% 由于该函数直接将图形旋转,如果想得到旋转之后的数据
% 此时可以使用get函数直接从图形的xdata,ydata和zdata属性中获取
xq=get(h,'xdata');
yq=get(h,'ydata');
zq=get(h,'zdata');
% 使用自己编写的rot3d函数
% 该函数自动返回旋转的数据而不是图形
% 也就是上面的xr,yr,zr
% 现在比较两组数据是否一致
disp('坐标Y的最大差距')
max(max(abs(yq-yr)))
disp('坐标X的最大差距')
max(max(abs(xq-xr)))
disp('坐标Z的最大差距')
max(max(abs(zq-zr)))
' }. n! r& b8 ]: l# j" g5 V
L, t, `: k. J' |0 K, ]
! H( ~$ v7 _" h: q7 Q( l2 ?8 f, x$ v
坐标X的最大差距
ans =
0
坐标Y的最大差距
ans =
0
坐标Z的最大差距
ans =
1.7764e-015
- M8 P% m. ]# x7 n8 M9 o* D
- B) l! P7 T7 x' P; }3 L
, y% X. F5 g8 T( \( J2 H/ h4 @" U
5 g. l' }( U( L3 D: v% r5 J
% M* T# d; y( g" ?0 x" }1 U
/ I) K; z8 P; E2 u2 ]* L4 M# n- k
作者:
CCxiaom
时间:
2020-3-2 16:26
选装跳跃
作者:
anguchou
时间:
2020-3-28 22:51
:):)
作者:
yin123
时间:
2020-3-30 19:00
绕任意空间轴旋转三维图形的MATLAB实现
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2