首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QuickDraw中的python3递归动画

QuickDraw中的python3递归动画
EN

Stack Overflow用户
提问于 2012-11-23 05:49:23
回答 1查看 1.2K关注 0票数 4

我有一个文本文件,里面有行星和它们对应的卫星/卫星,以及它们的轨道半径和周期,我想用它在quickdraw中创建一个类似于下面的动画:

文本文件如下:

代码语言:javascript
复制
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

我已经将我的原始代码(长得离谱)改成了这个更短的代码:(归功于sudo_O所有出色的help)

代码语言:javascript
复制
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)

我最大的问题是,我不知道如何编写代码从文件中导入数据,并通过recursion使用它来创建类似于所示动画的动画。我一直被告知,解决方案非常简单,代码实际上令人惊讶地短,但我不知道如何做到这一点,这实际上非常令人沮丧。

这是我的一个圆的代码,但它似乎太复杂了……

代码语言:javascript
复制
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

scale的代码:

代码语言:javascript
复制
scale=250/max([dict[planets]["Orbital Radius"] for x in dict if "Orbital Radius" in dict[planets]])

环绕行星运行的代码:

代码语言:javascript
复制
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

然而,这段代码不能很好地工作,作为一个初学者,我已经达到了这个问题的极限……

最后的努力!!这能行得通吗?

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-24 02:39:45

First problem递归-递归函数是调用自己的函数!这方面的一个简单示例是倒计时函数,例如:

代码语言:javascript
复制
def countdown(n):
    # counting down the recursive way! 
    if n > 0:
        print n
        countdown(n-1)
    else:
        return

调用countdown(10)将打印10, 9, 8,.., 2, 1

您可以看到,countdown被传递了一个数字n,它所做的就是打印这个数字,然后调用它自己,但这次传递的是n-1。只有在传递了n=0之后,它才不再需要做任何事情,所以每次递归调用都会被返回。对于您的字典情况(为避免混淆,我们称其为字典库),recursive打印方法为:

第一个dictionary.

  • Recursively调用本身,将整个库传递给打印routine.

  • Print,然后传递减去第一个字典的库。当库没有更多的词典可打印时,

  • 返回。

如下所示:

代码语言:javascript
复制
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)

下一步不是打印当前格式的字典,而是进行一些计算/转换,这样输出就是有效的quickdraw输入,就像使用quickdraw打印圆形的代码一样。

您将需要担心比例,以确保所有对象适合绘图表面找到具有最大Orbital Radius的天体,并使用它来计算比例。

使用类似于您的代码的列表理解,我们可以找到最大值:

代码语言:javascript
复制
max([planet[key]['Orbital Radius'] for key in planet])

>>> 8595000

scale = gridsize/max([planet[key]['Orbital Radius'] for key in planet])
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13520435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档