为什么三个行星(海龟)不能同时画出来?
Why can't the three planets(turtles) be drawn at the same time?
我写了一个python文件来模拟行星的轨道,但是我不能同时画出来。
turtle 文档说:"To use multiple turtles on a screen one has to use the object-oriented interface." 但是怎么做呢?
# -*- 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()
在移动到下一个之前,您正在为每个行星执行整个轨道。
您可以创建一个函数来执行交错的轨道:
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:
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)
此外,行星 class 可以跟踪 a
和 b
(需要更好的名字!)然后 orbit
函数就不需要这些值通过。这意味着 Planet
class 管理其数据和行为,这是面向对象设计的本质:
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)
到目前为止我和@PeterWood 在一起:
you could keep the planets in a list:
planets = [mercury, earth]
只有当此列表是 Planet
的 class 变量 并且在创建新行星的过程中自动更新时,这对我才有意义. IE。不是对象方法引用的外部实体!但即便如此,是太阳移动行星(通过列表)还是行星自己围绕太阳移动。
作为计时器事件的粉丝,我会以不同的方式处理这个问题。我允许行星加入而无需手动或以其他方式注册,再加上模拟行星不同速度的能力:
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()
这种方法在编码方面和现实方面都有其自身的问题,但它使事情变得相当简单并且有空间添加功能:
我写了一个python文件来模拟行星的轨道,但是我不能同时画出来。 turtle 文档说:"To use multiple turtles on a screen one has to use the object-oriented interface." 但是怎么做呢?
# -*- 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()
在移动到下一个之前,您正在为每个行星执行整个轨道。
您可以创建一个函数来执行交错的轨道:
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:
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)
此外,行星 class 可以跟踪 a
和 b
(需要更好的名字!)然后 orbit
函数就不需要这些值通过。这意味着 Planet
class 管理其数据和行为,这是面向对象设计的本质:
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)
到目前为止我和@PeterWood 在一起:
you could keep the planets in a list:
planets = [mercury, earth]
只有当此列表是 Planet
的 class 变量 并且在创建新行星的过程中自动更新时,这对我才有意义. IE。不是对象方法引用的外部实体!但即便如此,是太阳移动行星(通过列表)还是行星自己围绕太阳移动。
作为计时器事件的粉丝,我会以不同的方式处理这个问题。我允许行星加入而无需手动或以其他方式注册,再加上模拟行星不同速度的能力:
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()
这种方法在编码方面和现实方面都有其自身的问题,但它使事情变得相当简单并且有空间添加功能: