利用Matlab实现绘制中秋山间秋月和皓月当空效果

2022-11-13 16:11:00 绘制 皓月当空 山间

中秋节还有三天就到了,中秋节啊,阖家团圆的日子,又有多少人去摆弄电脑甚至打开MATLAB?因此要发就现在!

绘制效果

月饼绘制,立体月饼绘制,月饼状统计图往年我都已经画过了,那么今年不妨从月亮下手,两个动态绘图奉上。

山间秋月

在好久之前看到童晶老师《python趣味创意编程》一书中有一山水绘制示例非常惊艳,但用了一些Python中有matlab中没有的函数,一时手痒就改了个MATLAB版:

function landScape
% python代码原作出处:童晶|《Python趣味创意编程》
% MATLAB代码改写:slandarer


% axes设置
ax=GCa;
ax.XTick=[];
ax.YTick=[];
ax.XLim=[0,800];
ax.YLim=[0,600];
ax.DataAspectRatio=[1 1 1];
hold(ax,'on');
% =========================================================================
% 颜色预定义,注意此处是hsv格式
cClouds=[330,25,100];  % 云的颜色
cSky=[220,50,50];      % 天空的颜色
cFurther=[230,25,90];  % 远山的颜色
cCloser=[210,70,10];   % 近山的颜色
% =========================================================================
% 绘图函数调用
ax.Color=hsv2rgb(cFurther./[360,100,100]); % 背景为远山的颜色
drawSky(cSky,cFurther)                     % 画出天空颜色渐变效果 
drawClouds(cClouds)                        % 画出彩色云朵效果
drawMountains(cFurther,cCloser)            % 画出山脉效果
% =========================================================================
% 功能函数:
% -------------------------------------------------------------------------
% 渐变背景生成函数
    function drawSky(colSky,colFurther)
        % 颜色由hsv转rgb
        colSky=hsv2rgb(colSky./[360,100,100]);
        colFurther=hsv2rgb(colFurther./[360,100,100]);
        
        %构建渐变色网格
        [XMesh,YMesh]=meshgrid(1:800,301:600);
        ZMesh=zeros(size(XMesh));
        CMesh=vColORMat([800,300],[colFurther;colSky]);
        surf(XMesh,YMesh,ZMesh,'CData',CMesh,'EdgeColor','none');
    end
% -------------------------------------------------------------------------
% 云绘制函数
    function drawClouds(colClouds)
        colClouds=hsv2rgb(colClouds./[360,100,100]);

        % 随机噪声生成
        [X,Y]=meshgrid(linspace(0,1,500));
        CLX=(-cos(X.*2.*pi)+1).^.2;
        CLY=(-cos(Y.*2.*pi)+1).^.2;
        r=(X-.5).^2+(Y-.5).^2;
        alp=abs(ifftn(exp(3i*rand(500))./r.^.8)).*(CLX.*CLY);
        alp=alp./max(alp,[],'all');
        
        CMesh=zeros([size(alp),3]);
        CMesh(:,:,1)=colClouds(1);
        CMesh(:,:,2)=colClouds(2);
        CMesh(:,:,3)=colClouds(3);
        
        % 越向下、云越透明
        dy=(1:500)./500.*0.8+0.2;
        image([0,800],[350,600],CMesh,'AlphaData',alp.*(dy'));
    end
% -------------------------------------------------------------------------
% 山峰绘制函数
    function drawMountains(colFurther,colCloser)
        [X,Y]=meshgrid(linspace(0,1,800));
        CLX=(-cos(X.*2.*pi)+1).^.2;
        CLY=(-cos(Y.*2.*pi)+1).^.2;
        r=(X-.5).^2+(Y-.5).^2;
        % 8层山
        for i=1:8
            % 每次都生成一次二维随机噪声,并取其中一行的数据
            h=abs(ifftn(exp(5i*rand(800))./r.^1.05)).*(CLX.*CLY).*10;
            nh=(8-i)*30+h(400,:);
            if i==1,nh=nh.*.8;end
            hm=ceil(max(nh));
            CMesh=zeros([hm,800,3]);
            
            % 颜色矩阵构造,
            tcol=colFurther+(colCloser-colFurther)./8.*(i);
            tcol=hsv2rgb(tcol./[360,100,100]);
            CMesh(:,:,1)=tcol(1);
            CMesh(:,:,2)=tcol(2);
            CMesh(:,:,3)=tcol(3);
            
            % 用nan数值框出山的轮廓
            alp=ones(hm,800);
            alp((1:hm)'>nh)=nan;
            
            % 绘制山峰
            image([-50,850],[0,hm],CMesh,'AlphaData',alp.*0.98);        
        end
    end
% =========================================================================
% 一个线性插值的渐变图生成函数
    function colorMat=vColorMat(matSize,colorList)
        yList=((0:(matSize(2)-1))./(matSize(2)-1))';
        xList=ones(1,matSize(1));
        % 线性插值
        colorMat(:,:,1)=(colorList(1,1)+yList.*(colorList(2,1)-colorList(1,1)))*xList;
        colorMat(:,:,2)=(colorList(1,2)+yList.*(colorList(2,2)-colorList(1,2)))*xList;
        colorMat(:,:,3)=(colorList(1,3)+yList.*(colorList(2,3)-colorList(1,3)))*xList;
    end
end

本人将代码再次略作改编,贴合中秋主题,又写了山间秋月的代码,能够动态展示变换的云雾以及慢慢变圆的月亮:

function autumoon_2
% @author : slandarer
% gzh  : slandarer随笔

% axes设置
ax=gca;
ax.XTick=[];
ax.YTick=[];
ax.XLim=[0,800];
ax.YLim=[0,600];
ax.DataAspectRatio=[1 1 1];
hold(ax,'on');
% =========================================================================
% 颜色预定义,注意此处是hsv格式
cFurther=[225,35,70];  % 远山的颜色
cCloser=[210,70,10];   % 近山的颜色
cClouds=[250 26 43];   % 云的颜色
cSky=[215 100 18];     % 天空的颜色

% 月亮颜色格式为rgb
cMoon=[253,252,222]./255;
% =========================================================================
% 绘图函数调用
ax.Color=hsv2rgb(cFurther./[360,100,100]); % 背景为远山的颜色
drawSky(cSky,cFurther)                     % 画出天空颜色渐变效果 

% 基础绘制月亮
t1=linspace(-pi/2,pi/2,100);
t2=linspace(pi/2,3*pi/2,100);
X1=cos(t1).*35;Y1=sin(t1).*35;
X2=cos(t2).*35;Y2=sin(t2).*35;
moonHdl=fill([X1,X2]+600,[Y1,Y2]+500,cMoon,'EdgeColor','none');

% 画出彩色云朵效果                       
cloudsCMesh=getCloudsCMesh(cClouds);
cloudsAlpha1=getCloudsAlp();
cloudsAlpha2=getCloudsAlp();
cloudHdl=image([0,800],[250,600],cloudsCMesh,'AlphaData',cloudsAlpha1);


drawMountains(cFurther,cCloser)            % 画出山脉效果
% 随着时间变化月亮逐渐变圆
k=linspace(-1,1,100);
for n=1:length(k)
    tX2=X2.*k(n);
    moonHdl.XData=[X1,tX2]+600;
    cloudHdl.AlphaData=cloudsAlpha1+(cloudsAlpha2-cloudsAlpha1).*n./length(k);
    pause(.1)
end
% =========================================================================
% 功能函数:
% -------------------------------------------------------------------------
% 渐变背景生成函数
    function drawSky(colSky,colFurther)
        % 颜色由hsv转rgb
        colSky=hsv2rgb(colSky./[360,100,100]);
        colFurther=hsv2rgb(colFurther./[360,100,100]);
        
        %构建渐变色网格
        [XMesh,YMesh]=meshgrid(1:800,301:600);
        ZMesh=zeros(size(XMesh));
        CMesh=vColorMat([800,300],[colFurther;colSky]);
        surf(XMesh,YMesh,ZMesh,'CData',CMesh,'EdgeColor','none');
    end
% -------------------------------------------------------------------------
% 云绘制函数
    function CMesh=getCloudsCMesh(colClouds)
        colClouds=hsv2rgb(colClouds./[360,100,100]);
        CMesh=zeros([500,500,3]);
        CMesh(:,:,1)=colClouds(1);
        CMesh(:,:,2)=colClouds(2);
        CMesh(:,:,3)=colClouds(3);
    end
    function Alpha=getCloudsAlp(~,~)
        % 随机噪声生成
        [X,Y]=meshgrid(linspace(0,1,500));
        CLX=(-cos(X.*2.*pi)+1).^.2;
        CLY=(-cos(Y.*2.*pi)+1).^.2;
        r=(X-.5).^2+(Y-.5).^2;
        alp=abs(ifftn(exp(3i*rand(500))./r.^.8)).*(CLX.*CLY);
        alp=alp./max(alp,[],'all');
        dy=(1:500)./500.*0.8+0.2;
        Alpha=alp.*(dy');
    end
% -------------------------------------------------------------------------
% 山峰绘制函数
    function drawMountains(colFurther,colCloser)
        [X,Y]=meshgrid(linspace(0,1,800));
        CLX=(-cos(X.*2.*pi)+1).^.2;
        CLY=(-cos(Y.*2.*pi)+1).^.2;
        r=(X-.5).^2+(Y-.5).^2;
        % 8层山
        for i=1:8
            % 每次都生成一次二维随机噪声,并取其中一行的数据
            h=abs(ifftn(exp(5i*rand(800))./r.^1.05)).*(CLX.*CLY).*10;
            nh=(8-i)*30+h(400,:);
            if i==1,nh=nh.*.8;end
            hm=ceil(max(nh));
            CMesh=zeros([hm,800,3]);
            
            % 颜色矩阵构造
            tcol=colFurther+(colCloser-colFurther)./8.*(i);
            tcol=hsv2rgb(tcol./[360,100,100]);
            CMesh(:,:,1)=tcol(1);
            CMesh(:,:,2)=tcol(2);
            CMesh(:,:,3)=tcol(3);
            
            % 用nan数值框出山的轮廓
            alp=ones(hm,800);
            alp((1:hm)'>nh)=nan;
            
            % 绘制山峰
            image([-50,850],[0,hm],CMesh,'AlphaData',alp.*0.98);        
        end
    end
% =========================================================================
% 一个线性插值的渐变图生成函数
    function colorMat=vColorMat(matSize,colorList)
        yList=((0:(matSize(2)-1))./(matSize(2)-1))';
        xList=ones(1,matSize(1));
        % 线性插值
        colorMat(:,:,1)=(colorList(1,1)+yList.*(colorList(2,1)-colorList(1,1)))*xList;
        colorMat(:,:,2)=(colorList(1,2)+yList.*(colorList(2,2)-colorList(1,2)))*xList;
        colorMat(:,:,3)=(colorList(1,3)+yList.*(colorList(2,3)-colorList(1,3)))*xList;
    end
end

静态图:

皓月当空

需要下载mapping toolbox或者直接使用文末压缩包内的moonalb20c.mat文件,该文件是真实月球表面数据:

% @author : slandarer
% gzh  : slandarer随笔

% 数据读取
load moonalb20c.mat

[X,Y,Z0]=sphere(30);
surf(X,Y,Z0,'FaceColor','texturemap','CData',moonalb20c,'EdgeColor','none','FaceAlpha',.5)

% 调色
colormap gray
fig=gcf;
fig.Color=[0,0,0];
 
% 旋转 
for i=0:(2*pi/200):(4*pi)
    campos([cos(i),sin(i),.5])
    axis off vis3D
    pause(.1)
    drawnow
end

全部文件获取:

链接:https://pan.baidu.com/s/162CUlO9-33SiNx-7ZemVmA

提取码:h71f

到此这篇关于利用Matlab实现绘制中秋山间秋月和皓月当空效果的文章就介绍到这了,更多相关Matlab中秋内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关文章