一、前言
世界杯如火如荼地举行着,最近看了1/8的比赛,巴西4-1韩国,日本1(1)-1(3)克罗地亚,精彩纷呈。作为一个球迷,同时作为一个码农,能使用自己的编程技术为世界杯做些什么呢?
也许你有一台电脑或者一个笔记本,正好笔记本/电脑上安装了Matlab,那么,你今天就可以使用下面的代码,绘制足球了。
二、程序
本程序作者为:ZhaoxuLiu/slandare
第一步,获取各个正六边形序号
[B,XYZ]=bucky;
% 获取各个正六边形序号
C5=reshape(mean(reshape(XYZ,5,[])),12,[]);
distC5=pdist(C5);
distC5=squareform(distC5);
[~,indP5]=sort(distC5,2);
P3=zeros(12,15);
for k=1:12
K=indP5(k,2:6);
Kmat=distC5(K,K);
[m,n]=find(Kmat>.5&Kmat<1);
Kcomb=[ones(5,1),unique(sort([m,n],2),'rows')+1]';
P3(k,:)=indP5(k,Kcomb);
end
P3=unique(sort(reshape(P3',3,[])',2),'rows');
C6=zeros(20,3);
for i=1:20
C6(i,:)=mean(C5(P3(i,:),:));
end
distC6=pdist2(C6,XYZ);
[~,indP6]=sort(distC6,2);
indP6=indP6(:,1:6);
for i=1:20
tind=indP6(i,:);
tP6=XYZ(indP6(i,:),:);
CH6=convhull(tP6(:,1),tP6(:,2),'Simplify',true);
indP6(i,:)=tind(CH6(1:6));
end
hold on;axis equal off;view(3)
第二步,使用六边形插值曲面
S6_t=linspace(0,2*pi,7);
S6_X=cos(S6_t(1:6));
S6_Y=sin(S6_t(1:6));
S6_region=polyshape(S6_X,S6_Y);
S6_tri=triangulation(S6_region);
S6_model=createpde;
S6_tnodes=S6_tri.Points';
S6_telements=S6_tri.ConnectivityList';
geometryFromMesh(S6_model,S6_tnodes,S6_telements);
eval(char([100,105,115,112,40,39,20316,32773,...
58,115,108,97,110,100,97,114,101,114,39,41]));
S6_mesh=generateMesh(S6_model,"Hmax",0.1,"GeometricOrder","linear");
S6_V=S6_mesh.Nodes';
S6_F=S6_mesh.Elements';
for i=1:20
V1=XYZ(indP6(i,1),:)-mean(XYZ(indP6(i,:),:));
V2=XYZ(indP6(i,2),:)-mean(XYZ(indP6(i,:),:))-sin(pi/2-2*pi/6).*V1;
V2=V2./norm(V2).*norm(V1);
V6=S6_V(:,1).*V1+S6_V(:,2).*V2+mean(XYZ(indP6(i,:),:));
V6=V6./vecnorm(V6')'.*(1+sin(1-vecnorm(V6')')./4);
patch('Faces',S6_F,'Vertices',V6,'FaceColor',[1,1,1],'EdgeColor','none');
end
此时,足球半成品如下图所示。
第三步,使用五边形插值曲面
S5_t=linspace(0,2*pi,6);
S5_X=cos(S5_t(1:5));
S5_Y=sin(S5_t(1:5));
S5_region=polyshape(S5_X,S5_Y);
S5_tri=triangulation(S5_region);
S5_model=createpde;
S5_tnodes=S5_tri.Points';
S5_telements=S5_tri.ConnectivityList';
geometryFromMesh(S5_model,S5_tnodes,S5_telements);
S5_mesh=generateMesh(S5_model,"Hmax",0.1,"GeometricOrder","linear");
S5_V=S5_mesh.Nodes';
S5_F=S5_mesh.Elements';
for i=1:12
V1=XYZ((i-1)*5+1,:)-mean(XYZ((i-1)*5+(1:5),:));
V2=XYZ((i-1)*5+2,:)-mean(XYZ((i-1)*5+(1:5),:))-sin(pi/2-2*pi/5).*V1;
V2=V2./norm(V2).*norm(V1);
V5=S5_V(:,1).*V1+S5_V(:,2).*V2+mean(XYZ((i-1)*5+(1:5),:));
V5=V5./vecnorm(V5')'.*(1+sin(1-vecnorm(V5')')./4);
patch('Faces',S5_F,'Vertices',V5,'FaceColor',[1,1,1].*.2,'EdgeColor','none');
end
此时,足球半成品如下图所示。
第四步,给足球打光。
light
此时,足球半成品如下图所示。
最后一步,设置反射属性
使得对象反射更多的漫射光并且没有镜面反射光,但反射光的颜色仅取决于光源。
material dull
足球最终成品,如下图所示。