前言
这一章学习了面向对象编程,需要掌握的内容包括:会调用对象的方法和属性;如何编写类。
这一章课程中有个模拟双星运行的小程序,为了增进理解,我改了改代码,成了模拟三星运行。
为什么使用面向对象
完成一些简单任务时,使用面向对象常常会需要写更多的代码,那我们为什么要使用面向对象呢?
由于面向对象的一些特性 (这里不细说),我们可以设计出低耦合的系统,更容易修改和维护
三星运行模拟
我们把星球作为对象,设计一个星球类,类中就包含了星球的一些性质。然后在主程序中调用星球的方法,让它自己的事情自己做。
模拟三星运行时遇到了一些问题,常常几个星球跑不了一会儿就飞开了。
在多次调整参数后,它才终于可以多一起运行一会而,最终被我调成了类似恒星系的结构(有一个大质量的中心星球)。本来是想试试能不能出现三体那种效果的。
定义星球类
import math class Planet: Number = 0 def __init__(self, color, mass, position, v_init): Planet.Number += 1 self.color = color self.mass = mass self.x, self.y = position self.vx, self.vy = v_init def v_change(self, f, t=1e-3): fx, fy = f ax, ay = fx / self.mass, fy / self.mass self.vx += ax * t self.vy += ay * t def p_change(self, t=1e-3): self.x += self.vx * t self.y += self.vy * t def gravity(self, other_planet): distance = math.sqrt((self.x - other_planet.x) ** 2 + (self.y - other_planet.y) ** 2) f = self.mass * other_planet.mass / (distance ** 2) fx = (other_planet.x - self.x) / distance * f fy = (other_planet.y - self.y) / distance * f return fx, fy
主程序
import matplotlib.pyplot as plt from matplotlib import animation fig = plt.figure() point_1 = Planet('r', 100, (-3, -3), (0, 0.3)) point_2 = Planet('r', 10, (5, -5), (0, -3)) point_3 = Planet('r', 0.1, (0, 10), (3, 0)) def animate(i): fig.clear() for _ in range(500): f_21 = point_1.gravity(point_2) f_31 = point_1.gravity(point_3) f_12 = point_2.gravity(point_1) f_32 = point_2.gravity(point_3) f_13 = point_3.gravity(point_1) f_23 = point_3.gravity(point_2) point_1.p_change() point_1.v_change(f_21) point_1.v_change(f_31) point_2.p_change() point_2.v_change(f_12) point_2.v_change(f_32) point_3.p_change() point_3.v_change(f_13) point_3.v_change(f_23) plt.scatter(point_1.x, point_1.y, c='r') # 红色星球 plt.scatter(point_2.x, point_2.y, c='b') # 蓝色星球 plt.scatter(point_3.x, point_3.y, c='g') # 绿色星球 plt.xlim(-20, 20) plt.ylim(-20, 20) plt.draw() ani = animation.FuncAnimation(fig=fig, func=animate, frames=100, interval=1, blit=False) plt.show()