[英]python3 recursion animation in QuickDraw
I have a text file which has the planets and their corresponding moons/satellites along with their orbital radius and period and I would like to use this to create an animation in quickdraw
similar to the one below: 我有一个有行星及其相应卫星的文本文件/他们的轨道半径和时段,以及我沿着卫星想用这个来创建一个动画quickdraw
类似下面的一个:
The text file is as followed: 文本文件如下:
RootObject: Sun
Object: Sun
Satellites: Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris
Radius: 20890260
Orbital Radius: 0
Object: Miranda
Orbital Radius: 5822550
Radius: 23500
Period: 1.413
Object: Ariel
Orbital Radius: 8595000
Radius: 60000
Period: 2.520379
Object: Umbriel
Orbital Radius: 11983500
Radius: 60000
Period: 4.144177
Object: Titania
Orbital Radius: 19575000
Radius: 75000
Period: 8.7058
Object: Oberon
Orbital Radius: 26235000
Radius: 75000
Period: 13.463
Object: Uranus
Orbital Radius: 453572956
Radius: 2555900
Period: 30799
Satellites: Puck,Miranda,Ariel,Umbriel,Titania,Oberon
Object: Neptune
Orbital Radius: 550000000
Radius: 2476400
Period: 60190
Satellites: Triton
Object: Triton
Orbital Radius: 40000000
Radius: 135300
Period: -5.8
Object: Mercury
Orbital Radius: 38001200
Period: 87.9691
Radius: 243900.7
Object: Venus
Orbital Radius: 57477000
Period: 224.698
Radius: 605100.8
Object: Earth
Orbital Radius: 77098290
Period: 365.256363004
Radius: 637100.0
Satellites: Moon
Object: Moon
Orbital Radius: 18128500
Radius: 173700.10
Period: 27.321582
Object: Mars
Orbital Radius: 106669000
Period: 686.971
Radius: 339600.2
Satellites: Phobos,Deimos
Object: Phobos
Orbital Radius: 3623500.6
Radius: 200000
Period: 0.31891023
Object: Deimos
Orbital Radius: 8346000
Period: 1.26244
Radius: 200000.2
Object: Jupiter
Orbital Radius: 210573600
Period: 4332.59
Radius: 7149200
Satellites: Io,Europa,Ganymede,Callisto
Object: Ceres
Orbital Radius: 130995855
Period: 1679.67
Radius: 48700
Object: Io
Orbital Radius: 22000000
Period: 1.7691377186
Radius: 182100.3
Object: Europa
Orbital Radius: 36486200
Period: 3.551181
Radius: 156000.8
Object: Ganymede
Orbital Radius: 47160000
Period: 7.15455296
Radius: 263400
Object: Callisto
Orbital Radius: 69700000
Period: 16.6890184
Radius: 241000
Object: Saturn
Orbital Radius: 353572956
Period: 10759.22
Radius: 6026800
Satellites: Mimas,Enceladus,Tethys,Dione,Rhea,Titan,Iapetus
Object: Mimas
Orbital Radius: 8433396
Radius: 20600
Period: 0.9
Object: Enceladus
Orbital Radius: 10706000
Radius: 25000
Period: 1.4
Object: Tethys
Orbital Radius: 13706000
Radius: 50000
Period: 1.9
Object: Dione
Orbital Radius: 17106000
Radius: 56000
Period: 2.7
Object: Rhea
Orbital Radius: 24000000
Radius: 75000
Period: 4.5
Object: Titan
Orbital Radius: 50706000
Radius: 257600
Period: 15.945
Object: Iapetus
Radius: 75000
Orbital Radius: 72285891
Period: 79
I've changed my original code (which was ridiculously longer) to this shorter one: (credit to sudo_O for all his awesome help ) 我把原来的代码(这个时间长得太长了)改成了这个较短的代码:(感谢sudo_O提供了所有他非常棒的帮助 )
file = open("data1.txt","r")
def data(file):
d = {}
for line in file:
if line.strip() != '':
key,value = line.split(":")
if key == 'RootObject':
continue
if key == 'Object':
obj = value.strip()
d[obj]={}
else:
d[obj][key] = value.strip()
return d
planets = data(file)
print(planets)
My biggest problem is that I don't know how to write code that imports the data from the file and utilizes it through recursion
to create an animation similar to the one shown. 我最大的问题是我不知道如何编写从文件导入数据的代码,并通过recursion
利用它来创建类似于所示的动画。 I keep getting told that the solution is quite simple and the code is actually surprisingly short but I have no idea how to do it and it's actually very frustrating. 我不断被告知解决方案非常简单,而且代码实际上非常简短,但我不知道如何做到这一点,实际上非常令人沮丧。
Here is my code for a circle orbiting a circle but it seems too complicated... 这是我围绕圆圈运行的圆圈的代码,但它似乎太复杂了......
import math
print("circle",400,300,50)
print("flush false")
centreX=400
centreY=300
radius=100
angle=math.pi/2
while True:
print("color 0 0 0")
print("clear")
print("color 255 0 255")
print("circle",centreX,centreY,radius)
childX=math.sin(angle)*radius*1.5+centreX
childY=math.cos(angle)*radius*1.5+centreY
print("circle",childX,childY,radius/2)
print("refresh")
angle+=0.01
code for scale: 规模代码:
scale=250/max([dict[planets]["Orbital Radius"] for x in dict if "Orbital Radius" in dict[planets]])
Code for orbiting planets: 轨道行星代码:
print("flush false")
scale=250/max([dict[planets]["Orbital Radius"] for x in dict if "Orbital Radius" in dict[planets]])
t=0
x=400
y=300
while True:
print("refresh")
print("colour 0 0 0")
print("clear")
print("colour 255 255 255")
print("fillcircle",x,y,dict['Sun']['Radius']*scale)
print("text ", "\"Sun\"",x+dict['Sun']['Radius']*scale,y)
r_earth=dict['Earth']['Orbital Radius']*scale;
print("circle",x,y,r_earth)
r_X=x+math.sin(t*2*math.pi/dict['Earth']['Period'])*r_earth
r_Y=y+math.cos(t*2*math.pi/dict['Earth']['Period'])*r_earth
print("fillcircle",r_X,r_Y,dict['Earth']['Radius']*scale)
print("text ", "\"Earth\"",r_X+dict['Earth']['Radius']*scale,r_Y)
t+=0.02
this code does not work very well however and as a beginner, I am at my limits for this problem... 这段代码不能很好地工作,但作为一个初学者,我对这个问题的极限......
last ditch effort !! 最后的努力!! would this could work? 这会起作用吗?
print("flush false")
scale = 250/max([dict[planets]["Orbital Radius"] for x in dict if "Orbital Radius" in dict[planets]])
t = 0
x = 400
y = 300
print("fillcircle",400,300,dict['Sun']['Radius']*scale)
print("text ", "\"Sun\"",x+dict['Sun']['Radius']*scale,y)
while True:
r_new = dict['Object']['Orbital Radius']*scale
print("circle",x,y,r_new)
r_X = x + math.sin(t*2*math.pi/dict['Object']['Period'])*r_new
r_Y = y + math.cos(t*2*math.pi/dict['Object']['Period'])*r_new
print("fillcircle",r_X,r_Y,dict['Object']['Radius']*scale)
print("text ",Object,r_X+dict['Object']['Radius']*scale,r_Y)
t += 0.02
if planets['Object']['Satellites'] = 0
return
else:
r_sat = dict['Object']['Satellites']['Orbital Radius']*scale
print("circle",x,y,r_sat)
r_satX = x + math.sin(t*2*math.pi/dict['Object']['Satellites']['Period'])*r_sat
r_satY = y + math.cos(t*2*math.pi/dict['Object']['Satellites']['Period'])*r_sat
print("fillcircle",r_satX,r_satY,dict['Object']['Satellites']['Radius']*scale)
print("text ",['Object']['Satellites'],r_satX+dict['Object']['Satellites']['Radius']*scale,r_satY)
t += 0.02
First problem recursion - a recursive function is one that calls itself! 第一个问题递归 - 递归函数是一个自我调用的函数! A simple example of this is a countdown function such as: 一个简单的例子是倒计时功能,例如:
def countdown(n):
# counting down the recursive way!
if n > 0:
print n
countdown(n-1)
else:
return
Calling countdown(10)
will print 10, 9, 8,.., 2, 1
. 调用countdown(10)
将打印10, 9, 8,.., 2, 1
。
You can see that countdown
is passed a number n
and all it does is prints that number and then calls itself but passing n-1
this time. 您可以看到countdown
传递了一个数字n
,它所做的就是打印该数字,然后自己调用,但这次传递n-1
。 Only once n=0
is passed will it not have anything left to do so each recursive call is returned. 只有在n=0
才会传递它没有任何事情要做,所以返回每个递归调用。 For your dictionary of dictionaries case (lets call it a library of dictionaries to avoid confusion) a recursive
printing approach would be: 对于你的字典词典案例(让我们称之为词典库以避免混淆) , recursive
打印方法将是:
Something like this: 像这样的东西:
def recursive_print(dic):
if len(dic) > 0: # If dictionaries in library > 0
print dic.keys()[0] # Print the key i.e Earth
print dic[dic.keys()[0]] # Print the dictionary value for i.e Earth
dic.popitem() # Remove the Earth dictionary from library
recursive_print(dic) # Recursive call
else:
return # Printed all, return up the stack.
planets = data(file)
recursive_print(planets)
The next step would be instead of printing the dictionaries in there current format you would do some calculations/conversion so the output is valid quickdraw
input, like the code you have already for printing circles using quickdraw
. 下一步是不是以当前格式打印字典,而是进行一些计算/转换,因此输出是有效的quickdraw
输入,就像你已经使用quickdraw
打印圆圈的代码quickdraw
。
You will need to worry about the scale, to ensure all objects fit on the drawing surface find the celestial body with the largest Orbital Radius
and use that to calculate the scale. 您将需要担心比例,以确保所有对象适合绘图表面找到具有最大Orbital Radius
的天体并使用它来计算比例。
Using list comprehension similar to your code we can find the largest value: 使用类似于您的代码的列表理解,我们可以找到最大的值:
max([planet[key]['Orbital Radius'] for key in planet])
>>> 8595000
scale = gridsize/max([planet[key]['Orbital Radius'] for key in planet])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.