在这里插入图片描述
鼠标在叶子或花朵处滑动就可使其收缩。
完整代码:

function mimose
t1=0:pi/100:pi+2*pi/100;
y=5*abs(sin(t1).^(1/2));
y(t1>pi)=-y(t1>pi);

t1=t1.*cos(pi/9)-y.*sin(pi/9);
y=t1.*sin(pi/9)+y.*cos(pi/9);
T=[];
Y=[];
for i=1:20
    T=[T,(i-1)*(pi+2*pi/100)+t1];
    Y=[Y,y];   
end
L=length(T);
t2=linspace(pi/8,pi-2*pi/5,L);
Y=Y.*sin(t2);

X=T.*cos(pi)-Y.*sin(pi);
Y=T.*sin(pi)+Y.*cos(pi);
X=X-min(X);

X=X.*0.8;
Y=Y.*1.5;


fig=figure('units','pixels',...
        'position',[500 100 500 500],...
        'Numbertitle','off',...
        'Color',[1 1 1],...
        'resize','off',...
        'visible','on',...
        'name','mimose',...
         'menubar','none');

ax=axes('Units','pixels',...
        'parent',fig,...  
        'Color',[0.2667    0.4039    0.2745],...
        'Position',[0 0 500 500],...
        'XLim',[0 100],...
        'YLim',[0 100],...
        'XColor',[1 1 1],...
        'YColor',[1 1 1]);
hold(ax,'on')
%plot(ax,X+20,Y+50)

drawBranch([20,0],[50,10])
drawBranch([20,0],[35,12])
drawBranch([0,0],[15,45])
drawBranch([4,0],[0,20])

leaf.l1=drawLeaf([50,10]+1.*[cos(pi/1.7),sin(pi/1.7)],pi/1.7,X,Y,0.8,1);
leaf.l2=drawLeaf([50,10]+1.*[cos(-pi/8),sin(-pi/8)],-pi/8,X,Y,0.8,1);
leaf.l3=drawLeaf([50,10]+1.*[cos(pi/12),sin(pi/12)],pi/12,X,Y,1,1);
leaf.l4=drawLeaf([50,10]+1.*[cos(pi/3),sin(pi/3)],pi/3,X,Y,1,1);
leaf.l5=drawLeaf([0,45]+1.*[cos(pi/3),sin(pi/3)],pi/3,X,Y,1,1);
leaf.l6=drawLeaf([0,30]+1.*[cos(pi/5),sin(pi/5)],pi/5,X,Y,1,1);

flower.fl1=drawFlower([35,12]);
flower.fl2=drawFlower([20,5]);

fps=25;
mitimer=timer('ExecutionMode', 'fixedRate', 'Period',1/fps, 'TimerFcn', @miMove);
start(mitimer)
    function miMove(~,~)
        for ii=1:6
            if leaf.(['l',num2str(ii)]).ratio<1
                leaf.(['l',num2str(ii)]).ratio=leaf.(['l',num2str(ii)]).ratio+0.05;
            end
            resetH(leaf.(['l',num2str(ii)]),X,Y);
        end
        for ii=1:2
            if flower.(['fl',num2str(ii)]).ratio<1
                flower.(['fl',num2str(ii)]).ratio=flower.(['fl',num2str(ii)]).ratio+0.05;
            end
            resetL(flower.(['fl',num2str(ii)]));
        end
    end
set(gcf,'WindowButtonMotionFcn',@whilemovefcn)  

    function whilemovefcn(~,~)
        xy=get(gca,'CurrentPoint');
        xw=xy(1,1);yw=xy(1,2);
        pos=[xw,yw];
        for ii=1:6
            LF=leaf.(['l',num2str(ii)]);
            if closeLeaf(LF.pos1,LF.pos2,pos)
                if leaf.(['l',num2str(ii)]).ratio>0.2
                    leaf.(['l',num2str(ii)]).ratio=leaf.(['l',num2str(ii)]).ratio-0.2;
                end
            end
            
        end
        for ii=1:2
            FL=flower.(['fl',num2str(ii)]);
            if closeFlower(FL.pos,pos)
                if flower.(['fl',num2str(ii)]).ratio>0.6
                    flower.(['fl',num2str(ii)]).ratio=flower.(['fl',num2str(ii)]).ratio-0.2;
                end
            end
        end
    end

    function bool=closeLeaf(pos1,pos2,pos3)
        pL=pos1+(pos2-pos1).*0.1;
        pR=pos1+(pos2-pos1).*0.9;
        lTotal=norm(pL-pos3)+norm(pR-pos3);
        bool=lTotal<=norm(pos1-pos2); 
    end

    function bool=closeFlower(pos1,pos2)
       bool=norm(pos1-pos2)<=5;
    end

    function resetH(lf,X,Y)
        X=X.*lf.Len;
        Y=Y.*lf.h.*lf.ratio;
        xl1=X.*cos(lf.alf)-Y.*sin(lf.alf)+lf.pos1(1);
        yl1=X.*sin(lf.alf)+Y.*cos(lf.alf)+lf.pos1(2);
        xl2=X.*cos(lf.alf)+Y.*sin(lf.alf)+lf.pos1(1);
        yl2=X.*sin(lf.alf)-Y.*cos(lf.alf)+lf.pos1(2);
        XL=[xl1,xl2(end:-1:1)];
        YL=[yl1,yl2(end:-1:1)];
        set(lf.LHdl,'XData',XL,'YData',YL);  
    end

    function resetL(fl)
        xf=fl.x.*fl.ratio+fl.pos(1);
        yf=fl.y.*fl.ratio+fl.pos(2);
        xxf(2:2:2*length(xf))=xf;
        yyf(2:2:2*length(yf))=yf;
        xxf(1:2:2*length(xf))=fl.pos(1);
        yyf(1:2:2*length(yf))=fl.pos(2);
        %set(fl.plHdl,'XData',xxf,'YData',yyf);
        set(fl.scHdl,'XData',xf,'YData',yf);
        set(fl.plHdl,'XData',xxf,'YData',yyf); 
    end



    function fl=drawFlower(pos)
        theta=rand([1,120]).*2.*pi;
        r=rand([1,120]).*3+5;
        xf=r.*cos(theta)+pos(1);
        yf=r.*sin(theta)+pos(2);
        xxf(2:2:2*length(xf))=xf;
        yyf(2:2:2*length(yf))=yf;
        xxf(1:2:2*length(xf))=pos(1);
        yyf(1:2:2*length(yf))=pos(2);
        plHdl=plot(ax,xxf,yyf,'Color',[0.7608 0.4863 0.7216],'LineWidth',1);
        scHdl=scatter(ax,xf,yf,3,'filled','CData',[0.9569 0.9804 0.9333]);
        
        fl.x=xf-pos(1);
        fl.y=yf-pos(2);
        fl.pos=pos;
        fl.scHdl=scHdl;
        fl.plHdl=plHdl;
        fl.ratio=1;
        
        
        theta2=rand([1,80]).*2.*pi;
        r2=rand([1,80]).*1+3;
        xf2=r2.*cos(theta2)+pos(1);
        yf2=r2.*sin(theta2)+pos(2);
        xxf2=[ones([1,length(xf2)]).*pos(1);xf2];
        yyf2=[ones([1,length(yf2)]).*pos(2);yf2];
        
        plot(ax,xxf2,yyf2,'Color',[0.7804 0.6078 0.5020],'LineWidth',1)
        
        
    end

    function drawBranch(pos1,pos2)
        dir=(pos2-pos1)./norm(pos2-pos1);
        len=norm(pos2-pos1);
        xb=[0 1 1 0].*len;
        yb=[len.*0.02,len.*0.012,-len.*0.012,-len.*0.02];
       
        xxb=xb.*dir(1)-yb.*dir(2)+pos1(1);
        yyb=xb.*dir(2)+yb.*dir(1)+pos1(2);
        fill(ax,xxb,yyb,[0.8157 0.6431 0.6078],'EdgeColor',[0.6157 0.5529 0.4510],'LineWidth',1.5)
    end

    function lf=drawLeaf(pos,alf,X,Y,l,h)
        X=X.*l;
        Y=Y.*h;
        xl1=X.*cos(alf)-Y.*sin(alf)+pos(1);
        yl1=X.*sin(alf)+Y.*cos(alf)+pos(2);
        xl2=X.*cos(alf)+Y.*sin(alf)+pos(1);
        yl2=X.*sin(alf)-Y.*cos(alf)+pos(2);
        XL=[xl1,xl2(end:-1:1)];
        YL=[yl1,yl2(end:-1:1)];
        lf.LHdl=fill(XL,YL,[0.4980 0.7216 0.3176]);
        lf.pos1=pos;
        lf.pos2=[pos(1)+l*51*cos(alf),pos(2)+l*51*sin(alf)];
        lf.alf=alf;
        lf.Len=l;
        lf.h=h;
        lf.ratio=1;
        plot(ax,[pos(1),pos(1)+l*51*cos(alf)],[pos(2),pos(2)+l*51*sin(alf)],'Color',[0.6627 0.6980 0.4431],'LineWidth',3);
    end




end

注释版本

function mimose
% @author:slandarer

% =========================================================================
% <构造含羞草叶子轮廓曲线>
% 大体是画一个一个压扁倾斜的半圆弧拼在一起
% 然后乘以一个类似弧形曲线让每片小叶子不一样长

% 计算一个压扁倾斜的半圆弧曲线
t1=0:pi/100:pi+2*pi/100;
y=5*abs(sin(t1).^(1/2));
y(t1>pi)=-y(t1>pi);
t1=t1.*cos(pi/9)-y.*sin(pi/9);
y=t1.*sin(pi/9)+y.*cos(pi/9);

% 将多个压扁倾斜的半圆弧曲线拼接
T=[];
Y=[];
for i=1:20
    T=[T,(i-1)*(pi+2*pi/100)+t1];
    Y=[Y,y];   
end

% 乘以一个类似弧形曲线让每片小叶子不一样长
L=length(T);
t2=linspace(pi/8,pi-2*pi/5,L);
Y=Y.*sin(t2);

% 旋转并调整比例
X=T.*cos(pi)-Y.*sin(pi);
Y=T.*sin(pi)+Y.*cos(pi);
X=X-min(X);
X=X.*0.8;
Y=Y.*1.5;


% 创建figure及axes=========================================================
fig=figure('units','pixels',...
        'position',[500 100 500 500],...
        'Numbertitle','off',...
        'Color',[1 1 1],...
        'resize','off',...
        'visible','on',...
        'name','mimose',...
         'menubar','none');

ax=axes('Units','pixels',...
        'parent',fig,...  
        'Color',[0.2667    0.4039    0.2745],...
        'Position',[0 0 500 500],...
        'XLim',[0 100],...
        'YLim',[0 100],...
        'XColor',[1 1 1],...
        'YColor',[1 1 1]);
hold(ax,'on')
%plot(ax,X+20,Y+50)

% 调用后面定义的函数绘图===================================================
% 绘制树枝
drawBranch([20,0],[50,10])
drawBranch([20,0],[35,12])
drawBranch([0,0],[15,45])
drawBranch([4,0],[0,20])

% 绘制树叶
leaf.l1=drawLeaf([50,10]+1.*[cos(pi/1.7),sin(pi/1.7)],pi/1.7,X,Y,0.8,1);
leaf.l2=drawLeaf([50,10]+1.*[cos(-pi/8),sin(-pi/8)],-pi/8,X,Y,0.8,1);
leaf.l3=drawLeaf([50,10]+1.*[cos(pi/12),sin(pi/12)],pi/12,X,Y,1,1);
leaf.l4=drawLeaf([50,10]+1.*[cos(pi/3),sin(pi/3)],pi/3,X,Y,1,1);
leaf.l5=drawLeaf([0,45]+1.*[cos(pi/3),sin(pi/3)],pi/3,X,Y,1,1);
leaf.l6=drawLeaf([0,30]+1.*[cos(pi/5),sin(pi/5)],pi/5,X,Y,1,1);

% 绘制花朵
flower.fl1=drawFlower([35,12]);
flower.fl2=drawFlower([20,5]);

% 鼠标移动回调=============================================================
fps=25;
mitimer=timer('ExecutionMode', 'fixedRate', 'Period',1/fps, 'TimerFcn', @miMove);
start(mitimer)

    % 花朵树叶回缩函数
    function miMove(~,~)
        for ii=1:6
            if leaf.(['l',num2str(ii)]).ratio<1 %如果收缩率小于1则每隔一段时间+0.05,以下同理
                leaf.(['l',num2str(ii)]).ratio=leaf.(['l',num2str(ii)]).ratio+0.05;
            end
            resetH(leaf.(['l',num2str(ii)]),X,Y); % 依据收缩率重新绘制叶子
        end
        for ii=1:2
            if flower.(['fl',num2str(ii)]).ratio<1
                flower.(['fl',num2str(ii)]).ratio=flower.(['fl',num2str(ii)]).ratio+0.05;
            end
            resetL(flower.(['fl',num2str(ii)]));
        end
    end

set(gcf,'WindowButtonMotionFcn',@whilemovefcn)  

    % 鼠标移动调用的函数
    function whilemovefcn(~,~)
        % 检测鼠标位置
        xy=get(gca,'CurrentPoint');
        xw=xy(1,1);yw=xy(1,2);
        pos=[xw,yw];
        
        % 鼠标附近的叶子收缩率-0.2
        for ii=1:6
            LF=leaf.(['l',num2str(ii)]);
            if closeLeaf(LF.pos1,LF.pos2,pos)% 如果距离叶子距离足够近
                if leaf.(['l',num2str(ii)]).ratio>0.2
                    leaf.(['l',num2str(ii)]).ratio=leaf.(['l',num2str(ii)]).ratio-0.2;
                end
            end
            
        end
        
        % 鼠标附近的花收缩率-0.2
        for ii=1:2
            FL=flower.(['fl',num2str(ii)]);
            if closeFlower(FL.pos,pos)% 如果距离花距离足够近
                if flower.(['fl',num2str(ii)]).ratio>0.6
                    flower.(['fl',num2str(ii)]).ratio=flower.(['fl',num2str(ii)]).ratio-0.2;
                end
            end
        end
    end

    % 距离检测函数,叶子形状近乎于椭圆,当距离俩焦点和小于一定值认为足够近
    % 若足够近返回TRUE 否则返回FALSE
    function bool=closeLeaf(pos1,pos2,pos3)
        pL=pos1+(pos2-pos1).*0.1;
        pR=pos1+(pos2-pos1).*0.9;
        lTotal=norm(pL-pos3)+norm(pR-pos3);
        bool=lTotal<=norm(pos1-pos2); 
    end
    
    % 距离检测函数,花形状近乎于圆,当距离圆心小于一定值认为足够近
    % 若足够近返回TRUE 否则返回FALSE
    function bool=closeFlower(pos1,pos2)
       bool=norm(pos1-pos2)<=5;
    end

    % 依据收缩率重新计算并绘制叶子
    function resetH(lf,X,Y)
        X=X.*lf.Len;
        Y=Y.*lf.h.*lf.ratio;
        xl1=X.*cos(lf.alf)-Y.*sin(lf.alf)+lf.pos1(1);
        yl1=X.*sin(lf.alf)+Y.*cos(lf.alf)+lf.pos1(2);
        xl2=X.*cos(lf.alf)+Y.*sin(lf.alf)+lf.pos1(1);
        yl2=X.*sin(lf.alf)-Y.*cos(lf.alf)+lf.pos1(2);
        XL=[xl1,xl2(end:-1:1)];
        YL=[yl1,yl2(end:-1:1)];
        set(lf.LHdl,'XData',XL,'YData',YL);  
    end

    % 依据收缩率重新计算并绘制花朵
    function resetL(fl)
        xf=fl.x.*fl.ratio+fl.pos(1);
        yf=fl.y.*fl.ratio+fl.pos(2);
        xxf(2:2:2*length(xf))=xf;
        yyf(2:2:2*length(yf))=yf;
        xxf(1:2:2*length(xf))=fl.pos(1);
        yyf(1:2:2*length(yf))=fl.pos(2);
        %set(fl.plHdl,'XData',xxf,'YData',yyf);
        set(fl.scHdl,'XData',xf,'YData',yf);
        set(fl.plHdl,'XData',xxf,'YData',yyf); 
    end


    % 绘制花朵(圆心)
    function fl=drawFlower(pos)
        
        % 随机生成一些点作为花蕊并绘图
        theta=rand([1,120]).*2.*pi;
        r=rand([1,120]).*3+5;
        xf=r.*cos(theta)+pos(1);
        yf=r.*sin(theta)+pos(2);
        xxf(2:2:2*length(xf))=xf;
        yyf(2:2:2*length(yf))=yf;
        xxf(1:2:2*length(xf))=pos(1);
        yyf(1:2:2*length(yf))=pos(2);
        plHdl=plot(ax,xxf,yyf,'Color',[0.7608 0.4863 0.7216],'LineWidth',1);
        scHdl=scatter(ax,xf,yf,3,'filled','CData',[0.9569 0.9804 0.9333]);
        
        % 存储基础信息到实类
        fl.x=xf-pos(1);
        fl.y=yf-pos(2);
        fl.pos=pos;
        fl.scHdl=scHdl;
        fl.plHdl=plHdl;
        fl.ratio=1;
        
        % 计算可伸缩部分花蕊坐标,绘图,存储信息
        theta2=rand([1,80]).*2.*pi;
        r2=rand([1,80]).*1+3;
        xf2=r2.*cos(theta2)+pos(1);
        yf2=r2.*sin(theta2)+pos(2);
        xxf2=[ones([1,length(xf2)]).*pos(1);xf2];
        yyf2=[ones([1,length(yf2)]).*pos(2);yf2];
        
        plot(ax,xxf2,yyf2,'Color',[0.7804 0.6078 0.5020],'LineWidth',1)
        
        
    end

    % 绘制树枝 (端点1,端点2)
    function drawBranch(pos1,pos2)
        % 依据起始及末尾两点计算一个一头宽一头窄四边形坐标数据并绘图
        dir=(pos2-pos1)./norm(pos2-pos1);
        len=norm(pos2-pos1);
        xb=[0 1 1 0].*len;
        yb=[len.*0.02,len.*0.012,-len.*0.012,-len.*0.02];
       
        xxb=xb.*dir(1)-yb.*dir(2)+pos1(1);
        yyb=xb.*dir(2)+yb.*dir(1)+pos1(2);
        fill(ax,xxb,yyb,[0.8157 0.6431 0.6078],'EdgeColor',[0.6157 0.5529 0.4510],'LineWidth',1.5)
    end

    % 绘制叶子(起始位置,叶子方向,轮廓x数据,轮廓y数据,轮廓x方向放缩比例,轮廓y方向放缩比例)
    function lf=drawLeaf(pos,alf,X,Y,l,h)
        X=X.*l; % 放缩叶子长度
        Y=Y.*h; % 放缩叶子宽窄
        
        % 叶子数据旋转并把两个叶子数据并在一起
        xl1=X.*cos(alf)-Y.*sin(alf)+pos(1);
        yl1=X.*sin(alf)+Y.*cos(alf)+pos(2);
        xl2=X.*cos(alf)+Y.*sin(alf)+pos(1);
        yl2=X.*sin(alf)-Y.*cos(alf)+pos(2);
        XL=[xl1,xl2(end:-1:1)];
        YL=[yl1,yl2(end:-1:1)];
        
        % 绘图
        lf.LHdl=fill(XL,YL,[0.4980 0.7216 0.3176]);
        
        % 基础数据存到实类里
        lf.pos1=pos;
        lf.pos2=[pos(1)+l*51*cos(alf),pos(2)+l*51*sin(alf)];
        lf.alf=alf;
        lf.Len=l;
        lf.h=h;
        lf.ratio=1;
        
        % 绘制一下叶子中线
        plot(ax,[pos(1),pos(1)+l*51*cos(alf)],[pos(2),pos(2)+l*51*sin(alf)],'Color',[0.6627 0.6980 0.4431],'LineWidth',3);
    end




end
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐