m0_57990220 2021-07-04 22:13 采纳率: 50%
浏览 44
已采纳

有没有老哥会做这个跳动皮球的程序

img

  • 写回答

1条回答 默认 最新

  • hxycsdn9159 2021-07-05 09:54
    关注

    这个应该不难吧?学过物理的话应该很简单的吧

    效果图给你:

    img

    代码:

        public class SportBall
        {
            public SportBall(double mass, double energyLoss, double vx, double h, Point axisOrigin, Color c)
            {
                // 质量
                Mass = mass;
                // 每次撞击动能损失
                KineticEnergyLoss = energyLoss;
                // 水平方向初速度
                Vx = vx;
                // 初始高度
                InitHeight = h;
                // 由自由落体运动公式根据初始高度h计算初次落地时竖直方向速度
                Vy = Math.Sqrt(2 * h / g);
    
                // 总能量 = 动能 + 重力势能
                TotalEmergy = 0.5 * Mass * vx * vx + Mass * g * h;
    
                AxisOrigin = axisOrigin;
                BallColor = c;
                // 记录轨迹点
                pathList = new List<PointF>();
                pathList.Add(new PointF((float)(AxisOrigin.X + BallDiameter / 2), (float)(AxisOrigin.Y - BallDiameter / 2)));
            }
    
            #region 运动相关
            // 重力加速度g 9.8m/s^2
            private const double g = 98;
            // 每个阶段竖直上抛运动时长
            private double t0y;
            // 每一帧时刻
            private double t0x;
            // 质量 单位:kg
            public double Mass { get; private set; }
            // 每次撞击动能损失 单位:J
            public double KineticEnergyLoss { get; private set; }
            // 总能量
            public double TotalEmergy { get; private set; }
            // 初始高度
            public double InitHeight { get; private set; }
            // 相对于坐标系水平方向位移
            public double HorizontalDisplacement { get; private set; }
            // 相对于坐标系竖直方向位移
            public double VerticalDisplacement { get; private set; }
            // 每个阶段竖直上抛运动竖直方向初速度
            public double Vy { get; private set; }
            // 每个阶段竖直上抛运动水平方向初速度
            public double Vx { get; private set; }
    
            // y方向速度
            public double Vy_R { get; private set; }
            // x方向速度
            public double Vx_R { get; private set; }
            #endregion
    
            #region 外观相关
            // 球体颜色
            public Color BallColor { get; set; }
            // 球体直径
            public double BallDiameter { get; set; }
            #endregion
    
            #region 坐标系相关
            public Point AxisOrigin { get; private set; }
            #endregion
    
            List<PointF> pathList;
    
            // 开始运动
            public void StartSport(double timeSpan)
            {
    
                // 将毫秒换算成秒
                double ts = timeSpan / 1000;
                // 如果能量消耗完停止运动
                if (TotalEmergy <= 0) return;
    
                //1.水平方向做匀速直线运动
                HorizontalDisplacement += UniformSpeed(ts - t0x, Vx);
                t0x = ts;
    
                double displacement = ThrowUp(ts - t0y, Vy);
                if (displacement <= 0)
                {
                    Collision();
                    t0y = ts;
                }
                else
                {
                    VerticalDisplacement = displacement;
                }
            }
    
            private double UniformSpeed(double t, double vx)
            {
                Vx_R = vx;
                return vx * t;
            }
    
            // 竖直上抛运动
            private double ThrowUp(double t, double v0)
            {
                Vy_R = v0 - g * t;
                return v0 * t - 0.5 * g * t * t;
            }
            // 碰撞
            private void Collision()
            {
                double newEnergy = TotalEmergy - KineticEnergyLoss;
                double rate = newEnergy / TotalEmergy;
                TotalEmergy = newEnergy;
                // 撞击之后根据损失后的总能量计算水平方向速度以及数值方向初速度
                Vx = Vx * rate;
                Vy = Math.Sqrt(2 * (TotalEmergy - 0.5 * Mass * Vx * Vx) / Mass);
            }
    
            public void Draw(Graphics g)
            {
                DrawAxis(g);
                DrawBall(g);
                DrawPath(g);
            }
            // 画球
            private void DrawBall(Graphics g)
            {
                if (BallDiameter <= 0) BallDiameter = 10;
                if (BallColor == null) BallColor = Color.Red;
                if (AxisOrigin == null) AxisOrigin = new Point(0, 0);
                double x = AxisOrigin.X + HorizontalDisplacement - BallDiameter / 2;
                double y = AxisOrigin.Y - VerticalDisplacement - BallDiameter / 2;
                g.FillEllipse(new SolidBrush(BallColor), (float)x, (float)y, (float)BallDiameter, (float)BallDiameter);
                pathList.Add(new PointF((float)(x + BallDiameter / 2), (float)(y + BallDiameter / 2)));
            }
            // 画坐标轴
            private void DrawAxis(Graphics g)
            {
                g.DrawLine(new Pen(new SolidBrush(Color.Black)), AxisOrigin.X, AxisOrigin.Y, (float)(HorizontalDisplacement + 200), AxisOrigin.Y);
                g.DrawLine(new Pen(new SolidBrush(Color.Black)), AxisOrigin.X, AxisOrigin.Y, AxisOrigin.X, (float)(AxisOrigin.Y - InitHeight - 50));
            }
            // 画运动轨迹
            private void DrawPath(Graphics g)
            {
                g.DrawLines(new Pen(new SolidBrush(Color.Black)), pathList.ToArray());
            }
        }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 7月9日

悬赏问题

  • ¥15 宇视监控服务器无法登录
  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据
  • ¥15 (关键词-阻抗匹配,HFSS,RFID标签天线)