自学内容网 自学内容网

matlab模拟小球平抛


课题作业 模拟小球平抛运动过程:考虑惯性、旋转和地面碰撞

在这篇文章中,我们将通过 MATLAB 仿真来模拟小球的平抛运动。在这个模拟中,我们考虑了小球的惯性、旋转以及与地面的碰撞,展示了小球在能量逐渐损耗、停止弹跳和滚动之前的完整运动过程。通过这个项目,我们不仅可以观察到小球平抛运动的实际轨迹,还可以了解重力、摩擦力以及碰撞如何影响物体的运动状态。


仿真思路

首先,为了准确模拟小球的运动,我们需要考虑以下几点物理因素:

  1. 重力作用:小球受重力影响,使其在垂直方向不断加速。
  2. 能量损耗:小球每次与地面碰撞都会损失部分能量。用恢复系数 e 来控制每次碰撞后的能量保留。
  3. 摩擦力:小球与地面接触时会受到摩擦力的影响,进而导致水平速度和角速度的改变。摩擦系数 mu 控制摩擦力的大小。
  4. 运动终止条件:当小球的垂直速度和水平速度低于一定阈值时,认为小球已不再弹跳和滚动。

我们在仿真过程中创建动画,并将整个动画保存为视频文件,以便观察小球运动的完整过程。

代码解析

以下是代码的结构与关键部分解析:

1. 基础参数设置

首先,我们定义了一些基础参数,例如小球的初始位置 (x0, y0)、初速度 (vx0, vy0)、重力加速度 g、时间步长 dt、恢复系数 e、摩擦系数 mu 等。此外,小球的质量和转动惯量 I 也在这里定义:

x0 = 0;       % 初始水平位置
y0 = 10;      % 初始垂直位置(高度)
vx0 = 5;      % 初始水平速度
vy0 = 0;      % 初始垂直速度
g = -9.81;    % 重力加速度
dt = 0.01;    % 时间步长
e = 0.8;      % 恢复系数
mu = 0.1;     % 摩擦系数
radius = 0.2; % 小球半径
mass = 0.5;   % 小球质量
I = (2/5)*mass*radius^2; % 转动惯量

这些参数决定了小球的初始运动状态以及它在运动中如何受到各种力的影响。

2. 初始化动画

接下来,我们创建了一个全屏窗口,用于绘制小球的运动轨迹。小球的当前位置以红色圆点显示,轨迹以蓝色线条展示。此外,代码设置了坐标轴的范围和标签,方便我们实时观察小球的位置。

figure('Position', get(0, 'ScreenSize'));
hold on;
grid on;
xlabel('水平位置 (m)');
ylabel('垂直位置 (m)');
title('考虑惯性的小球平抛运动模拟(含能量损失)');
3. 仿真循环

仿真主循环中,小球的运动不断更新,主要过程包括以下几部分:

  • 更新速度和位置:在每个时间步 dt 内,垂直方向速度 vy 受重力加速度影响,水平和垂直位置 (x, y) 更新。

  • 碰撞检测和摩擦力处理:当小球与地面接触(y <= radius)时,会发生碰撞。在碰撞过程中,小球垂直速度反向并考虑能量损失。摩擦力作用在水平速度和角速度上,使小球在地面上逐渐减速。

  • 终止条件判断:如果垂直速度低于某个阈值,则认为小球停止弹跳;如果水平速度也足够小,认为小球停止滚动,结束仿真。

while true
    % 更新速度和位置
    vy = vy + g * dt;
    x = x + vx * dt;
    y = y + vy * dt;
    
    % 碰撞检测
    if y <= radius
        y = radius;
        vy = -e * vy;
        
        % 摩擦力引起的速度和角速度变化
        Fn = mass * abs(g);
        Ff = mu * Fn;
        dv = (Ff / mass) * dt;
        domega = (Ff * radius / I) * dt;
        
        if vx > 0
            vx = vx - dv;
            omega = omega + domega;
        elseif vx < 0
            vx = vx + dv;
            omega = omega - domega;
        end
        
        % 停止弹跳与滚动判断
        if abs(vy) < threshold_vy && abs(vx) < threshold_vx
            break;
        end
    end
end
4. 动态绘图与视频保存

在每个时间步中,我们实时更新小球的当前位置和轨迹,使用 getframe 捕获当前帧,将其写入视频文件。仿真结束后,关闭视频对象。

% 更新动画
set(ball, 'XData', x, 'YData', y);
set(trajectory, 'XData', X, 'YData', Y);
frame = getframe(gcf);
writeVideo(video, frame);
5. 结束仿真

当小球的垂直和水平速度都低于设定的阈值时,仿真终止。最终轨迹绘制完成,并保存视频供后续观看。

% 关闭视频对象
close(video);
plot(X, Y, 'LineWidth', 2);

运行效果

运行代码后,我们可以观察到一个完整的模拟小球平抛运动的动画,展示了小球如何在重力、惯性和摩擦力的共同作用下逐渐减速直至停止。

总结

通过这个仿真项目,我们更好地理解了力学中的碰撞、摩擦等物理因素对物体运动的影响。同时,MATLAB 的图形和动画功能让我们能够更加直观地观察运动过程,为物理学习和仿真分析提供了便利。

完整代码

% 需求:模拟小球平抛运动过程,考虑惯性、旋转和与地面的碰撞,直到能量足够少弹不起来为止,用动画形式展示
% TODO:调整动画窗口和坐标轴以完整显示动画,并将动画保存为视频

% 基础参数设置
x0 = 0;          % 初始水平位置
y0 = 10;         % 初始垂直位置(高度)
vx0 = 5;         % 初始水平速度
vy0 = 0;         % 初始垂直速度
g = -9.81;       % 重力加速度,单位:m/s^2
dt = 0.01;       % 时间步长,单位:秒
e = 0.8;         % 恢复系数(每次碰撞后的能量保留比例)
mu = 0.1;        % 地面与小球之间的摩擦系数
radius = 0.2;    % 小球半径,单位:米
mass = 0.5;      % 小球质量,单位:kg
I = (2/5)*mass*radius^2; % 小球的转动惯量

threshold_vy = 0.1; % 判定小球停止弹跳的垂直速度阈值
threshold_vx = 0.01; % 判定小球停止滚动的水平速度阈值

% 初始化变量
x = x0;
y = y0;
vx = vx0;
vy = vy0;
omega = 0;       % 初始角速度
t = 0;

% 用于存储轨迹数据
X = [];
Y = [];

% 设置动画
figure('Position', get(0, 'ScreenSize')); % 将窗口设置为全屏
hold on;
grid on;
xlabel('水平位置 (m)');
ylabel('垂直位置 (m)');
title('考虑惯性的小球平抛运动模拟(含能量损失)');

ball = plot(x, y, 'ro', 'MarkerSize', 15, 'MarkerFaceColor', 'r'); % 小球
trajectory = plot(NaN, NaN, 'b'); % 轨迹

% 初始化坐标轴范围
axis([x0-1 x0+10 0 y0+5]);

% 调整画面显示
set(gca, 'FontSize', 14); % 增大坐标轴字体

% 创建视频对象
video_filename = 'ball_motion.mp4'; % 视频文件名
video = VideoWriter(video_filename, 'MPEG-4');
video.FrameRate = 1/dt; % 设置帧率,与模拟时间步长匹配
open(video);

% 仿真循环
while true
    % 更新速度
    vy = vy + g * dt;
    
    % 更新位置
    x = x + vx * dt;
    y = y + vy * dt;
    
    % 存储数据
    X(end+1) = x;
    Y(end+1) = y;
    
    % 碰撞检测
    if y <= radius  % 考虑小球的半径
        y = radius;           % 确保小球不穿过地面
        vy = -e * vy;         % 垂直速度反向并考虑能量损失
        
        % 计算由于摩擦导致的水平速度变化和角速度变化
        Fn = mass * abs(g);   % 法向力
        Ff = mu * Fn;         % 摩擦力
        dv = (Ff / mass) * dt;     % 水平速度的变化量
        domega = (Ff * radius / I) * dt; % 角速度的变化量
        
        % 更新水平速度和角速度
        if vx > 0
            vx = vx - dv;
            omega = omega + domega;
            if vx < 0
                vx = 0;
            end
        elseif vx < 0
            vx = vx + dv;
            omega = omega - domega;
            if vx > 0
                vx = 0;
            end
        end
        
        % 判断是否停止弹跳
        if abs(vy) < threshold_vy
            vy = 0;
            % 检查是否需要继续滚动
            if abs(vx) < threshold_vx
                break; % 水平速度过小,结束仿真
            end
        end
    end
    
    % 当小球在地面上滚动时,考虑摩擦力减速
    if y == radius && vy == 0
        Fn = mass * abs(g);   % 法向力
        Ff = mu * Fn;         % 摩擦力
        dv = (Ff / mass) * dt;     % 水平速度的变化量
        domega = (Ff * radius / I) * dt; % 角速度的变化量
        
        % 更新水平速度和角速度
        if vx > 0
            vx = vx - dv;
            omega = omega + domega;
            if vx < 0
                vx = 0;
            end
        elseif vx < 0
            vx = vx + dv;
            omega = omega - domega;
            if vx > 0
                vx = 0;
            end
        end
        
        % 判断是否停止滚动
        if abs(vx) < threshold_vx
            break; % 水平速度过小,结束仿真
        end
    end
    
    % 更新动画
    set(ball, 'XData', x, 'YData', y);
    set(trajectory, 'XData', X, 'YData', Y);
    
    % 动态调整坐标轴范围
    axis([min(X)-1 max(X)+1 0 y0+5]);
    
    drawnow;
    
    % 捕获当前帧并写入视频
    frame = getframe(gcf);
    writeVideo(video, frame);
    
    % 更新时间
    t = t + dt;
end

% 关闭视频对象
close(video);

% 最后绘制完整轨迹
plot(X, Y, 'LineWidth', 2);

ball_motion


原文地址:https://blog.csdn.net/weixin_57140993/article/details/143468112

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!