先放一张三维球体旋转图形效果图
该图形旋转主要用到了圆的参数方程和空间几何变换矩阵。
1. 画出球形
为了画出一个圆形,圆形的参数方程为:
y=y0+r×cos(θ)
y
=
y
0
+
r
×
c
o
s
(
θ
)
z=z0+r×sin(θ)
z
=
z
0
+
r
×
s
i
n
(
θ
)
其中 (y0,z0) ( y 0 , z 0 ) 是圆心, r r 是半径。这样在平面就能画出一个圆了。现在要画在三维坐标下,所以我们只需要增加一个固定 x0 x 0 坐标,就可以画出圆心在 (x0,y0,z0) ( x 0 , y 0 , z 0 ) ,半径为 r r ,平行于的圆了。为了简化一点,我们把球心坐标定为 (0,0,0) ( 0 , 0 , 0 ) , 在 x x 轴方向上画出等间距的若干圆,并且使他们的r和x0满足三角关系
R R 为球体半径,为到 yoz y o z 的距离,r为圆的半径。
2.旋转
旋转用到了三维空间的几何变换,三维空间几何变换包括平移,旋转,缩放等操作,这里只用到了绕z轴旋转。旋转矩阵为
T=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪cos(θ)sin(θ)00−sin(θ)cos(θ)0000100001 ⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪
T
=
{
c
o
s
(
θ
)
−
s
i
n
(
θ
)
0
0
s
i
n
(
θ
)
c
o
s
(
θ
)
0
0
0
0
1
0
0
0
0
1
}
变换时左乘以变换矩阵
⎧⎩⎨⎪⎪⎪⎪⎪⎪x′y′z′1 ⎫⎭⎬⎪⎪⎪⎪⎪⎪=T⎧⎩⎨⎪⎪⎪⎪⎪⎪xyz1 ⎫⎭⎬⎪⎪⎪⎪⎪⎪
{
x
′
y
′
z
′
1
}
=
T
{
x
y
z
1
}
3.代码实现
先写一个画圆的函数方便调用
% function name:getCirclePoints
% input:
% - r 圆的半径
% - x0 y0 z0 圆的圆心
% output:
% - x y z 坐标点向量
function [x,y,z] = getCirclePoints(r,x0,y0,z0)
theta = 0: 0.01*pi: 2*pi; %角度0-2pi
x = x0*ones(1,length(theta)); %计算坐标
y = y0 + r*cos(theta);
z = z0 + r*sin(theta);
end
主程序
clc,clear
x0 = -7 : 0.5 : 7; %圆的横坐标
y0 = 0; z0 = 0;
R = 7*ones(1,length(x0)); %球半径
r = sqrt(R.^2 - x0.^2); %圆半径
theta = 0 : 0.01*pi : 2*pi; %旋转角度为一圈
pic_num = 1;
for k = 1:length(theta)
x = []; y =[]; z = [];
% 计算画一个球体坐标
for i = 1:length(r)
[xt,yt,zt] = getCirclePoints(r(i),x0(i), y0, z0);
x = [x xt];
y = [y yt];
z = [z zt];
end
coordinate = [x;y;z;ones(1,length(x))]; %增加一行1
T = [cos(theta(k)),-sin(theta(k)),0,0; sin(theta(k)),cos(theta(k)),0,0; 0,0,1,0; 0,0,0,1]; %绕z旋转矩阵
coordinate = T*coordinate;%旋转变换
figure(1)
plot3(coordinate(1,:),coordinate(2,:),coordinate(3,:),'.'); %画出图形
axis equal %等间距,不然看起来可能是瘪的
axis([-10 10 -10 10 -10 10])
view([20,0,0]) %设置观察视角
%下面是保存成GIF动画
drawnow;
F=getframe(gcf);
I=frame2im(F);
[I,map]=rgb2ind(I,256);
if pic_num == 1
imwrite(I,map,'global.gif','gif', 'Loopcount',inf,'DelayTime',0.1);
else
imwrite(I,map,'global.gif','gif','WriteMode','append','DelayTime',0.001);
end
pic_num = pic_num + 1;
end