先放一张三维球体旋转图形效果图
该图形旋转主要用到了圆的参数方程和空间几何变换矩阵。
1. 画出球形
为了画出一个圆形,圆形的参数方程为:
y=y0+r×cos(θ)y=y0+r×cos(θ)
z=z0+r×sin(θ)z=z0+r×sin(θ)
其中(y0,z0)(y0,z0)是圆心,rr是半径。这样在平面就能画出一个圆了。现在要画在三维坐标下,所以我们只需要增加一个固定x0x0坐标,就可以画出圆心在(x0,y0,z0)(x0,y0,z0),半径为rr,平行于的圆了。为了简化一点,我们把球心坐标定为(0,0,0)(0,0,0), 在xx轴方向上画出等间距的若干圆,并且使他们的r和x0满足三角关系
RR为球体半径,为到yozyoz的距离,r为圆的半径。
2.旋转
旋转用到了三维空间的几何变换,三维空间几何变换包括平移,旋转,缩放等操作,这里只用到了绕z轴旋转。旋转矩阵为
T=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪cos(θ)sin(θ)00−sin(θ)cos(θ)0000100001 ⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪T={cos(θ)−sin(θ)00sin(θ)cos(θ)0000100001 }
变换时左乘以变换矩阵
⎧⎩⎨⎪⎪⎪⎪⎪⎪x′y′z′1 ⎫⎭⎬⎪⎪⎪⎪⎪⎪=T⎧⎩⎨⎪⎪⎪⎪⎪⎪xyz1 ⎫⎭⎬⎪⎪⎪⎪⎪⎪{x′y′z′1 }=T{xyz1 }
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