基于Matlab生成黑色火柴人运球 + 起跳 + 投篮动作

说明:

  1. 运球阶段加入更平滑的身体上下起伏与摆臂摆腿

  2. 起跳阶段使用缓动函数,使动作更自然

  3. 投篮阶段加入出手、随挥动作以及篮球抛物线轨迹

  4. 支持导出 GIF:将 exportGIF 改为 true

本程序在matlab2026a运行可跑通,版本较低,可能会运行报错。

可尝试安装高版本软件《MATLAB2026a版本新特点》

下面为主要程序。

Matlab 复制代码
clear; clc; close all;

exportGIF = false;                         % true:导出 GIF
gifName   = 'black_stickman_basketball_fast_drop.gif';

fps = 50;                                  % 帧率提高,视觉更流畅
n1 = 95;                                   % 运球阶段:更短,动作更快
n2 = 38;                                   % 起跳合球阶段
n3 = 55;                                   % 投篮飞行阶段
n4 = 70;                                   % 篮球掉落阶段
nFrame = n1 + n2 + n3 + n4;

fig = figure('Color','w','Position',[100 100 1200 680]);
ax  = axes(fig);

for k = 1:nFrame
    cla(ax);
    hold(ax,'on');
    axis(ax,'equal');
    axis(ax,[0 13 0 7.5]);
    ax.XTick = [];
    ax.YTick = [];
    ax.Box = 'off';

    drawCourt(ax);

    if k <= n1
        %% 阶段1:快速大幅度运球前进
        p = (k-1)/(n1-1);
        pe = easeInOutSine(p);

        x = 1.05 + 5.10*pe;

        % 更快、更明显的跑动节奏
        cyc = 2*pi*5.8*p;
        bob = 0.12*sin(cyc);

        ballX = x + 0.78;
        ballY = 0.55 + 1.42*abs(sin(cyc));

        pose.phase = cyc;
        pose.jump = bob;
        pose.mode = 'dribble';
        pose.ballPos = [ballX, ballY];
        pose.bodyLean = 0.16;
        pose.armRaise = 0;
        pose.followThru = 0;

        drawStickmanDynamic(ax, x, 0.38, 1.0, pose);
        drawBall(ax, ballX, ballY, 0.22);

    elseif k <= n1+n2
        %% 阶段2:快速合球 + 大幅屈膝 + 起跳
        p = (k-n1)/n2;
        pe = easeInOutCubic(p);

        x = 6.15 + 0.90*pe;

        % 先快速下蹲,再快速起跳
        if p < 0.35
            q = p/0.35;
            jump = -0.28*sin(pi*q/2);
        else
            q = (p-0.35)/(1-0.35);
            jump = -0.28 + 1.20*sin(pi*q/2);
        end

        ballX = x + 0.50 + 0.18*pe;
        ballY = 1.45 + 2.85*pe + jump;

        pose.phase = 0;
        pose.jump = jump;
        pose.mode = 'gather';
        pose.ballPos = [ballX, ballY];
        pose.bodyLean = 0.12;
        pose.armRaise = pe;
        pose.followThru = 0;

        drawStickmanDynamic(ax, x, 0.38, 1.0, pose);
        drawBall(ax, ballX, ballY, 0.22);

    elseif k <= n1+n2+n3
        %% 阶段3:快速出手 + 篮球飞向篮筐
        p = (k-(n1+n2))/n3;
        pe = easeOutCubic(min(p,1));

        x = 7.05;

        % 人物起跳后逐渐下落
        jump = 0.82*(1-min(p*1.25,1)).^1.6;

        startP = [7.66, 4.38];
        ctrlP  = [8.85, 6.82];
        endP   = [10.35, 4.60];

        ballPos = (1-pe)^2*startP + 2*(1-pe)*pe*ctrlP + pe^2*endP;

        pose.phase = 0;
        pose.jump = jump;
        pose.mode = 'release';
        pose.ballPos = ballPos;
        pose.bodyLean = 0.06;
        pose.armRaise = 1;
        pose.followThru = pe;

        drawStickmanDynamic(ax, x, 0.38, 1.0, pose);
        drawBall(ax, ballPos(1), ballPos(2), 0.22);

        if pe > 0.82
            drawNetShake(ax, pe);
        end

    else
        %% 阶段4:投中后篮球掉落 + 地面反弹
        p = (k-(n1+n2+n3))/n4;
        p = min(max(p,0),1);

        x = 7.05;
        jump = 0;

        % 篮球从篮筐下方掉落,带一点横向漂移
        ballX = 10.35 + 0.18*sin(2*pi*p);

        % 分段下落 + 反弹
        if p < 0.62
            q = p/0.62;
            ballY = 4.45 - 3.78*(q^2);          % 加速下落
        else
            q = (p-0.62)/(1-0.62);
            ballY = 0.67 + 0.95*sin(pi*q).*exp(-1.55*q);  % 落地后小幅反弹
        end

        pose.phase = 0;
        pose.jump = jump;
        pose.mode = 'celebrate';
        pose.ballPos = [ballX, ballY];
        pose.bodyLean = 0;
        pose.armRaise = 1;
        pose.followThru = p;

        drawStickmanDynamic(ax, x, 0.38, 1.0, pose);
        drawBall(ax, ballX, ballY, 0.22);
        drawNetShake(ax, 1);

        % 地面撞击提示
        if p > 0.60 && p < 0.72
            plot(ax,[9.92 10.18],[0.48 0.48],'k-','LineWidth',1.4);
            plot(ax,[10.52 10.78],[0.48 0.48],'k-','LineWidth',1.4);
        end
    end

    title(ax,'MATLAB 黑色火柴人打篮球动画:快速动作 + 篮球掉落', ...
        'FontSize',18,'FontWeight','bold');

    drawnow;

    if exportGIF
        frame = getframe(fig);
        img = frame2im(frame);
        [A,map] = rgb2ind(img,256);

        if k == 1
            imwrite(A,map,gifName,'gif','LoopCount',inf,'DelayTime',1/fps);
        else
            imwrite(A,map,gifName,'gif','WriteMode','append','DelayTime',1/fps);
        end
    end
end

完整程序:

分享的文件:基于Matlab生成黑色火柴人运球 + 起跳 + 投篮动作.rar

链接: https://pan.baidu.com/s/1OG7qUyu8-gV8p_WRl95T7Q?pwd=ew6d

相关推荐
数智工坊4 小时前
机器人运动控制:采样、优化与学习三大流派深度对比与实战
android·学习·机器人
ZC跨境爬虫4 小时前
跟着 MDN 学JavaScript day_7:数学运算与逻辑判断实战测试
开发语言·前端·javascript·学习·ecmascript
神仙别闹7 小时前
基于 MATLAB DCT 的图像编码器并进行调试分析
matlab
MartinYeung57 小时前
[论文学习]隐私保护联邦特徵选择与差分隐私的的工程实践框架
学习
qeen877 小时前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
Flandern11118 小时前
Pull Requests(PR)
学习·github·pr
nashane9 小时前
HarmonyOS 6学习:JsCrash“闪退”法医指南——从FaultLog堆栈还原崩溃现场的终极手册
学习·华为·harmonyos
for_ever_love__9 小时前
UI学习:UICollectionView瀑布流
学习·ui·ios·objective-c·cocoa
AOwhisky9 小时前
MySQL 学习笔记(第六期):MySQL 备份与恢复
运维·数据库·笔记·学习·mysql·云计算
chhttty9 小时前
《Simulink嵌入式开发实战》新书上市
matlab·simulink