《MATLAB实战训练营:从入门到工业级应用》趣味入门篇-用MATLAB画一朵会动的3D玫瑰:从零开始的浪漫编程之旅

发布于:2025-04-13 ⋅ 阅读:(18) ⋅ 点赞:(0)

《MATLAB实战训练营:从入门到工业级应用》趣味入门篇-🌹用MATLAB画一朵会动的3D玫瑰:从零开始的浪漫编程之旅在这里插入图片描述

你是否想过用代码创造一朵永不凋谢的玫瑰?今天,我将带你走进MATLAB的奇妙世界,用数学公式和编程技巧,打造一朵专属于你的3D动态玫瑰。这不仅是技术教程,更是一场浪漫的数学艺术创作!

🌟 前言:当代码遇上玫瑰

“程序员不懂浪漫?” 让我们用MATLAB打破这一刻板印象!玫瑰不仅是爱情的象征,它的优美曲线也蕴含着丰富的数学规律。通过这篇教程,你将学会:

  • 用极坐标方程描述玫瑰花瓣的优雅曲线
  • 将2D图形拓展到3D空间,赋予玫瑰立体生命
  • 添加光影效果,让玫瑰更加真实动人
  • 创建平滑动画,让你的玫瑰"活"起来
  • 导出作品,送给特别的人或分享到社交网络

准备好了吗?让我们一起开始这段代码与艺术交融的奇妙旅程!

🧮 第一章:玫瑰背后的数学之美

1.1 玫瑰曲线的历史渊源

玫瑰曲线(Rose Curve)最早由意大利数学家Guido Grandi在1723年研究,因其形状酷似玫瑰花瓣而得名。这种曲线在极坐标下展现出惊人的对称美,是数学与自然完美结合的典范。

1.2 极坐标下的玫瑰方程

基础玫瑰曲线方程为:

r = a × cos(k × θ)

其中:

  • r:极径(点到原点的距离)
  • θ:极角(点与极轴的夹角)
  • a:控制花瓣大小
  • k:控制花瓣数量和形状

趣味实验:尝试不同的k值,观察花瓣变化规律:

  • 当k为整数时:花瓣数量为k(k为奇数)或2k(k为偶数)
  • 当k为分数时:会产生更复杂的花瓣图案

1.3 3D玫瑰的魔法公式

要将玫瑰带入三维世界,我们需要更丰富的参数方程:

x = r × sin(θ) × cos(φ)
y = r × sin(θ) × sin(φ)
z = r × cos(θ)

其中φ是第二个角度参数,让我们能在z轴上创造变化。

💻 第二章:从零开始绘制2D玫瑰

2.1 基础绘图代码

让我们先用最简单的代码绘制一朵2D玫瑰:

% 清空工作区,准备画布
clf; clear; close all;

% 设置参数
a = 2;       % 花瓣大小
k = 5;       % 花瓣数量
theta = linspace(0, 2*pi, 1000);  % 创建1000个角度点

% 计算极坐标
r = a * cos(k * theta);

% 转换为笛卡尔坐标
x = r .* cos(theta);
y = r .* sin(theta);

% 绘制玫瑰
figure('Color', 'black')  % 黑色背景更显艺术感
plot(x, y, 'Color', [0.9 0.2 0.3], 'LineWidth', 3)
title('\fontsize{16}\color{white}MATLAB绘制的2D玫瑰', 'Interpreter', 'tex')
axis equal off  % 保持比例并隐藏坐标轴
set(gca, 'Color', 'black')  % 设置坐标区背景为黑色

运行效果:你会看到一朵鲜艳的红色五瓣玫瑰绽放在黑色背景上,就像夜空中绽放的烟火。

2.2 个性化你的玫瑰

尝试修改这些参数,创造属于你的独特玫瑰:

% 尝试不同的颜色
colors = {'#FF1493', '#FFD700', '#00FF7F', '#9370DB', '#00BFFF'};

figure('Position', [100 100 800 600], 'Color', 'black')
for i = 1:5
    subplot(2,3,i)
    k = i+2;  % 不同花瓣数量
    r = a * cos(k * theta);
    x = r .* cos(theta);
    y = r .* sin(theta);
    plot(x, y, 'Color', colors{i}, 'LineWidth', 2)
    title(sprintf('%d瓣玫瑰', k), 'Color', 'white')
    axis equal off
    set(gca, 'Color', 'black')
end

这段代码会生成一个包含5种不同颜色和花瓣数量的玫瑰画廊。
在这里插入图片描述

🌌 第三章:进入3D世界 - 让玫瑰立体起来

3.1 基础3D玫瑰

现在,让我们把玫瑰带入三维空间:

% 3D玫瑰参数
a = 1;          % 大小
k = 5;          % 花瓣数
n = 2;          % 形状控制
m = 3;          % 形状控制

% 创建角度网格
[theta, phi] = meshgrid(linspace(0, 2*pi, 100), linspace(0, pi, 50));

% 计算极径
r = a * sin(n * theta) .* cos(m * phi);

% 转换为3D坐标
x = r .* sin(theta) .* cos(phi);
y = r .* sin(theta) .* sin(phi);
z = r .* cos(theta);

% 绘制3D玫瑰
figure('Position', [100 100 800 600], 'Color', [0.1 0.1 0.3])
rose = surf(x, y, z, 'EdgeColor', 'none');
title('\fontsize{16}\color{white}3D玫瑰', 'Interpreter', 'tex')
colormap('hot')  % 使用热力图颜色
axis equal off
view(30, 30)    % 设置视角

% 添加专业光照
light('Position', [1 1 1], 'Style', 'infinite', 'Color', [1 1 0.8])
light('Position', [-1 -1 -1], 'Style', 'infinite', 'Color', [0.3 0.3 1])
lighting gouraud  % 使用Gouraud着色,更平滑
material shiny    % 使表面有光泽

效果说明:你会看到一朵立体的玫瑰,表面有漂亮的光影渐变,就像被阳光照射的真实花朵。
在这里插入图片描述

3.2 高级美化技巧

让我们进一步提升视觉效果:

% 创建更精细的玫瑰
[theta, phi] = meshgrid(linspace(0, 2*pi, 200), linspace(0, pi, 100));

% 更复杂的形状公式
r = a * (sin(n*theta).^2) .* (cos(m*phi).^3);

% 重新计算坐标
x = r .* sin(theta) .* cos(phi);
y = r .* sin(theta) .* sin(phi);
z = r .* cos(theta);

% 创建专业级可视化
figure('Position', [100 100 1000 800], 'Color', [0.05 0.05 0.1])
ax = axes('Color', 'none', 'Position', [0 0 1 1]);  % 全屏坐标区

% 绘制带透明度的玫瑰
rose = surf(x, y, z, 'FaceColor', [0.9 0.2 0.3], ...
    'EdgeColor', 'none', ...
    'FaceAlpha', 0.9, ...
    'DiffuseStrength', 0.8, ...
    'SpecularStrength', 0.5, ...
    'BackFaceLighting', 'lit');

% 设置视角和光照
view(45, 30)
axis equal vis3d off
camlight('left')  % 添加相机相关光照
lighting phong    % 更高质量的光照

% 添加颜色条
c = colorbar('eastoutside', 'Color', 'white');
c.Label.String = '深度';
c.Label.FontSize = 12;

% 添加艺术字标题
annotation('textbox', [0.3 0.9 0.4 0.1], ...
    'String', 'MATLAB 3D艺术玫瑰', ...
    'Color', 'white', ...
    'FontSize', 24, ...
    'FontWeight', 'bold', ...
    'EdgeColor', 'none', ...
    'HorizontalAlignment', 'center');

效果提升:这朵玫瑰现在拥有更精细的表面细节、更自然的光照效果和专业的排版布局,完全可以作为数字艺术品展示。
在这里插入图片描述

🎬 第四章:让玫瑰动起来 - MATLAB动画魔法

4.1 基础旋转动画

让我们先创建一个简单的旋转动画:

% 准备动画参数
n_frames = 120;  % 总帧数
azimuth_step = 360 / n_frames;  % 每帧旋转角度

% 创建图形窗口
fig = figure('Position', [100 100 800 800], 'Color', [0.1 0.1 0.3]);
ax = axes('Position', [0 0 1 1], 'Color', 'none');
axis equal off
view(30, 30)

% 预分配电影帧
movie_frames(n_frames) = struct('cdata', [], 'colormap', []);

% 生成动画
for i = 1:n_frames
    % 更新视角
    view(30 + (i-1)*azimuth_step, 30 + 10*sin(2*pi*(i-1)/n_frames))
    
    % 添加动态标题
    title(ax, sprintf('旋转的玫瑰 - 帧 %d/%d', i, n_frames), ...
        'Color', 'white', 'FontSize', 16)
    
    % 捕获当前帧
    drawnow
    movie_frames(i) = getframe(fig);
end

% 在MATLAB中播放动画
figure('Position', [100 100 800 800])
movie(movie_frames, 3, 30)  % 播放3次,30fps

动画效果:玫瑰会平滑旋转,同时视角有轻微上下浮动,模拟手持相机拍摄的效果。

4.2 绽放动画 - 从花苞到盛开

更令人惊叹的是让玫瑰从花苞逐渐绽放:

% 参数设置
a_final = 1.5;  % 最终大小
k = 7;          % 花瓣数
n = 3;          % 形状参数
m = 4;          % 形状参数

% 创建精细网格
[theta, phi] = meshgrid(linspace(0, 2*pi, 200), linspace(0, pi, 100));

% 准备动画
fig = figure('Position', [100 100 1000 800], 'Color', [0.05 0.05 0.15]);
ax = axes('Position', [0 0 1 1], 'Color', 'none');
axis equal vis3d off
view(45, 25)

% 设置光照
light('Position', [0 0 10], 'Style', 'local', 'Color', [1 0.8 0.6])
light('Position', [10 10 10], 'Style', 'local', 'Color', [0.6 0.6 1])
lighting gouraud

% 动画参数
n_frames = 90;
bloom_frames(n_frames) = struct('cdata', [], 'colormap', []);

% 绽放过程
for t = linspace(0, 1, n_frames)
    % 计算当前大小和形状
    current_a = a_final * smoothstep(t);  % 使用平滑函数
    r = current_a * (sin(n*theta).^2) .* (cos(m*phi).^3);
    
    % 计算坐标
    x = r .* sin(theta) .* cos(phi);
    y = r .* sin(theta) .* sin(phi);
    z = r .* cos(theta);
    
    % 绘制玫瑰(首次绘制或更新)
    if t == 0
        rose = surf(x, y, z, 'FaceColor', [0.9 0.2*t 0.3], ...
            'EdgeColor', 'none', 'FaceAlpha', 0.9);
    else
        set(rose, 'XData', x, 'YData', y, 'ZData', z, ...
            'FaceColor', [0.9 0.2+0.5*t 0.3]);
    end
    
    % 添加动态视角
    view(45 + t*180, 25 + 10*sin(t*2*pi))
    
    % 添加进度文本
    annotation('textbox', [0.4 0.05 0.2 0.05], ...
        'String', sprintf('绽放进度: %.0f%%', t*100), ...
        'Color', 'white', 'FontSize', 14, ...
        'EdgeColor', 'none', 'HorizontalAlignment', 'center')
    
    % 捕获帧
    drawnow
    bloom_frames(round(t*(n_frames-1))+1) = getframe(fig);
    
    % 删除进度文本
    if t < 1
        delete(findall(fig, 'Type', 'annotation'))
    end
end

% 平滑过渡函数
function y = smoothstep(x)
    y = x.^2 .* (3 - 2*x);
end

动画亮点

  1. 玫瑰从中心逐渐向外绽放
  2. 颜色从深红渐变为亮红
  3. 视角缓慢旋转,展示不同角度
  4. 底部有进度条显示绽放百分比
  5. 使用平滑函数使动画更加自然
    在这里插入图片描述

🎁 第五章:导出与分享你的作品

5.1 保存为GIF动画

filename = 'blooming_rose.gif';

% 调整帧率
delay_time = 0.08;  % 每帧延迟时间

for i = 1:length(bloom_frames)
    % 将帧转换为图像
    img = frame2im(bloom_frames(i));
    [imind, cm] = rgb2ind(img, 256);
    
    % 写入GIF
    if i == 1
        imwrite(imind, cm, filename, 'gif', ...
            'Loopcount', inf, ...
            'DelayTime', delay_time, ...
            'BackgroundColor', 0);
    else
        imwrite(imind, cm, filename, 'gif', ...
            'WriteMode', 'append', ...
            'DelayTime', delay_time);
    end
    
    % 显示进度
    fprintf('正在保存GIF: %.1f%%\n', 100*i/length(bloom_frames));
end

在这里插入图片描述

5.2 保存为高清视频

% 创建VideoWriter对象
v = VideoWriter('blooming_rose_hd.mp4', 'MPEG-4');
v.Quality = 100;      % 最高质量
v.FrameRate = 30;     % 30帧/秒
open(v);

% 写入帧
for i = 1:length(bloom_frames)
    writeVideo(v, bloom_frames(i));
    fprintf('正在保存视频: %.1f%%\n', 100*i/length(bloom_frames));
end

% 关闭文件
close(v);

MATLAB制作会旋转的玫瑰花

🌈 第六章:创意扩展 - 打造你的玫瑰花园

6.1 多朵玫瑰组合

% 创建画布
figure('Position', [100 100 1200 800], 'Color', [0.05 0.05 0.15])
ax = axes('Color', 'none');
axis equal vis3d off
view(40, 25)
lighting gouraud
hold on

% 定义不同玫瑰参数
roses = {
    struct('a',1,'k',5,'n',2,'m',3,'color',[0.9 0.2 0.3],'pos',[0 0 0]), 
    struct('a',0.8,'k',7,'n',3,'m',2,'color',[0.2 0.8 0.5],'pos',[2 1 0]),
    struct('a',1.2,'k',4,'n',1,'m',4,'color',[0.4 0.3 0.9],'pos',[-1 2 0])
};

% 绘制每朵玫瑰
for r = roses
    [theta, phi] = meshgrid(linspace(0, 2*pi, 150), linspace(0, pi, 75));
    r_val = r.a * sin(r.n*theta) .* cos(r.m*phi);
    x = r_val .* sin(theta) .* cos(phi) + r.pos(1);
    y = r_val .* sin(theta) .* sin(phi) + r.pos(2);
    z = r_val .* cos(theta) + r.pos(3);
    
    surf(x, y, z, ...
        'FaceColor', r.color, ...
        'EdgeColor', 'none', ...
        'FaceAlpha', 0.85);
end

% 添加统一光照
light('Position', [5 5 10], 'Color', [1 1 0.8])
light('Position', [-5 -5 5], 'Color', [0.5 0.5 1])

% 添加地面
[x_ground, y_ground] = meshgrid(-5:0.5:5, -5:0.5:5);
z_ground = -0.5 * ones(size(x_ground));
surf(x_ground, y_ground, z_ground, ...
    'FaceColor', [0.2 0.3 0.2], ...
    'EdgeColor', 'none', ...
    'FaceAlpha', 0.7)

% 添加标题
title('\fontsize{20}\color{white}MATLAB玫瑰花园', 'Interpreter', 'tex')
hold off

在这里插入图片描述

6.2 季节变化动画

创建一个展示玫瑰四季变化的动画:

% 参数设置
seasons = {'春', '夏', '秋', '冬'};
season_colors = {
    [0.9 0.3 0.4],   % 春 - 鲜红
    [0.8 0.1 0.2],    % 夏 - 深红
    [0.7 0.4 0.3],    % 秋 - 橙红
    [0.6 0.5 0.7]     % 冬 - 紫红
};
season_alphas = [0.9, 1.0, 0.8, 0.6];  % 透明度变化

% 创建动画
fig = figure('Position', [100 100 1000 800], 'Color', [0.1 0.1 0.2]);
ax = axes('Position', [0 0 1 1], 'Color', 'none');
axis equal vis3d off
view(45, 25)
lighting gouraud

% 预分配帧
season_frames(120) = struct('cdata', [], 'colormap', []);

% 创建基础玫瑰
[theta, phi] = meshgrid(linspace(0, 2*pi, 150), linspace(0, pi, 75));
r = sin(3*theta) .* cos(4*phi);
x = r .* sin(theta) .* cos(phi);
y = r .* sin(theta) .* sin(phi);
z = r .* cos(theta);
rose = surf(x, y, z, 'EdgeColor', 'none');

% 动画循环
for i = 1:120
    % 计算当前季节(0-3)和季节内进度(0-1)
    season_idx = floor((i-1)/30) + 1;
    season_progress = mod(i-1, 30)/30;
    
    % 季节间颜色过渡
    if season_idx < 4
        next_idx = season_idx + 1;
    else
        next_idx = 1;
    end
    color = season_colors{season_idx} * (1-season_progress) + ...
            season_colors{next_idx} * season_progress;
    
    % 更新玫瑰属性
    set(rose, 'FaceColor', color, ...
              'FaceAlpha', season_alphas(season_idx)*(1-season_progress) + ...
                           season_alphas(next_idx)*season_progress);
    
    % 添加季节文本
    annotation('textbox', [0.4 0.9 0.2 0.05], ...
        'String', sprintf('季节: %s', seasons{season_idx}), ...
        'Color', 'white', 'FontSize', 18, ...
        'EdgeColor', 'none', 'HorizontalAlignment', 'center')
    
    % 缓慢旋转
    view(45 + i, 25 + 5*sin(i/10))
    
    % 捕获帧
    drawnow
    season_frames(i) = getframe(fig);
    
end

% 播放动画
figure
movie(season_frames, 2, 30)  % 播放2次,30fps

在这里插入图片描述

🎉 结语:你的代码,你的艺术

通过这篇教程,你已经掌握了:

  • 玫瑰曲线的数学原理与MATLAB实现
  • 专业级的3D数据可视化技巧
  • 复杂动画的制作与优化方法
  • 艺术化呈现科学数据的多种手法

但更重要的是,你学会了如何用代码表达创意和美感。MATLAB不仅是科学计算的工具,也可以成为数字艺术创作的画布。

创意挑战

  1. 尝试为你的玫瑰添加花茎和叶子
  2. 创建一个心形玫瑰图案
  3. 设计一朵随时间变化颜色的彩虹玫瑰
  4. 模拟玫瑰在风中摇曳的效果

记住,每个伟大的数字艺术作品都始于一行简单的代码。现在,轮到你创造属于自己的MATLAB艺术了!


网站公告

今日签到

点亮在社区的每一天
去签到