Python 更改海龟图形的操作
首先,我对编程非常陌生,在这里我吃不完。无论如何 我正在尝试用python作为模型构建太阳系/轨道模拟 这是我的完整代码:Python 更改海龟图形的操作,python,python-3.x,simulation,turtle-graphics,Python,Python 3.x,Simulation,Turtle Graphics,首先,我对编程非常陌生,在这里我吃不完。无论如何 我正在尝试用python作为模型构建太阳系/轨道模拟 这是我的完整代码: # Import math and turtle import math from turtle import * import turtle # Gravitational Constant G = 6.67428e-11 # Scale: 1 pixel = 1 astronomical unit # 1 astronomical unit = 1 AU = 14959
# Import math and turtle
import math
from turtle import *
import turtle
# Gravitational Constant
G = 6.67428e-11
# Scale: 1 pixel = 1 astronomical unit
# 1 astronomical unit = 1 AU = 149597900 km
AU = (149.6e6 * 1000) # 149.6 million km in meters
Scale = 250 / AU
wn = turtle.Screen()
wn = turtle.bgcolor('black')
class body(Turtle):
# Subclass of turtle representing a body
# Additional attributes:
# mass in kg
# vx, vy: x, y velocities in m/sc
# px, py: x, y positions in m
# Set background to black
# Turtle.bgcolor('black')
name = 'body'
mass = None
vx = vy = 0.0
px = py = 0.0
def attraction(self, other):
# (body): (fx, fy)
# returns the force exerted on this body by the other body.
# Report and error if the other object is the same as this one.
if self is other:
raise ValueError("Attraction of object %r to itself requested" % self.name)
# Compute the distance of the other body:
sx, sy = self.px, self.py
ox, oy = other.px, other.py
dx = (ox - sx)
dy = (oy - sy)
d = math.sqrt(dx**2 + dy**2)
# Report an Error if the distance is 0
# ZeroDivisionError would happen later otherwise
if d == 0:
raise ValueError("Collision between objects %r and %r" % (self.name, other.name))
# Compute the force of attraction
f = G * self.mass * other.mass / (d**2)
# Compute the direction of the force
theta = math.atan2(dy, dx)
fx = math.cos(theta) * f
fy = math.sin(theta) * f
return fx, fy
def updateInfo(step, bodies):
# (int, [body])
# Displays infomation about status of simulation.
print('Step #{}'.format(step))
for body in bodies:
s = '{:<8} Pos.={:>6.2f} Vel.={:>10.3f}'.format(body.name, body.px/AU, body.py/AU, body.vy)
print(s)
print()
def loop(bodies):
# (body)
# Never returns; loop through the simulation and updates the positions of given bodies
timestep = 24*3600 # One Day
for body in bodies:
body.penup()
body.hideturtle()
step = 1
while True:
updateInfo(step, bodies)
step += 1
force = {}
for body in bodies:
# Adds all the forces exerted on a body
totalFx = totalFy = 0.0
for other in bodies:
# Don't calculate attraction to itself
if body is other:
continue
fx, fy = body.attraction(other)
totalFx += fx
totalFy += fy
# Record the total force exerted
force[body] = (totalFx, totalFy)
# Update velocities based on the force.
for body in bodies:
fx, fy = force[body]
body.vx += fx / body.mass * timestep
body.vy += fy / body.mass * timestep
# Update positions
body.px += body.vx * timestep
body.py += body.vy * timestep
body.goto(body.px*Scale, body.py*Scale)
body.dot(5)
def main():
sun = body()
sun.name = 'Sun'
sun.mass = 1.98892 * 10**30
sun.pencolor('yellow')
earth = body()
earth.name = 'Earth'
earth.mass = 5.9742 * 10**24
earth.px = -1*AU
earth.vy = 29.783 * 1000
earth.pencolor('blue')
venus = body()
venus.name = 'Venus'
venus.mass = 4.8685 * 10**24
venus.px = 0.723 * AU
venus.vy = -35.02 * 1000
venus.pencolor('orange')
loop([sun, earth, venus])
if __name__ == '__main__':
main()
#导入数学和乌龟
输入数学
从海龟进口*
进口海龟
#引力常数
G=6.67428e-11
#比例:1像素=1天文单位
#1天文单位=1 AU=149597900公里
AU=(149.6e6*1000)#1.496亿公里(米)
刻度=250/AU
wn=tutle.Screen()
wn=turtle.bgcolor('black')
团体(海龟):
#代表身体的海龟的亚纲
#其他属性:
#质量(kg)
#vx,vy:x,y速度,单位为m/sc
#px,py:x,y位置,单位为m
#将背景设置为黑色
#Turtle.bgcolor('black'))
名称='body'
质量=无
vx=vy=0.0
px=py=0.0
def吸引力(自身、其他):
#(正文):(外汇,财政年度)
#返回另一个实体施加在该实体上的力。
#如果另一个对象与此对象相同,则报告和错误。
如果self是他者:
raise VALUERROR(“请求将对象%r吸引到自身”%self.name)
#计算另一个实体的距离:
sx,sy=self.px,self.py
ox,oy=other.px,other.py
dx=(ox-sx)
dy=(oy-sy)
d=数学sqrt(dx**2+dy**2)
#如果距离为0,则报告错误
#否则,错误将在稍后发生
如果d==0:
raise VALUERROR(“对象%r和%r”%(self.name,other.name)之间的冲突”)
#计算吸引力
f=G*自身质量*其他质量/(d**2)
#计算力的方向
θ=math.atan2(dy,dx)
fx=数学cos(θ)*f
fy=数学sin(θ)*f
外汇收益,财政年度
def updateInfo(步骤,正文):
#(国际,[正文])
#显示有关模拟状态的信息。
打印('Step{}'。格式(Step))
对于身体中的身体:
格式(body.name,body.px/AU,body.py/AU,body.vy)
印刷品
打印()
def回路(主体):
#(正文)
#永不回头;循环模拟并更新给定实体的位置
时间步长=24*3600#一天
对于身体中的身体:
body.penup()
body.hideturtle()
步骤=1
尽管如此:
更新信息(步骤、正文)
步骤+=1
力={}
对于身体中的身体:
#添加施加在实体上的所有力
totalFx=totalFy=0.0
其他机构:
#不要计算对自己的吸引力
如果主体是其他主体:
持续
fx,fy=身体吸引力(其他)
totalFx+=fx
总fy+=fy
#记录施加的总力
力[体]=(totalFx,totalFy)
#基于力更新速度。
对于身体中的身体:
fx,fy=力[体]
body.vx+=fx/body.mass*timestep
body.vy+=fy/body.mass*timestep
#更新职位
body.px+=body.vx*timestep
body.py+=body.vy*timestep
body.goto(body.px*比例,body.py*比例)
正文.dot(5)
def main():
太阳=身体()
sun.name='sun'
太阳质量=1.98892*10**30
太阳色(“黄色”)
地球=身体()
earth.name='earth'
地球质量=5.9742*10**24
earth.px=-1*AU
earth.vy=29.783*1000
地球。铅笔颜色(“蓝色”)
维纳斯=身体()
venus.name='venus'
金星质量=4.8685*10**24
venus.px=0.723*AU
venus.vy=-35.02*1000
维纳斯。铅笔颜色(“橙色”)
环([太阳、地球、金星])
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
我为我的窗口添加了一行
import-turtle
,因为我想将窗口颜色更改为黑色。我知道这两种进口风格之间的主要区别,以及为什么有些人喜欢其中一种而不是另一种(或者为什么其中一种不好)。我想改变类的结构,这样我就可以对模拟的图形有更多的控制权,同时也可以远离from x import*
方法。欢迎任何意见 我的选择是使用导入:
from turtle import Screen, Turtle
通过阻塞功能接口来强制面向对象接口。但我会更进一步:
fx, fy = force[body]
body.vx += fx / body.mass * timestep
body.vy += fy / body.mass * timestep
# Update positions
body.px += body.vx * timestep
body.py += body.vy * timestep
海龟可以使用向量(Vec2D
),所以我们不需要对x和y值进行单独的操作
for body in bodies:
body.penup()
body.hideturtle()
这可以是主体
类初始值设定项的一部分
body.goto(body.px*Scale, body.py*Scale)
我们可以预先缩放海龟的坐标系,避免在主循环中进行缩放操作
while True:
不是在像turtle这样的事件驱动世界中——而是使用ontimer()
。以下返工实现了上述建议,以说明如何解决此问题:
# Import math and turtle
import math
from turtle import Screen, Turtle, Vec2D
# Gravitational Constant
G = 6.67428e-11
# Scale: 1 pixel = 1 astronomical unit
# 1 astronomical unit = 1 AU = 149597900 km
AU = 149.6e6 * 1000 # 149.6 million km in meters
TIME_STEP = 24 * 3600 # One day
FORMAT = "{:<8} Pos.={:>6.2f} Vel.={:>10.3f}"
CURSOR_SIZE = 20
class Body(Turtle):
''' Subclass of turtle representing a body. '''
# Additional attributes:
# mass in kg
# velocity in m/sc
# position in m
name = 'body'
mass = None
velocity = Vec2D(0.0, 0.0)
Position = Vec2D(0.0, 0.0) # Position to avoid conflict with turtle's position() method
def __init__(self, dot_size=5):
super().__init__(shape='circle')
self.shapesize(dot_size / CURSOR_SIZE)
self.penup()
def attraction(self, other):
''' Return the force exerted on this body by the other body. '''
# Report an error if the other object is the same as this one.
if self is other:
raise ValueError("Attraction of object {} to itself requested".format(self.name))
# Compute the distance of the other body:
dx, dy = other.Position - self.Position
distance = math.sqrt(dx**2 + dy**2)
# Report an Error if the distance is 0
# ZeroDivisionError would happen later otherwise
if distance == 0:
raise ValueError("Collision between objects {} and {}".format(self.name, other.name))
# Compute the force of attraction
force = G * self.mass * other.mass / distance**2
# Compute the direction of the force
theta = math.atan2(dy, dx)
direction = Vec2D(math.cos(theta), math.sin(theta))
return direction * force
def updateInfo(step: int, bodies: list):
''' Display information about status of simulation. '''
print('Step #{}'.format(step))
for body in bodies:
print(FORMAT.format(body.name, abs(body.Position * (1 / AU)), abs(body.velocity)))
print()
def single_step(bodies, step=1):
''' Step through the simulation and updates the positions of given bodies. '''
updateInfo(step, bodies)
for body in bodies:
# Adds all the forces exerted on a body
totalForce = Vec2D(0.0, 0.0)
for other in bodies:
# Don't calculate attraction to itself
if body is not other:
totalForce += body.attraction(other)
# Update velocities based on the force.
body.velocity += totalForce * (1 / body.mass) * TIME_STEP
# Update position
body.Position += body.velocity * TIME_STEP
body.setposition(body.Position)
screen.update()
screen.ontimer(lambda: single_step(bodies, step + 1))
if __name__ == '__main__':
screen = Screen()
screen.bgcolor('black')
screen.setworldcoordinates(-2 * AU, -2 * AU, 2 * AU, 2 * AU)
screen.tracer(False)
sun = Body(10)
sun.name = 'Sun'
sun.mass = 1.98892 * 10**30
sun.color('yellow')
earth = Body()
earth.name = 'Earth'
earth.mass = 5.9742 * 10**24
earth.Position = Vec2D(-AU, 0.0)
earth.velocity = Vec2D(0.0, 29.783 * 1000)
earth.color('blue')
venus = Body()
venus.name = 'Venus'
venus.mass = 4.8685 * 10**24
venus.Position = Vec2D(0.723 * AU, 0.0)
venus.velocity = Vec2D(0.0, -35.02 * 1000)
venus.color('orange')
single_step([sun, earth, venus])
screen.mainloop()
#导入数学和乌龟
输入数学
从turtle导入屏幕,turtle,Vec2D
#引力常数
G=6.67428e-11
#比例:1像素=1天文单位
#1天文单位=1 AU=149597900公里
AU=149.6e6*1000#14960万公里(米)
时间步长=24*3600#一天
FORMAT=“{:6.2f}级别={:>10.3f}”
光标大小=20
团体(海龟):
“代表身体的海龟的亚类”
#其他属性:
#质量(kg)
#速度单位:m/sc
#以m表示的位置
名称='body'
质量=无
速度=Vec2D(0.0,0.0)
Position=Vec2D(0.0,0.0)#避免与海龟Position()方法冲突的位置
定义初始值(自身,点大小=5):
超级()
self.shapesize(点大小/光标大小)
self.penup()
def吸引力(自身、其他):
“返回另一个物体施加在这个物体上的力”
#如果另一个对象与此对象相同,则报告错误。
如果self是他者:
提高价值错误(“obje的吸引力