Python 设计真实反弹球算法及原理分析 (使用物理定律)

2023-11-18

文章简单地使用物理定律, 编写程序模拟真实世界中的碰撞。
在开始正式讲解之前, 先看这两个代码:

# 把球掉头
ball.speed[0] = -ball.speed[0]
ball.speed[1] = -ball.speed[1]

可以看到, 这个代码直接把球的速度反了一下, 比较粗糙。
这是提升的版本 (真实世界中两个球质量相同时,是这个样子):

# 这里用 speed表示速度
self.speed,other.speed = other.speed,self.speed # 把两个球进行速度交换

运行效果:
球

更精确的算法

前面两种算法, 都还不能很好地模拟真实世界中的碰撞。
由于我们模拟的是弹性碰撞, 碰撞前后两球的总动量守恒,总动能也守恒。
根据动量p=mv, 动能E=mv2 / 2,
可以推导出以下公式:(v1, v2是两小球的速度, m1,m2是质量, v1’ , v2’ 是碰撞后的速度)


根据这个公式, 就可以设计相应的程序。
使用pygame设计的完整代码如下:

import sys, pygame,math,time
from random import *

__version__='1.1'
class Ball(pygame.sprite.Sprite):
    def __init__(self, image, location, speed,mass=1):
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = location
        self.pos = location
        self.speed = speed
        self.m = mass

    def move(self):
        self.pos = (self.pos[0]+self.speed[0],self.pos[1]+self.speed[1])
        self.rect.left,self.rect.top = self.pos

        # 检查有无撞到窗口
        if self.rect.left <= 0:
            self.speed[0] = abs(self.speed[0])
        elif self.rect.right >= width:
            self.speed[0] = -abs(self.speed[0])
        if self.rect.top <= 0:
            self.speed[1] = abs(self.speed[1])
        elif self.rect.bottom >= height:
            self.speed[1] = -abs(self.speed[1])
    def distance(self,other):
        dx=other.rect.left-self.rect.left
        dy=other.rect.top-self.rect.top
        return math.hypot(dx,dy)
    def collide(self,other):
        # 反弹球算法部分
        m1=self.m;m2=other.m
        dx1 = (m1-m2)/(m1+m2)*self.speed[0] + 2*m2/(m2+m1)*other.speed[0]
        dy1 = (m1-m2)/(m1+m2)*self.speed[1] + 2*m2/(m2+m1)*other.speed[1]
        dx2 = (m2-m1)/(m1+m2)*other.speed[0] + 2*m1/(m2+m1)*self.speed[0]
        dy2 = (m2-m1)/(m1+m2)*other.speed[1] + 2*m1/(m2+m1)*self.speed[1]
        self.speed=[dx1, dy1]
        other.speed=[dx2, dy2]

animate()函数更新一次小球在屏幕上的位置,
state用于记录球的碰撞信息, 避免球重复碰撞 (也可以使用更好的代码)。

state = {}
def animate(group):
    rect=pygame.rect.Rect((0,0),(width,height))
    screen.fill((255,255,255),rect)
    global ball
    for ball in group:
        ball.move()
    for i in range(len(group)):
        ball=group[i]
        for j in range(i):
            other=group[j]
            collided = ball.distance(other) < ball.rect.width
            # 避免球重复碰撞
            if i!=j:
                if collided and not state.get((i,j),0):
                    ball.collide(other)
                    state[(i,j)] = 1
                elif not collided:
                    state[(i,j)] = 0

        screen.blit(ball.image, ball.rect)
    pygame.display.flip()

使用pygame的主程序的实现:

size = width,height = 640, 480
screen = pygame.display.set_mode(size,pygame.RESIZABLE)
screen.fill((255, 255, 255))
image = pygame.image.load("beach_ball.png")
clock = pygame.time.Clock()
group = []
for row in range(3):
    for column in range(3):
        location = [column * 180 + 50, row * 120 + 50]
        speed = [randrange(-4,5), randrange(-4,5)]
        ball = Ball(image,location, speed)
        group.append(ball)

主事件循环, 每循环一次就调用一次(也可以是多次) animate()函数, 刷新一次小球位置:

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            frame_rate = clock.get_fps()
            print("frame rate = ", frame_rate)
            running = False
        elif event.type == pygame.VIDEORESIZE:
            width,height = event.size
            screen = pygame.display.set_mode(event.size, pygame.RESIZABLE)
    animate(group)
    clock.tick(60)
pygame.quit()

程序运行效果:
球

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 设计真实反弹球算法及原理分析 (使用物理定律) 的相关文章

随机推荐

  • silk lobe资源公众号_资源合集

    11 月 十一月 iOS内置韩文字体 Apple SD Gothic Neo 锤子 黑 Smartisan 与方正合作定制的UI黑体 Emoji 鸽了好久的可爱 Emoji 字体 移植到安卓手机 沙扬娜拉 岩田仿宋 复古聚珍仿宋风格 返璞归
  • chatgpt赋能python:Python如何优化中文SEO

    Python如何优化中文SEO Python 作为一种流行的编程语言 可以用来开发各种不同的应用程序 当涉及到网络营销和搜索引擎优化 SEO 时 Python的功能也非常有用 在本篇文章中 我们将介绍如何使用Python来优化中文SEO 以
  • opencv显示对比

    在opencv中我们一般都要展示处理前后图像的对比 有时候我们会imshow两次来展示两张图片 那为什么我们不放在一个图片里呢 这样显然是更加优雅的模式 上代码 Mat combineImage Mat before Mat after a
  • Go语言实现Onvif客户端:4、配置网络信息

    Go语言实现Onvif客户端 4 配置网络信息 文章目录 Go语言实现Onvif客户端 4 配置网络信息 1 思路 2 代码 上一节获取到网络接口token后 就可进行一些网络配置了 这里我们暂时只实现进行ip地址的配置接口和封装 1 思路
  • 【SpringCloud】pom.xml文件解析

    本文档为本人学习交流所用 参考原文档 https www cnblogs com hoyong articles 13034270 html 1 pom xml是什么 pom是Project Object Model 项目对象模型 的缩写
  • 虚表

    虚表 虚函数表 C 中 一个类存在虚函数 那么编译器就会为这个类生成一个虚函数表 在虚函数表里存放的是这个类所有虚函数的地址 虚表从属于类 编译器会为包含虚函数的类加上一个成员变量 该成员变量是一个指向虚函数表的指针 因此虚表指针是一个成员
  • UE4安卓打包配置(大陆内网络整顿后,Android打包时AndroidWorks无法使用的解决方法)

    由于国内进行了网络整顿 UE4官网上用CodeWorksforAndroid下载安卓打包工具配置的方法已经不能使用了 开了VPN也链接不上 这使得用UE4打包配置安卓游戏变得非常麻烦 博主捣鼓了好几天才打包成功 深感在中国学习UE4的艰难与
  • 力扣-图解算法数据结构-剑指 Offer 05. 替换空格

    题目要求 力扣题解 代码 program mydemo description 剑指 Offer 05 替换空格 author Mr zeng create 2021 03 05 11 04 public class Solution1 p
  • @escook/request-miniprogram基于 Promise 的小程序网路请求库

    安装 npm install escook request miniprogram 导入 按需导入 http 对象 import http from escook request miniprogram 将按需导入的 http 挂载到 wx
  • 静态资源存放的位置

    存放的四个位置 classpath META INF resources classpath resources classpath static classpath public 如果要访问的话 是当前项目的根路径 静态资源名 因为这个图
  • C#中浮点数的比较

    前几天去面试 被问到怎么比较两个浮点数的大小 当时只说了个大概 看得出来面试官不是太满意 回来特意查了一下 在MSDN上发现了比较浮点数是否相等的不错的方法 Initialize two doubles with apparently id
  • 接口测试用例设计 - 实战篇

    目录 一 接口测试流程 二 分析接口文档中哪些元素 三 如何设计接口测试用例 3 1 为什么要设计测试用例 3 2 设计接口测试用例从哪些方面考虑 四 常用的接口测试用例覆盖方法 五 接口测试的接口优先级 5 1 优先级 针对所有接口 5
  • MATLAB代码显示内存不足的解决方法

    总结了下大家对于运行MATLAB代码 显示内存不足的问题 在网上进行调研 总结如下 一般out of memenry存在以下几种情况 1 变量需要的存储空间超过了可用的内存空间 2 数据需要的存储空间 超过内存中最大的可用连续存储空间 3
  • 最大子列和问题【简单易懂】

    问题 给定N个整数的序列 求函数的最大值 算法一 例如序列为 1 2 3 4 所以子列分别为 1 1 2 1 2 3 1 2 3 4 2 2 3 2 3 4 3 3 4 4 我们要做的就是依次将这些子列的和求出并比较 得出最大子列和 首先将
  • 2020算法设计与分析 官方考前模拟卷 参考答案

    算法设计与分析 样例试题 算法设计与分析总结笔记 注 此试题仅供了解题型 和期末考试试题没有任何直接关系 FBI Warning 这套题难度较大 千万不要坏了心态 xj大佬说要是考试那么难他直播粪坑蝶泳 Power By 王宏志教授 5 分
  • matlab的tfdata函数_matlab 入门基本操作命令与函数

    一 tf 函数 是传递函数的意思 一般学自动控制原理的时候经常用 在s域中 比如你要输入G s 1 s 2 2s 1 就可以在matlab中输入G tf 1 1 2 1 就OK了 不懂的话你可以在command窗口输入help tf 就行了
  • 为什么使用start方法启动Java的Thread线程?

    一 简介 在Java代码当中 当我们需要开启子线程去处理一些任务的时候 往往是调用Thread对象的start方法 这样Thread实例中的Runnable对象的run方法就会在一个新的线程当中执行 创建一个线程 Thread thread
  • 从注意力机制到Vison Transformer

    原视频链接 https www bilibili com video BV1Jh411Y7WQ spm id from 333 788 vd source f04f16dd6fd058b8328c67a3e064abd5 https www
  • 【Zabbix实战之运维篇】Zabbix的客户端自动注册配置

    Zabbix实战之运维篇 Zabbix的客户端自动注册配置 一 自动注册与自动发现介绍 1 自动注册介绍 2 自动发现介绍 3 主动模式与被动模式 二 客户端安装abbix agent2 1 下载zabbix agent2软件包 2 安装z
  • Python 设计真实反弹球算法及原理分析 (使用物理定律)

    文章简单地使用物理定律 编写程序模拟真实世界中的碰撞 在开始正式讲解之前 先看这两个代码 把球掉头 ball speed 0 ball speed 0 ball speed 1 ball speed 1 可以看到 这个代码直接把球的速度反了