QuickDraw中的python3递归动画 [英] python3 recursion animation in QuickDraw

查看:96
本文介绍了QuickDraw中的python3递归动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文本文件,其中包含行星及其相应的卫星/卫星以及它们的轨道半径和周期,我想用它在 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:

文本文件如下:

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)

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 利用它来创建类似于所示动画。我一直被告知该解决方案非常简单,并且代码实际上很短,但是我不知道该怎么做,而且实际上非常令人沮丧。

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. 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

比例尺代码:

scale=250/max([dict[planets]["Orbital Radius"] for x in dict if "Orbital Radius" in dict[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

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

您可以看到倒计时传递了数字 n 及其所做的只是打印该数字,然后调用自身,但这次传递 n-1 。仅一旦传递 n = 0 ,它便无事可做,因此将返回每个递归调用。对于您的词典字典案例(为了避免混淆,可以将其称为词典库) 递归打印方法为:

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. Only once n=0 is passed will it not have anything left to do so each recursive call is returned. For your dictionary of dictionaries case (lets call it a library of dictionaries to avoid confusion) a recursive printing approach would be:


  1. 将整个库传递到打印例程。

  2. 打印第一个词典。

  3. 递归调用自身,并通过库减去第一个字典。

  4. 当图书馆没有更多可打印的字典时返回。

  1. Pass the whole library to the printing routine.
  2. Print the first dictionary.
  3. Recursively call itself and pass the library minus the first dictionary.
  4. Return when the library has no more dictionaries to print.

类似以下内容:

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 打印圈子了。

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.

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

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.

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

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])

这篇关于QuickDraw中的python3递归动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆