足球顶点坐标的计算程序(Matlab)

                     

贡献者: addis

  • 本文处于草稿阶段。
预备知识 足球顶点坐标的计算
图
图 1:绘图结果,动画见这里

代码 1:body60.m
function [Pa,Pb,Pc,Pd,Pe,Pf,Pg,Ph,flat5,flat6]=body60(RorHorL,draw)

%生成平面上的五边形
R=1/2/sin(36/180*pi);
Pa=zeros(5,3); 
temp=linspace(pi/2,18/180*pi+2*pi,5);
Pa(:,1)=R*cos(temp)';
Pa(:,2)=R*sin(temp)';

%计算出第二层五个点
Pb(5,:)=P32P(Pa([1 5 4],:));
Pb(1,:)=P32P(Pa([2 1 5],:));
Pb(2,:)=P32P(Pa([3 2 1],:));
Pb(3,:)=P32P(Pa([4 3 2],:));
Pb(4,:)=P32P(Pa([5 4 3],:));

%仅用补全多边形的方法,就可以生成剩下所有的点

%第1层6边形
[Pc(9,:),Pc(10,:)]=hexagon([Pa([1 5],:); Pb(5,:)]);
[Pc(1,:),Pc(2,:)]=hexagon([Pa([2 1],:); Pb(1,:)]);
[Pc(3,:),Pc(4,:)]=hexagon([Pa([3 2],:); Pb(2,:)]);
[Pc(5,:),Pc(6,:)]=hexagon([Pa([4 3],:); Pb(3,:)]);
[Pc(7,:),Pc(8,:)]=hexagon([Pa([5 4],:); Pb(4,:)]);

%第2层5边形
[Pd(9,:),Pd(10,:)]=pentagon([Pc(1,:); Pb(1,:); Pc(10,:)]);
[Pd(1,:),Pd(2,:)]=pentagon([Pc(3,:); Pb(2,:); Pc(2,:)]);
[Pd(3,:),Pd(4,:)]=pentagon([Pc(5,:); Pb(3,:); Pc(4,:)]);
[Pd(5,:),Pd(6,:)]=pentagon([Pc(7,:); Pb(4,:); Pc(6,:)]);
[Pd(7,:),Pd(8,:)]=pentagon([Pc(9,:); Pb(5,:); Pc(8,:)]);
%-------------------------------------------------球心
%第2层6边形
[Pe(9,:),Pe(10,:)]=hexagon([Pc([10 9],:);Pd(8,:)]);
[Pe(1,:),Pe(2,:)]=hexagon([Pc([2 1],:);Pd(10,:)]);
[Pe(3,:),Pe(4,:)]=hexagon([Pc([4 3],:);Pd(2,:)]);
[Pe(5,:),Pe(6,:)]=hexagon([Pc([6 5],:);Pd(4,:)]);
[Pe(7,:),Pe(8,:)]=hexagon([Pc([8 7],:);Pd(6,:)]);

%第2层6边形
[Pf(10,:),Pf(1,:)]=hexagon([Pd([10 9],:);Pe(10,:)]);
[Pf(2,:),Pf(3,:)]=hexagon([Pd([2 1],:);Pe(2,:)]);
[Pf(4,:),Pf(5,:)]=hexagon([Pd([4 3],:);Pe(4,:)]);
[Pf(6,:),Pf(7,:)]=hexagon([Pd([6 5],:);Pe(6,:)]);
[Pf(8,:),Pf(9,:)]=hexagon([Pd([8 7],:);Pe(8,:)]);

%第3层5边形
Pg(5,:)=pentagon([Pe(10,:);Pe(9,:);Pf(9,:)]);
Pg(1,:)=pentagon([Pe([2 1],:);Pf(1,:)]);
Pg(2,:)=pentagon([Pe([4 3],:);Pf(3,:)]);
Pg(3,:)=pentagon([Pe([6 5],:);Pf(5,:)]);
Pg(4,:)=pentagon([Pe([8 7],:);Pf(7,:)]);

%第3层6边形
Ph(5,:)=hexagon([Pf([1 10],:);Pg(5,:)]);
Ph(1,:)=hexagon([Pf([3 2],:);Pg(1,:)]);
Ph(2,:)=hexagon([Pf([5 4],:);Pg(2,:)]);
Ph(3,:)=hexagon([Pf([7 6],:);Pg(3,:)]);
Ph(4,:)=hexagon([Pf([9 8],:);Pg(4,:)]);

%使球心落在原点
H=Ph(1,end)/2;
Pa(:,3)=Pa(:,3)-H; Pb(:,3)=Pb(:,3)-H;   Pc(:,3)=Pc(:,3)-H; Pd(:,3)=Pd(:,3)-H;
Pe(:,3)=Pe(:,3)-H; Pf(:,3)=Pf(:,3)-H;   Pg(:,3)=Pg(:,3)-H; Ph(:,3)=Ph(:,3)-H; 

if RorHorL=='R'
    R=sqrt(1/4/sin(36/180*pi)^2+H^2);
    Pa=Pa/R; Pb=Pb/R; Pc=Pc/R; Pd=Pd/R; 
    Pe=Pe/R; Pf=Pf/R; Pg=Pg/R; Ph=Ph/R; 
elseif RorHorL=='H'
    Pa=Pa/H; Pb=Pb/H; Pc=Pc/H; Pd=Pd/H; 
    Pe=Pe/H; Pf=Pf/H; Pg=Pg/H; Ph=Ph/H; 
% RorHorL=='L' 无需操作
end


%12个正5边形(从下到上)
flat5(:,:,12)=Ph;
flat5(:,:,1)=Pa;
%第2层5边形
flat5(:,:,2)=[Pb(1,:);Pc(1,:);Pd(10,:);Pd(9,:);Pc(10,:)];
flat5(:,:,3)=[Pb(2,:);Pc(3,:);Pd(2,:);Pd(1,:);Pc(2,:)];
flat5(:,:,4)=[Pb(3,:);Pc(5,:);Pd(4,:);Pd(3,:);Pc(4,:)];
flat5(:,:,5)=[Pb(4,:);Pc(7,:);Pd(6,:);Pd(5,:);Pc(6,:)];
flat5(:,:,6)=[Pb(5,:);Pc(9,:);Pd(8,:);Pd(7,:);Pc(8,:)];
%----------------------------------------------------
%第3层5边形
flat5(:,:,7)=[Pg(1,:);Pf(2,:);Pe(2,:);Pe(1,:);Pf(1,:)];
flat5(:,:,8)=[Pg(2,:);Pf(4,:);Pe(4,:);Pe(3,:);Pf(3,:)];
flat5(:,:,9)=[Pg(3,:);Pf(6,:);Pe(6,:);Pe(5,:);Pf(5,:)];
flat5(:,:,10)=[Pg(4,:);Pf(8,:);Pe(8,:);Pe(7,:);Pf(7,:)];
flat5(:,:,11)=[Pg(5,:);Pf(10,:);Pe(10,:);Pe(9,:);Pf(9,:)];


%20个正六边形
%第1层6边形
flat6(:,:,1)=[Pa([2 1],:);Pb(1,:);Pc([1 2],:);Pb(2,:)];
flat6(:,:,2)=[Pa([3 2],:);Pb(2,:);Pc([3 4],:);Pb(3,:)];
flat6(:,:,3)=[Pa([4 3],:);Pb(3,:);Pc([5 6],:);Pb(4,:)];
flat6(:,:,4)=[Pa([5 4],:);Pb(4,:);Pc([7 8],:);Pb(5,:)];
flat6(:,:,5)=[Pa([1 5],:);Pb(5,:);Pc([9 10],:);Pb(1,:)];
%第2层6边形
flat6(:,:,6)=[Pc([2 1],:);Pd(10,:);Pe([1 2],:);Pd(1,:)];
flat6(:,:,7)=[Pc([4 3],:);Pd(2,:);Pe([3 4],:);Pd(3,:)];
flat6(:,:,8)=[Pc([6 5],:);Pd(4,:);Pe([5 6],:);Pd(5,:)];
flat6(:,:,9)=[Pc([8 7],:);Pd(6,:);Pe([7 8],:);Pd(7,:)];
flat6(:,:,10)=[Pc([10 9],:);Pd(8,:);Pe([9 10],:);Pd(9,:)];
%-------------------------------------------------
%第3层6边形
flat6(:,:,11)=[Pd([2 1],:);Pe(2,:);Pf([2 3],:);Pe(3,:)];
flat6(:,:,12)=[Pd([4 3],:);Pe(4,:);Pf([4 5],:);Pe(5,:)];
flat6(:,:,13)=[Pd([6 5],:);Pe(6,:);Pf([6 7],:);Pe(7,:)];
flat6(:,:,14)=[Pd([8 7],:);Pe(8,:);Pf([8 9],:);Pe(9,:)];
flat6(:,:,15)=[Pd([10 9],:);Pe(10,:);Pf([10 1],:);Pe(1,:)];
%第4层6边形
flat6(:,:,16)=[Pf([3 2],:);Pg(1,:);Ph([1 2],:);Pg(2,:)];
flat6(:,:,17)=[Pf([5 4],:);Pg(2,:);Ph([2 3],:);Pg(3,:)];
flat6(:,:,18)=[Pf([7 6],:);Pg(3,:);Ph([3 4],:);Pg(4,:)];
flat6(:,:,19)=[Pf([9 8],:);Pg(4,:);Ph([4 5],:);Pg(5,:)];
flat6(:,:,20)=[Pf([1 10],:);Pg(5,:);Ph([5 1],:);Pg(1,:)];


%画图
if draw==1
    draw_football(flat5,flat6);
end

end

%已知五边形的3点,求第2点连出的线段的另一端的坐标
%size(P3)=[3,3];
function P=P32P(P3) %P3右手定则的法向向球外

v1=P3(2,:)-P3(1,:);
v2=P3(2,:)-P3(3,:);
C=1/2/cos(54/180*pi); S=sqrt(1-C^2);
v3=vunit(cross(v1,v2));
P=vunit(v1+v2)*C+P3(2,:)+v3*S;

end

%已知5边形的3点, 求出第4点和第5点
function [P4,P5]=pentagon(P3)

v1=P3(2,:)-P3(1,:); 
v2=P3(3,:)-P3(2,:);
C=cos(72/180*pi);
P4=P3(3,:)+v2*C*2-v1;
v3=P4-P3(3,:);
P5=P4+v3*C*2-v2;

end

%%已知6边形的3点, 求出第4,5,6点
function [P4,P5,P6]=hexagon(P3)
v1=P3(2,:)-P3(1,:); 
v2=P3(3,:)-P3(2,:);
P4=P3(3,:)+v2-v1;
v3=P4-P3(3,:);
P5=P4+v3-v2;
v4=P5-P4;
P6=P5+v4-v3;
end

   动画程序

代码 2:draw_football.m
%画出足球,flat5是所有的5边形,第n个5边形的第ii个点的坐标就是flat5(ii,:,n)
%flat6是所有6边形,类比flat5.

%如果输入vz和theta,画出静态的足球. 先绕z轴转动thetavz
%  , 再把轴转向vz方向; vz不为零即可.
%如果输入vz=Omega,theta=omega, 则z轴以Omega角速度旋转
% , 足球以角速度omega自转; 动画时间为T

%rec=1时, 在桌面生成录像

%生成视频的例子:
 % [Pa,Pb,Pc,Pd,Pe,Pf,Pg,Ph,flat5,flat6]=body60('R',0);
 % draw_football(flat5,flat6,pi/6,pi/3,5,1)

function mov=draw_football(flat5,flat6,vz,theta,T,rec) % 忽略错误
%设置播放帧率(可以是非整数)
f=20;
%f=7;%实时播放的频率

%判断模式, 初始化
if nargin==6 %avi模式, 生成avi视频
    flag='a'; 
    Omega=vz; %轴倾斜角速度
    omega=theta;%绕轴角速度
    Axis1=[0 0 1]; %轴
    kk_max=floor(f*T); %视频总帧数
    mov(1:kk_max)=struct('cdata', [], 'colormap', []); %视频矩阵
    
elseif nargin==5%movie模式, 动画演示或视频
    flag='m'; 
    Omega=vz; %轴倾斜角速度
    omega=theta;%绕轴角速度
    Axis1=[0 0 1]; %轴
    kk_max=floor(f*T); %视频总帧数
    
elseif nargin==4 %static模式, 旋转后的静态图像
    flag='s'; 
    kk_max=1; %视频总帧数
    Axis1=[0 0 1]; %轴
    
elseif nargin==2 %origin模式, 原始静态图像
    flag='o'; 
    kk_max=1; %视频总帧数
    Axis1=[0 0 1]; %轴
end

kk=0; %当前帧数
warning_mark=false;

%设置窗口
hf=figure;  
axis([-1.5 1.5 -1.5 1.5 -1.5 1.5]); 
 axis on;
view([26,38]); axis equal; grid on;
set(gca,'CameraViewAngleMode','manual');
input('调整窗口大小,按回车开始');
figure(hf);

%rect(1:2)是figure的左下角在电脑屏幕上的坐标, rect(3:4)是axis的右上角的
%刚好消除figure最外层的边框!(忽略掉窗口边界).
set(hf,'unit','pixels'); f_posi=get(hf,'position');
rect(1:2)=f_posi(1:2);
rect(3:4)=f_posi(1:2)+f_posi(3:4)-1;

time1=tic; %开始播放的时间
%播放循环, 一个循环播放一帧图像
while kk+1<=kk_max
    %转动足球所有坐标
    if flag=='m' || flag=='a'
        Axis=Axis1;
        %Axis绕y轴旋转得到Axis1
        Axis1=vturn(Axis,[0 1 0],Omega/f);
        %足球绕Axis旋转
        [flat5(:,1,:),flat5(:,2,:),flat5(:,3,:)]=...
            turn(flat5(:,1,:),flat5(:,2,:),flat5(:,3,:),Axis,omega/f);
        [flat6(:,1,:),flat6(:,2,:),flat6(:,3,:)]=...
            turn(flat6(:,1,:),flat6(:,2,:),flat6(:,3,:),Axis,omega/f);
        %%足球随着Axis转到Axis1
        [flat5(:,1,:),flat5(:,2,:),flat5(:,3,:)]=...
            turn(flat5(:,1,:),flat5(:,2,:),flat5(:,3,:),Axis,Axis1);
        [flat6(:,1,:),flat6(:,2,:),flat6(:,3,:)]=...
            turn(flat6(:,1,:),flat6(:,2,:),flat6(:,3,:),Axis,Axis1);
    elseif flag=='s'
        [flat5(:,1,:),flat5(:,2,:),flat5(:,3,:)]=...
            turn(flat5(:,1,:),flat5(:,2,:),flat5(:,3,:),[0 0 1],theta);
        [flat5(:,1,:),flat5(:,2,:),flat5(:,3,:)]=...
            turn(flat5(:,1,:),flat5(:,2,:),flat5(:,3,:),[0 0 1],vz);
    end
    
    %画图
    cla; hold on; %清除足球,坐标轴不变
    for ii=1:size(flat5,3);
        temp=flat5(:,:,ii);
        Fill3(temp,'k','LineStyle','none');
    end

    for ii=1:size(flat6,3);
        temp=flat6(:,:,ii);
        Fill3(temp,'w','FaceAlpha',0.85,'LineWidth',2);
    end
    light
    kk=kk+1; %当前帧数
    
    %播放控制
    if flag=='m' %动画模式
        now=toc(time1);
        temp=kk/f-now; %该周期中画完图后余下的时间
        if temp>0
            pause(temp);%补足该帧剩下的时间
        else
            warning_mark=true; %如果画图太慢, 在程序结束后警告;    
        end
        
    elseif  flag=='a' %录像模式
        pause(0.05); %等待作图
        temp=printScreen; %截屏
        %选取axis所在的区域rect
        Size=size(temp);%屏幕尺寸
        temp=temp(Size(1)-rect(4)+1:Size(1)-rect(2)+1, rect(1):rect(3),:);
        mov(kk).cdata=temp;
    end
    
end

%播放结束
% if  flag=='a' %制作电影;
%     frame=mov(1:kk);
%     cf; movie2avi(frame,'rotating_football','compression',....
%                                   'Cinepak','fps',20,'quality',100); 
% end

if warning_mark
    warning('帧数太高, 不能播放动画, 在line11设置');
end

if flag=='a'
    cf; movie2avi(mov,'rotating_football','compression','None','fps',f);
end

end


致读者: 小时百科一直以来坚持所有内容免费无广告,这导致我们处于严重的亏损状态。 长此以往很可能会最终导致我们不得不选择大量广告以及内容付费等。 因此,我们请求广大读者热心打赏 ,使网站得以健康发展。 如果看到这条信息的每位读者能慷慨打赏 20 元,我们一周就能脱离亏损, 并在接下来的一年里向所有读者继续免费提供优质内容。 但遗憾的是只有不到 1% 的读者愿意捐款, 他们的付出帮助了 99% 的读者免费获取知识, 我们在此表示感谢。

                     

友情链接: 超理论坛 | ©小时科技 保留一切权利