• 有趣之matlab-烟花


    待整合1 2 3

    1. 动态

    有趣编程之11

    静态 逼真

    3 .m文件路径下放back1.jpg back4.jpg…背景照片
    点击screen 就会有小白点升起,爆炸

    function yanhuamoban()
        clear all;
        %定义全局变量
        global ah ;%坐标轴句柄
        global styleNum ;%爆炸图案样式
        global multiColor; %多颜色变换
        global color;%烟花颜色
        global v0;%烟花爆炸速度
        global n; %粒子数量
        global g;%粒子重力加速度
        %变量初始化开始
        multiColor = 0;
        styleNum = 3;
        color = [1 1 0];
        v0 = 250;   %烟花爆炸时的速度
        n = 2000;%粒子shumu
        g=1000;
        %变量初始化结束
        %GUI部分开始
        fig = figure('units','normalized','position',[0.1 0.1 0.6 0.8],...
            'menubar','none','numberTitle','off','Name','烟花欣赏','WindowButtonDownFcn',@yanhua...
            );
        %菜单
        file_menu = uimenu(fig,'Label','文件(&f)');
        sub_file_menu1 = uimenu(file_menu,'Label','退出(&q)','CallBack',@file_menu_callback);
     
        style_menu = uimenu(fig,'Label','爆炸风格(&s)');
        sub_style_menu1 = uimenu(style_menu,'Label','风格(&1)','CallBack',@style_menu_callback);
        sub_style_menu2 = uimenu(style_menu,'Label','风格(&2)','CallBack',@style_menu_callback);
        sub_style_menu3 = uimenu(style_menu,'Label','风格(&3)','CallBack',@style_menu_callback);
        sub_style_menu4 = uimenu(style_menu,'Label','风格(&4)','CallBack',@style_menu_callback);
        sub_style_menu5 = uimenu(style_menu,'Label','风格(&5)','CallBack',@style_menu_callback);
        sub_style_menu6 = uimenu(style_menu,'Label','风格(&6)','CallBack',@style_menu_callback);
     
        picture_menu = uimenu(fig,'Label','背景图片(&p)');
        sub_picture_menu1 = uimenu(picture_menu,'Label','图片(&1)','CallBack',@picture_menu_callback);
        sub_picture_menu2 = uimenu(picture_menu,'Label','图片(&2)','CallBack',@picture_menu_callback);
        sub_picture_menu3 = uimenu(picture_menu,'Label','图片(&3)','CallBack',@picture_menu_callback);
        sub_picture_menu4 = uimenu(picture_menu,'Label','图片(&4)','CallBack',@picture_menu_callback);
        sub_picture_menu5 = uimenu(picture_menu,'Label','图片(&5)','CallBack',@picture_menu_callback);
     
        color_menu = uimenu(fig,'Label','烟花颜色(&c)');
        sub_color_menu1 = uimenu(color_menu,'Label','黄色(&1)','CallBack',@color_menu_callback);
        sub_color_menu2 = uimenu(color_menu,'Label','紫红色(&2)','CallBack',@color_menu_callback);
        sub_color_menu3 = uimenu(color_menu,'Label','青色(&3)','CallBack',@color_menu_callback);
        sub_color_menu4 = uimenu(color_menu,'Label','红色(&4)','CallBack',@color_menu_callback);
        sub_color_menu5 = uimenu(color_menu,'Label','绿色(&5)','CallBack',@color_menu_callback);
        sub_color_menu6 = uimenu(color_menu,'Label','蓝色(&6)','CallBack',@color_menu_callback);
        sub_color_menu7 = uimenu(color_menu,'Label','白色(&7)','CallBack',@color_menu_callback);
        sub_color_menu8 = uimenu(color_menu,'Label','五彩变换(&8)','CallBack',@color_menu_callback);
     
        %按钮面板
        color_button_group = uibuttongroup(fig,'Title','颜色调节面板','Position',[0.83,0.55,0.16,0.44]);
        speed_button_group = uibuttongroup(fig,'Title',regexprep('速度调节面板(num)','num',num2str(v0)),'Position',[0.83,0.36,0.16,0.185],'Tag','speed_panel');
        number_button_group = uibuttongroup(fig,'Title',regexprep('数量调节面板(num)','num',num2str(n)),'Position',[0.83,0.005,0.16,0.35],'Tag','ammount_panel');
     
        %颜色微调滑动条
        red_slider = uicontrol(fig,'Style','slider','String','red','Position',[695,450,25,140],'Min',0,'Max',1,'Value',1,'backgroundColor',[1,0,0],'CallBack',@slider_callback);
        green_slider = uicontrol(fig,'Style','slider','String','green','Position',[735,450,25,140],'Min',0,'Max',1,'Value',1,'backgroundColor',[0,0,1],'CallBack',@slider_callback);
        blue_slider = uicontrol(fig,'Style','slider','String','blue','Position',[775,450,25,140],'Min',0,'Max',1,'Value',0,'backgroundColor',[0,1,0],'CallBack',@slider_callback);
        %颜色参数静态文本
        color_text = uicontrol(fig,'Style','text','Position',[690,395,115,50],'Tag','color_text',...
            'String',char('red=1','blue=1','green=0'),'backgroundColor',[1,0.95,0.87],'FontSize',10,'HorizontalAlignment','left');
        %颜色演示面板
        color_panel = uipanel(fig,'Title','颜色演示面板','BackgroundColor',color,'Units','pixels','Position',[690,345,115,40]);
     
        %修改速度按钮
        fast_button = uicontrol(fig,'Style','pushbutton','Position',[700,280,100,40],'FontSize',10,'String','加快','CallBack',@button_callback);
        slow_button = uicontrol(fig,'Style','pushbutton','Position',[700,230,100,40],'FontSize',10,'String','减慢','CallBack',@button_callback);
     
        %修改数量按钮
        increase_button = uicontrol(fig,'Style','pushbutton','Position',[700,160,100,40],'FontSize',10,'String','增多','CallBack',@button_callback);
        decrease_button = uicontrol(fig,'Style','pushbutton','Position',[700,110,100,40],'FontSize',10,'String','减少','CallBack',@button_callback);
        modNum_button = uicontrol(fig,'Style','pushbutton','Position',[700,60,100,40],'FontSize',10,'String','手动调整数量','CallBack',@button_callback);
        modG_button = uicontrol(fig,'Style','pushbutton','Position',[700,10,100,40],'FontSize',10,'String','手动调整加速度','CallBack',@button_callback);
     
        axes('DrawMode','fast','position',[0,0,0.8,1]);
        II=imread('back4.jpg');
        image(II)
        ah = axes('DrawMode','fast','Color','none','position',[0,0,0.8,1]);
        axis([-200 420 1 410])%设置坐标轴的范围
        grid off
        %GUI部分结束
     
        hold on
        %烟花主控函数,每次点击鼠标按钮监听器都会调用此函数。
        function yanhua(src,event)
            cp = get(ah,'CurrentPoint'); % 得到点击点的坐标
            xt = cp(1,1);yt = cp(1,2);
            if(xt < 420)%若点击在按钮面板则不放烟花
                launch(xt,yt)%烟花发射函数
            end
        end
    end  %主函数调用结束
     
    %colormap(hot)
    %烟花发射函数
    function launch(xt,yt)
        x=xt;
        y=0;
        H=plot(x,y,'w.');      %以白色,点来绘制图像。
        set(H,'EraseMode','xor','MarkerSize',25)%擦除式绘图,通过在极短的时间里不断绘制新点坐标,擦出旧点坐标来实现烟花向上发射的运动效果
        T = timer('TimerFcn',@timer_display1,'StopFcn',@stopFcn1,'TasksToExecute',50,'Period',0.005,'ExecutionMode','fixedSpacing');%非阻塞式定时器,以0.005秒为间隔调用TimerFcn,共调用50次。调用玩后会启动StopFcn函数,进行清尾工作,如清楚发射点图像,初始化烟花爆炸的定时器等。而烟花发射的运动,就是通过在这50次的重复调用中,不断更新点的坐标来实现的。
        T.userData = {H,xt,yt,1};%定时器对象的属性。在定时函数里使用。定时器函数是不变的,但在重复调用中要实现点坐标的改变,就要通过改变定时器对象的对象属性才行。
        %为什么要用对象属性而不是函数内定义的局部变量?因为局部变量在每次函数调用完毕就会被销毁,不能实现类似于静态变量的效果在下次重复调用中生效。那为什么不适用全局变量?因为全局变量是共用的,我的定时器A能用,定时器B也能用,A修改了这个变量,B中也生效了,这就有“线程安全性”问题了。
        start(T);%启动定时器
    end
    function timer_display1(obj,event)
        userData = obj.userData;%获取对象数据
        H = userData{1};
        x = userData{2};
        yt = userData{3};
        i = userData{4};
        y=i/50*yt;%执行50次,就到了鼠标点击位置,预备爆炸了。这个运动模型可以结合实际的物理模型做进一步优化,感兴趣的同学不妨试试。
        set(H,'XData',x,'YData',y)%更新烟花坐标
        drawnow;%重画页面,使烟花"H"出现在新位置
     
        i=i+1;%这是控制烟花位移的关键
        obj.userData = {H,x,yt,i};%更新对象数据,再下次重复调用时再取出使用
    end
     
    function stopFcn1(obj,event)%定时器1完成了它的50次调用使命,使烟花(点)到达爆炸处(鼠标位置),这个烟花(点)在这里被消除,然后开始了烟花爆炸的定时器初始化、启动工作
        global n;
        global color;
        userData = obj.userData;
        H = userData{1}
        xt = userData{2};
        yt = userData{3};
        x=-20;y=-20;
        set(H,'XData',x,'YData',y);
        %上述程序使得烟花到达鼠标的位置后消失在视野内
        %*************烟花的爆炸过程    
        x=zeros(n,1);%爆炸后的颗粒数为n
        y=zeros(n,1);
        h=plot(x,y,'.');%烟花爆炸后的形状
        set(h,'Color',color);
        set(h,'erasemode','xor','MarkerSize',5)
        T = timer('TimerFcn',@timer_display2,'StopFcn',@stopFcn2,'TasksToExecute',40,'Period',0.05,'ExecutionMode','fixedSpacing');
        T.userData = {h,xt,yt,0};
        start(T);
    end
    function timer_display2(obj,event)
        global n v0 styleNum multiColor g;
        userData = obj.userData;
        h = userData{1};
        x0 = userData{2};
        y0 = userData{3};
        t = userData{4};
        theta=rand(n,1)*2*pi;%粒子的仰角
        fy=rand(n,1)*2*pi;%粒子的方位角
        theta1=round(12*rand(n,1))/6*pi;
        for i=1:n %绘制粒子下落过程,
            switch(styleNum)%图案判定,通过菜单修改全局变量控制
                case 1
                    x(i)=2*v0*cos(fy(i))*cos(theta(i)+t*pi)*t+x0;
                    y(i)=1.2*v0*cos(fy(i))*sin(theta(i)+i*pi)*t-g*t.^2+y0;
                case 2
                    if(mod(theta(i),0.4*pi)<=0.1*pi)
                        x(i)=2*v0*cos(fy(i))*cos(theta(i)-4*t*pi)*t+x0;
                        y(i)=1.2*v0*cos(fy(i))*sin(theta(i)-4*t*pi)*t-g*t.^2+y0;
                    else 
                        x(i)=(mod(theta(i),0.4*pi)*2.5/pi+0.4)*2*v0*cos(fy(i))*cos(theta(i)-4*t*pi)*t+x0;
                        y(i)=(mod(theta(i),0.4*pi)*2.5/pi+0.4)*1.2*v0*cos(fy(i))*sin(theta(i)-4*t*pi)*t-g*t.^2+y0;
                    end
                case 3
                    x(i)=2*v0*cos(fy(i))*cos(theta(i)+i*t*pi)*t+x0;
                    y(i)=1.2*v0*cos(fy(i))*sin(theta(i)+i*t*pi)*t-g*t.^2+y0;
                case 4
                    x(i)=0.8*fy(i)/pi*2*v0*cos(fy(i))*cos(theta(i)+i*pi)*t+x0;
                    y(i)=0.8*fy(i)/pi*(1.2*v0*cos(fy(i))*sin(theta(i)+i*pi)*t-g*t.^2)+y0;
                case 5
                     x(i)=4*v0*cos(fy(i))*cos(theta1(i))*t+x0;
                     y(i)=(4*v0*cos(fy(i))*sin(theta1(i)-cos(fy(i))*cos(theta1(i))*0.3*t*pi)*t-4*t.^2)+y0;
                case 6                       
                    x(i)=v0*cos(fy(i))*cos(theta1(i)+4*t*pi)*t+x0;
                    y(i)=v0*cos(fy(i))*sin(theta1(i))*t-g*t.^2+y0;    
                  end
        end
        set(h,'xdata',x,'ydata',y);
        if(multiColor == 1)
            set(h,'Color',rand(1,3));
        end
        drawnow;
        t = t + 0.01;
        obj.userData = {h,x0,y0,t};
    end
    function stopFcn2(obj,event)
        %下述程序使爆炸的烟花消失
        global n;
        userData = obj.userData;
        h = userData{1};
        x=zeros(n,1);
        y=zeros(n,1);
        set(h,'xdata',x,'ydata',y);
    end
     
    %hObject  eventdata handles
    %按钮回调函数
    function button_callback(object,data,handles)
        global v0 n g;
        switch(object.String)
            case '加快'
                v0 = v0 + 50;
                speed_panel = findobj(gcf,'Tag','speed_panel');
                speed_panel.Title = regexprep(speed_panel.Title,'\d*',num2str(v0));%正则表达式替换
            case '减慢'
                v0 = v0 - 50;
                speed_panel = findobj(gcf,'Tag','speed_panel');
                speed_panel.Title = regexprep(speed_panel.Title,'\d*',num2str(v0));%正则表达式替换
            case '增多'
                n = n + 100;
                ammount_panel = findobj(gcf,'Tag','ammount_panel');
                ammount_panel.Title = regexprep(ammount_panel.Title,'\d*',num2str(n));%正则表达式替换
            case '减少'
                n = n - 100;
                ammount_panel = findobj(gcf,'Tag','ammount_panel');
                ammount_panel.Title = regexprep(ammount_panel.Title,'\d*',num2str(n));%正则表达式替换
            case '手动调整数量'
                ammount_input = inputdlg('请输入爆炸后烟花颗粒的数量','修改烟花数量',1);
                num=str2num(ammount_input{1});
                if isempty(num)
                  errordlg('必须输入有效数字','错误');
                else
                    n = num;
                    ammount_panel = findobj(gcf,'Tag','ammount_panel');
                    ammount_panel.Title = regexprep(ammount_panel.Title,'\d*',num2str(n));%正则表达式替换
                end
            case '手动调整加速度'
            ammount_input = inputdlg(strcat('请输入爆炸后烟花加速度值,当前值为:',num2str(g)),'修改加速度',1);
            num=str2num(ammount_input{1});
            if isempty(num)
              errordlg('必须输入有效数字','错误');
            else
                g = num;
            end
        end
    end
    %烟花样式改变菜单
    function style_menu_callback(object,data,handles)
        global styleNum;
        number = regexp(object.Label,'\d','match');
        styleNum = str2num(number{1});
    end
    function file_menu_callback(object,data,handles)
        switch(object.Label)
            case '退出(&q)'
                close(gcf);
        end
    end
    function picture_menu_callback(object,data,handles)
        global ah;
        number = regexp(object.Label,'\d','match');
        imageName = strcat(strcat('back',number),'.jpg');
        axes('DrawMode','fast','position',[0,0,0.8,1]);
        II=imread(imageName{1});
        image(II);
        ah = axes('DrawMode','fast','Color','none','position',[0,0,0.8,1]);
        axis([-200 420 1 410])%设置坐标轴的范围
        grid off
        hold on;
    end
    function color_menu_callback(object,data,handles)
        global color multiColor;
        disp(object.Label);
        multiColor = 0;%初始化颜色状态
        switch(object.Label)
            case '黄色(&1)'
                color = [1 1 0];
            case '紫红色(&2)'
                color = [1 0 1];
            case '青色(&3)'
                color = [0 1 1];
            case '红色(&4)'
                color = [1 0 0];
            case '绿色(&5)'
                color = [0 0 1];
            case '蓝色(&6)'
                color = [0 1 0];
            case '白色(&7)'
                color = [1 1 1];
            case '五彩变换(&8)'
                color = [0 0 0];
                multiColor = 1; 
        end
     
        parseColor(color);
    end
     
    function slider_callback(obj,event)
        global color ;
        red_slider = findobj(gcf,'String','red');
        blue_slider = findobj(gcf,'String','blue');
        green_slider = findobj(gcf,'String','green');
        color = [red_slider.Value,blue_slider.Value,green_slider.Value];
        parseColor(color);
    end
    function[rbgStr] = parseColor(color)
        color_text = findobj(gcf,'Tag','color_text');
        rbgStr = char(strcat('red=',num2str(color(1))),...
            strcat('blue=',num2str(color(2))),...
            strcat('green=',num2str(color(3))));
        color_text.String = rbgStr;
        color_panel = findobj(gcf,'Title','颜色演示面板');
        color_panel.BackgroundColor = color;
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305

    参考博文

  • 相关阅读:
    生产管理电子看板在制造业中的成功案例分享
    java项目-第99期基于spring+springmvc+hibernate的在线问卷答题系统-计算机毕业设计
    vue快速学习02、基础用法
    顺序表(7.24)
    基于SSM+Vue的鲸落文化线上体验馆设计与实现
    文件或目录损坏且无法读取
    如果线性变换可以模仿
    java项目_第164期ssm定西扶贫惠农推介系统-_java毕业设计_计算机毕业设计
    大数据——Hadoop3.1.3安装与配置
    【主题课】9.10教师节电子贺卡制作
  • 原文地址:https://blog.csdn.net/u012114900/article/details/136710469