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 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)
  • ¥20 怎么在stm32门禁成品上增加查询记录功能
  • ¥15 Source insight编写代码后使用CCS5.2版本import之后,代码跳到注释行里面
  • ¥50 NT4.0系统 STOP:0X0000007B
  • ¥15 想问一下stata17中这段代码哪里有问题呀
  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿