绘pyopengl实现两个小球的碰撞,蓄力提供初速度,无需考虑重力,给出代码和注释
时间: 2024-02-27 12:55:38 浏览: 144
下面是一个简单的PyOpenGL实现两个小球碰撞的代码,注释中会详细说明每一行代码的作用。
```python
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import math
# 球的半径
RADIUS = 0.1
# 球1的初始位置和速度
BALL1_POS = (-0.5, 0)
BALL1_SPEED = (0.05, 0)
# 球2的初始位置和速度
BALL2_POS = (0.5, 0)
BALL2_SPEED = (-0.03, 0)
# 碰撞后球的速度变化比例
SPEED_CHANGE_RATE = 0.8
# 窗口大小和位置
WINDOW_WIDTH, WINDOW_HEIGHT = 600, 400
WINDOW_X, WINDOW_Y = 100, 100
# 窗口刷新时间间隔(毫秒)
TIMER_INTERVAL = 30
def drawCircle(x, y, radius):
"""绘制一个圆形"""
glBegin(GL_TRIANGLE_FAN)
glVertex2f(x, y) # 中心点
for i in range(361):
angle = i * math.pi / 180
glVertex2f(x + math.sin(angle) * radius, y + math.cos(angle) * radius)
glEnd()
def draw():
"""绘制场景"""
glClear(GL_COLOR_BUFFER_BIT)
# 绘制球1
glColor3f(1, 0, 0) # 红色
drawCircle(*BALL1_POS, RADIUS)
# 绘制球2
glColor3f(0, 0, 1) # 蓝色
drawCircle(*BALL2_POS, RADIUS)
glutSwapBuffers()
def update():
"""更新球的位置和速度"""
global BALL1_POS, BALL1_SPEED, BALL2_POS, BALL2_SPEED
# 更新球1的位置
BALL1_POS = (BALL1_POS[0] + BALL1_SPEED[0], BALL1_POS[1] + BALL1_SPEED[1])
# 更新球2的位置
BALL2_POS = (BALL2_POS[0] + BALL2_SPEED[0], BALL2_POS[1] + BALL2_SPEED[1])
# 判断球1和球2是否碰撞
if math.sqrt((BALL1_POS[0] - BALL2_POS[0]) ** 2 + (BALL1_POS[1] - BALL2_POS[1]) ** 2) <= RADIUS * 2:
# 两球产生碰撞,更新球的速度
BALL1_SPEED = ((BALL1_SPEED[0] + BALL2_SPEED[0]) * SPEED_CHANGE_RATE, (BALL1_SPEED[1] + BALL2_SPEED[1]) * SPEED_CHANGE_RATE)
BALL2_SPEED = ((BALL2_SPEED[0] + BALL1_SPEED[0]) * SPEED_CHANGE_RATE, (BALL2_SPEED[1] + BALL1_SPEED[1]) * SPEED_CHANGE_RATE)
glutPostRedisplay()
def main():
"""程序入口"""
glutInit()
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE)
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT)
glutInitWindowPosition(WINDOW_X, WINDOW_Y)
glutCreateWindow("Bouncing Balls")
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(-1, 1, -1, 1)
glutDisplayFunc(draw)
glutTimerFunc(TIMER_INTERVAL, update, 0)
glutMainLoop()
if __name__ == '__main__':
main()
```
这个程序包含了两个小球的位置和速度,以及碰撞后的速度变化比例。程序的主要功能在`update`函数中实现,它会在每个时间间隔内更新球的位置和速度,并检查两球是否发生碰撞。如果发生碰撞,就更新两球的速度。
在`draw`函数中,我们使用了`glBegin`和`glEnd`函数来定义一个基本的图元,然后使用`glVertex2f`函数来指定图元的各个顶点坐标。这里我们使用了`GL_TRIANGLE_FAN`模式来绘制圆形。
在`main`函数中,我们初始化了OpenGL,并设置了窗口大小和位置。然后我们设置了投影矩阵和绘制函数,并使用`glutTimerFunc`函数来定时更新球的位置和速度。最后我们进入主循环,等待OpenGL事件的发生。
阅读全文