利用Matlab實現(xiàn)繪制中秋山間秋月和皓月當空效果
中秋節(jié)還有三天就到了,中秋節(jié)啊,闔家團圓的日子,又有多少人去擺弄電腦甚至打開MATLAB?因此要發(fā)就現(xiàn)在!
繪制效果


月餅繪制,立體月餅繪制,月餅狀統(tǒng)計圖往年我都已經(jīng)畫過了,那么今年不妨從月亮下手,兩個動態(tài)繪圖奉上。
山間秋月
在好久之前看到童晶老師《Python趣味創(chuàng)意編程》一書中有一山水繪制示例非常驚艷,但用了一些python中有matlab中沒有的函數(shù),一時手癢就改了個MATLAB版:
function landScape
% python代碼原作出處:童晶|《Python趣味創(chuàng)意編程》
% 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]; % 近山的顏色
% =========================================================================
% 繪圖函數(shù)調用
ax.Color=hsv2rgb(cFurther./[360,100,100]); % 背景為遠山的顏色
drawSky(cSky,cFurther) % 畫出天空顏色漸變效果
drawClouds(cClouds) % 畫出彩色云朵效果
drawMountains(cFurther,cCloser) % 畫出山脈效果
% =========================================================================
% 功能函數(shù):
% -------------------------------------------------------------------------
% 漸變背景生成函數(shù)
function drawSky(colSky,colFurther)
% 顏色由hsv轉rgb
colSky=hsv2rgb(colSky./[360,100,100]);
colFurther=hsv2rgb(colFurther./[360,100,100]);
%構建漸變色網(wǎng)格
[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
% -------------------------------------------------------------------------
% 云繪制函數(shù)
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
% -------------------------------------------------------------------------
% 山峰繪制函數(shù)
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
% 每次都生成一次二維隨機噪聲,并取其中一行的數(shù)據(jù)
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數(shù)值框出山的輪廓
alp=ones(hm,800);
alp((1:hm)'>nh)=nan;
% 繪制山峰
image([-50,850],[0,hm],CMesh,'AlphaData',alp.*0.98);
end
end
% =========================================================================
% 一個線性插值的漸變圖生成函數(shù)
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


本人將代碼再次略作改編,貼合中秋主題,又寫了山間秋月的代碼,能夠動態(tài)展示變換的云霧以及慢慢變圓的月亮:
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;
% =========================================================================
% 繪圖函數(shù)調用
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
% =========================================================================
% 功能函數(shù):
% -------------------------------------------------------------------------
% 漸變背景生成函數(shù)
function drawSky(colSky,colFurther)
% 顏色由hsv轉rgb
colSky=hsv2rgb(colSky./[360,100,100]);
colFurther=hsv2rgb(colFurther./[360,100,100]);
%構建漸變色網(wǎng)格
[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
% -------------------------------------------------------------------------
% 云繪制函數(shù)
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
% -------------------------------------------------------------------------
% 山峰繪制函數(shù)
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
% 每次都生成一次二維隨機噪聲,并取其中一行的數(shù)據(jù)
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數(shù)值框出山的輪廓
alp=ones(hm,800);
alp((1:hm)'>nh)=nan;
% 繪制山峰
image([-50,850],[0,hm],CMesh,'AlphaData',alp.*0.98);
end
end
% =========================================================================
% 一個線性插值的漸變圖生成函數(shù)
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

靜態(tài)圖:


皓月當空
需要下載mapping toolbox或者直接使用文末壓縮包內的moonalb20c.mat文件,該文件是真實月球表面數(shù)據(jù):
% @author : slandarer
% gzh : slandarer隨筆
% 數(shù)據(jù)讀取
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

全部文件獲?。?/p>
鏈接:https://pan.baidu.com/s/162CUlO9-33SiNx-7ZemVmA
提取碼:h71f
到此這篇關于利用Matlab實現(xiàn)繪制中秋山間秋月和皓月當空效果的文章就介紹到這了,更多相關Matlab中秋內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
你只用do-while來實現(xiàn)循環(huán)?太浪費了
這篇文章主要介紹了你只用do-while來實現(xiàn)循環(huán)?太浪費了,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12

