本章我们将实现互相作用的圆球,如图所示。首先实现多个随机的圆球,为圆球之间增加作用力,使其均匀分布到一个大圆内;然后实现鼠标交互,并能实现不同半径的圆球;最后学习函数的定义与使用,改进实现的代码。
最终代码:
balls = [] # 存储所有圆球的全局变量,初始为空列表
def setup():
size(800, 800) # 设定画布大小
noStroke() # 不绘制线条
def draw():
background(30) # 黑灰色背景
for i in range(len(balls)):
fx = 0 # 第i号圆球,x方向所受合力
fy = 0 # 第i号圆球,y方向所受合力
for j in range(len(balls)): # 对其他所有球遍历
if (i!=j): # 对于不等于i的j
dx = balls[j][0] - balls[i][0] # 两个小球x坐标差
dy = balls[j][1] - balls[i][1] # 两个小球y坐标差
distance = sqrt(dx*dx + dy*dy) # 两个小球间的距离
if distance < 1: # 防止距离过小,有除0的风险
distance = 1
# j号球对i号球的作用力大小
f_mag = (distance - 300)* balls[j][4]
fx += f_mag*dx/distance # 求出x方向的受力,加到fx上
fy += f_mag*dy/distance # 求出y方向的受力,加到fy上
ax = fx/balls[i][4] *0.05 # 合力除以质量,计算两个方向的加速度
ay = fy/balls[i][4] *0.05
balls[i][2] = 0.99*balls[i][2] + 0.01*ax # 根据加速度更新速度
balls[i][3] = 0.99*balls[i][3] + 0.01*ay
for ball in balls: # 对所有圆球遍历
ball[0] += ball[2] # 根据x方向速度,更新x坐标
ball[1] += ball[3] # 根据y方向速度,更新y坐标
fill(ball[5],230) # 设置填充颜色
circle(ball[0], ball[1], 2*ball[4]) # 画一个圆
def addBall(): # 添加一个新的圆球
radius = random(5,20) # 随机半径
# 随机颜色
c = color(random(100,255),random(100,255),random(100,255))
# ball = [x坐标,y坐标,x方向速度,y方向速度,半径,颜色]
ball = [mouseX,mouseY,0,0,radius,c] # 当前圆球列表
balls.append(ball) # 把圆球添加到balls中
def mousePressed(): # 鼠标点击时
addBall() # 添加一个新的圆球
def mouseDragged(): # 鼠标拖拽时
if frameCount % 5 == 0: # 防止添加过多圆球
addBall() # 添加一个新的圆球
def keyPressed(): # 当按下任意键盘按键时
global balls # 全局变量
if len(balls)>0: # 如果blls列表不为空
balls = [] # 清空所有圆球
实现效果:
练习:在画布中生成随机的圆,并保证所有圆不相交。
这一章主要讲解了无参数函数的定义、复合运算符等语法知识,实现了互相作用的圆球。用好函数可以避免程序开发的重复劳动,读者也可以尝试用函数改进之前章节实现的案例。