转载自:http://blog.sina.com.cn/s/blog_6f83fdb401018k9s.html
因为要准备数模,所以要备一些Matlab的干货
Matlab画足球
科普:足球表面是由12个正五边形和20个正六边形构成,每个正五边形相邻的是5个正六边形,共有60个顶点,90条棱,这些数据可以根据欧拉定理计算得出,不是这里要说明的重点。
思路:先计算出60个顶点的三维坐标,然后调用matlab的绘图函数画图。
至于顶点坐标的计算属于数学问题,通过空间对称和旋转,可以计算得出。不是这里要说明的重点,也可以参考链接文档《空间多面体》说明的方法计算:这里不再赘述。
在matlab中有一个得到足球顶点坐标的函数:bucky(),参看matlab帮助关于该函数的说明如下:
bucky
有了顶点坐标,接下来就是绘制足球面的问题了,由于每条棱长都相等,因此可以先计算出一条棱长,然后把所有距离等于棱长的两点连线,就画出了每个面的正多边形。这步可能还有其他更简单的方法,留待后续有时间再思考。
还有最后一步,就是给五边形和六边形涂色,五边形是黑色,六边形是白色,由于受每个面的外接球的那一部分影响,至于涂色的方法暂未想好,先上代码吧:仅供参考
clear
clc
%计算各顶点坐标
[B,football_pos] = bucky();
%绘半透明球体
[x,y,z]=sphere(30);
surf(x,y,z,'facecolor',[1 10],'edgecolor','none','facealpha',0.7);
axis equal
view(3,3)
hold on
%绘各顶点
plot3(football_pos(:,1),football_pos(:,2),football_pos(:,3),'*');
%计算棱长
Edge_Vector =football_pos(1,:)-football_pos(2,:);
Edge_Length = Edge_Vector * Edge_Vector';
Error = 0.0005;
%距离等于棱长的两点显然是棱,将两点连线
for i=1:length(football_pos)-1
for j=i+1:min(j+15,length(football_pos))
Vector = football_pos(i,:)-football_pos(j,:);
Length = Vector*Vector';
if abs(Length-Edge_Length)
x = [football_pos(i,1),football_pos(j,1)];
y = [football_pos(i,2),football_pos(j,2)];
z = [football_pos(i,3),football_pos(j,3)];
line(x,y,z)
end
end
end
效果图: