我写了一个python文件来模拟行星的轨道,但是我不能同时绘制它们。 乌龟文档说:“要在屏幕上使用多只乌龟,必须使用面向对象的界面。”但是该怎么做?
# -*- coding:utf-8 -*-
import math
import turtle
#define a class of planets, which rotate in a oval
class Planet(turtle.Turtle):
def orbit(self, a, b, t):
c = math.sqrt(a ** 2 - b ** 2)
self.goto(a * math.cos(t / 200) + c, b * math.sin(t / 200))
def Sun():
sun.color('yellow')
sun.pd()
sun.showturtle()
for t in range(1000):
sun.orbit(0, 0, t)
def Mercury():
mercury.color('blue')
mercury.speed(0)
mercury.pu()
mercury.goto(50+math.sqrt(50 ** 2 - 49.9 ** 2), 0)
mercury.pd()
mercury.showturtle()
mercury.lt(90)
for t in range(1000):
mercury.orbit(50, 49.9, t)
def Earth():
earth.color('red')
earth.speed(0)
earth.pu()
earth.goto(75+math.sqrt(75 ** 2 - 74.9 ** 2), 0)
earth.pd()
earth.showturtle()
earth.lt(90)
for t in range(1000):
earth.orbit(75, 74.9,t)
sun = Planet(shape='circle')
mercury = Planet(shape='circle')
earth = Planet(shape='circle')
turtle.Screen().ontimer(Sun, 100)
turtle.Screen().ontimer(Mercury, 100)
turtle.Screen().ontimer(Earth, 100)
turtle.Screen().mainloop()
答案 0 :(得分:0)
您正在移动每个行星的整个轨道,然后再移动到下一行星。
您可以创建一个函数来执行交织的轨道:
def orbit_planets():
for t in range(1000):
mercury.orbit(50, 49.9, t)
earth.orbit(75, 74.9,t)
turtle.Screen().ontimer(orbit_planets, 100)
您还需要从行星功能中删除轨道代码。 同样,行星函数只需要调用一次即可初始化其位置。
但是,您可以将此代码放入Planet
类中:
class Planet(turtle.Turtle):
def __init__(self, colour, a, b):
turtle.Turtle.__init__(self)
self.color(colour)
self.speed(0)
self.pu()
self.goto(a + math.sqrt(a ** 2 - b ** 2), 0)
self.pd()
self.showturtle()
self.lt(90)
...
然后:
mercury = Planet('blue', 50, 49.9)
earth = Planet('red', 75, 74.9)
另外,行星类可以跟踪a
和b
(需要更好的名称!),然后orbit
函数不需要传递值。这意味着Planet
类管理其数据和行为,这是面向对象设计的本质:
def __init__(self, a, b):
...
self.a = a
self.b = b
和:
def orbit(self, t):
c = math.sqrt(self.a ** 2 - self.b ** 2)
self.goto(self.a * math.cos(t / 200) + c,
self.b * math.sin(t / 200))
然后,轨道计时器功能将是:
def orbit_planets():
for t in range(1000):
mercury.orbit(t)
earth.orbit(t)
再进一步,您可以将行星列在列表中:
planets = [mercury, earth]
def orbit_planets():
for t in range(1000):
for planet in planets:
planet.orbit(t)
答案 1 :(得分:0)
到目前为止,我与@PeterWood在一起:
您可以将行星列入清单:
行星= [汞,地球]
仅当此列表是Planet
的类变量且由创建新行星的过程自动更新时,这对我才有意义。即不是由对象方法引用的外部实体!但是即使那样,太阳还是会(通过列表)移动行星,还是行星绕着太阳自身移动。
作为计时器事件的粉丝,我会采取不同的方式。我将允许行星加入而无需手动或其他方式进行注册,并添加了模拟行星不同速度的功能:
from math import sqrt, cos, sin, pi
from turtle import Screen, Turtle
class Star(Turtle):
def __init__(self, colour):
super().__init__(shape='circle')
self.color(colour)
class Planet(Turtle):
def __init__(self, colour, a, b, period):
super().__init__(shape='circle')
self.color(colour)
self.a = a
self.b = b
self.period = period
self.t = 0
self.speed('fastest')
self.shapesize(0.25)
self.penup()
self.orbit()
self.pendown()
def orbit(self):
c = sqrt(self.a ** 2 - self.b ** 2)
angle = self.t / (2 * pi)
self.goto(self.a * cos(angle) + c, self.b * sin(angle))
self.t += 1
screen.ontimer(self.orbit, self.period)
screen = Screen()
sun = Star('yellow')
mercury = Planet('blue', 50, 49.9, 88)
earth = Planet('red', 75, 74.9, 365)
screen.mainloop()
这种方法在编码方面和在现实方面都有其自身的问题,但它使事情变得相当简单,并具有添加功能的空间: