首页 > 其他分享 >matlab模拟小球平抛

matlab模拟小球平抛

时间:2024-11-03 17:51:37浏览次数:4  
标签:end 小球 matlab vx vy dt omega 模拟


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

在这篇文章中,我们将通过 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);

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="Kw8unFKV-1730627428678" src="https://live.csdn.net/v/embed/432336"></iframe>

ball_motion

标签:end,小球,matlab,vx,vy,dt,omega,模拟
From: https://blog.csdn.net/weixin_57140993/article/details/143468112

相关文章

  • noip模拟4
    AMedian打了\(70\)分,但是因为printf("%.1lf")惨遭爆零。原因详见我写的讨论。首先,你需要把\([1,10^7]\)范围是质数全部筛出来,大概耗时半秒。然后,考虑数据是根据质数构造的,所以近似为随机。那么既然随机,那咱们直接对于每次移动去维护中位数的位置就好了。点击查看代......
  • noip模拟3
    这场好难。A网格队列里的结构体数组开大了导致RE。。。正解很简洁,对于现在有的字符串,添加一个数字或符号的转移是相对固定的:添加一个数字,如果前一位是运算符,那么久新加一个数字,否则,让现在的数字乘以10加上它;添加运算符同理。点击查看代码#include<bits/stdc++.h>us......
  • Comsol&Matlab 基于准亥姆霍兹共振的可调谐水声超材料:从低频到超宽带
    我们报道了一种具有深亚波长厚度(例如,k=300)和强承载能力的轻质可调谐声学超材料,用于水下低频和超宽带声学完美吸收。该超材料是通过在金属六边形蜂窝状亥姆霍兹谐振器中引入橡胶涂层和嵌入金属颈来构建的。物理上,橡胶涂层引发的准亥姆霍兹共振与嵌入颈部引起的反相位抵消导致......
  • 【STL_list 模拟】——打造属于自己的高效链表容器
    一、list节点​list是一个双向循环带头的链表,所以链表节点结构如下: template<classT> structListNode { Tval; ListNode*next; ListNode*prve; ListNode(intx) { val=x; next=prve=this; } };二、list迭代器2.1、list迭代器与vector......
  • 2024.11.2 模拟赛
    2024.11.2模拟赛T1P11242碧树把\(n\)个点往外连即可。最终答案为\(n-\max_{i=1}^na_i+1\)T2P11243繁花感觉我的做法麻烦了,而且随机复杂度()显然的,从左往右看可以分层,遇到一次大于号分一次。对于每段,遍历一遍,每遇到一次小于号计算一次答案。如果不考虑等于号,这段的......
  • strlen函数的模拟实现
    首先我们先新建项目,并新建源文件然后先调用sring.h里的strlen函数看看该函数的效果可以看到strlen的结果为字符串"abc"的长度我们又知道对于字符串"abc"实际上在字符串尾部会存在\0,即字符串arr实际上是"abc\0"那么先定义自定义函数my_strlen使它的返回类型为int,接受的数组......
  • 易语言模拟真人动态生成鼠标滑动路径
    一.简介鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。鼠标轨迹算法的底层实现采用C/C++语言,原因在于C/C++提供了高性能的执行能力和直接访问操作系统底层资源的能力。鼠标轨迹算法具有以下优势:模拟人工轨迹:算法能够模拟出非贝塞尔曲线的......
  • Python模拟真人动态生成鼠标滑动路径
    一.简介鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。鼠标轨迹算法的底层实现采用C/C++语言,原因在于C/C++提供了高性能的执行能力和直接访问操作系统底层资源的能力。鼠标轨迹算法具有以下优势:模拟人工轨迹:算法能够模拟出非贝塞尔曲线的......