猫史档案馆


【Python作品分享】【120强进36】多体运动模拟器

用户:InkyRainInkyRain查看:0 回复:0 评论:0 创建时间:2021-05-16T20:32:20


【作品展示】

center_image

 

【作品介绍】

模拟宇宙天体引力

还是黑白风

界面tkinter

绘图turtle

可以粗略模拟宇宙天体

参加复赛

望喜欢

 

【作品源代码】

import turtle
import os
import tkinter
import numpy
from tkinter import filedialog
from tkinter import simpledialog
from tkinter import ttk

Name = ""
Way = ""
Pl = 1
G = 0.666
T = 1
M = [1]
X = [1]
Y = [1]
Vx = [1]
Vy = [1]

def run_un():
    global M
    global X 
    global Y 
    global Vx
    global Vy
    for i in range(len(M)): M[i] = float(M[i])
    for i in range(len(X)): X[i] = float(X[i])
    for i in range(len(Y)): Y[i] = float(Y[i])
    for i in range(len(Vx)): Vx[i] = float(Vx[i])
    for i in range(len(Vy)): Vy[i] = float(Vy[i])
    turtle.screensize(800,600, "black")
    R = [[0 for i in range(Pl)] for j in range(Pl)]
    F = [[0 for i in range(Pl)] for j in range(Pl)]
    A = [[0 for i in range(Pl)] for j in range(Pl)]
    AX = [0 for i in range(Pl)]
    AY = [0 for i in range(Pl)]
    PEN = [turtle.Pen() for i in range(Pl)]
    for i in range(Pl):
        PEN[i].pencolor("#ffffff")
        PEN[i].hideturtle()
    
    k = 0
    while True:
        
        for i in range(Pl):

            for j in range(Pl):
                if i != j:
                    R[i][j] = numpy.sqrt((X[i] - X[j])**2+(Y[i]-Y[j])**2)
            for j in range(Pl):
                if i != j:
                    A[i][j] = G*M[j]/(R[i][j]**2)
            for j in range(Pl):    
                if j!=i:
                    AX[i] = AX[i] + A[i][j]*(X[j]-X[i])/R[i][j]
                    AY[i] = AY[i] + A[i][j]*(Y[j]-Y[i])/R[i][j]
        for i in range(Pl):
            
            Vx[i] = Vx[i] + AX[i] * T
            Vy[i] = Vy[i] + AY[i] * T
            X[i] = X[i] + Vx[i] * T
            Y[i] = Y[i] + Vy[i] * T
            
            PEN[i].penup()
            PEN[i].setx(X[i])
            PEN[i].sety(Y[i])
            PEN[i].pendown()
            PEN[i].dot(7)
        k=k+1
            
            

def edit_un():
    edit_window = tkinter.Tk()
    edit_window.title("编辑宇宙")
    edit_window.geometry("500x600")
    edit_window.configure(bg='black')
    title_label = tkinter.Label(edit_window, text="编辑宇宙", font=("宋体-简", 50), fg="white", background="black")
    title_label.pack()
    def edit_G():
        global G 
        G = simpledialog.askfloat('编辑引力常量', '', initialvalue=0.0000000000667)
    editG_button = tkinter.Button(edit_window, text ="编辑引力常量", font=("宋体-简", 30), width = 30, command=edit_G)
    editG_button.pack()
    def edit_T():
        global T
        T = simpledialog.askfloat('编辑精度', '精度越小越精准,但计算时间长', initialvalue=1)
    editT_button = tkinter.Button(edit_window, text ="编辑精度", font=("宋体-简", 30), width = 30, command=edit_T)
    editT_button.pack()
    columns = ("编号", "质量", "X坐标", "Y坐标", "X速度", "Y速度")
    planet_form = ttk.Treeview(edit_window, height=10, show="headings", columns=columns)
    planet_form.column("编号", width=50, anchor='center')
    planet_form.column("质量", width=80, anchor='center')
    planet_form.column("X坐标", width=80, anchor='center')
    planet_form.column("Y坐标", width=80, anchor='center')
    planet_form.column("X速度", width=80, anchor='center')
    planet_form.column("Y速度", width=80, anchor='center')
    planet_form.heading("编号", text="编号")
    planet_form.heading("质量", text="质量")
    planet_form.heading("X坐标", text="X坐标")
    planet_form.heading("Y坐标", text="Y坐标")
    planet_form.heading("X速度", text="X速度")
    planet_form.heading("Y速度", text="Y速度")
    planet_form.pack()
    for i in range(Pl):
        planet_form.insert('', i, values=(i+1, M[i], X[i], Y[i], Vx[i], Vy[i]))
    def del_pl():
        del_pl_num = simpledialog.askinteger('删除天体', '删除的天体的编号:')
        global Pl
        if del_pl_num == True and del_pl_num <= Pl and del_pl_num > 0: 
            Pl = Pl - 1
            global M
            del M[del_pl_num-1]
            global X
            del X[del_pl_num-1]
            global Y
            del Y[del_pl_num-1]
            global Vx
            del Vx[del_pl_num-1]
            global Vy
            del Vy[del_pl_num-1]
            edit_un()
            edit_window.quit()
    del_button = tkinter.Button(edit_window, text ="删除天体", font=("宋体-简", 30), width = 30, command=del_pl)
    del_button.pack()
    def new_pl():
        global Pl
        Pl=Pl+1
        global M
        M.append(simpledialog.askfloat('新的天体', '新的天体的质量:'))
        global X
        X.append(simpledialog.askfloat('新的天体', '新的天体的X坐标:'))
        global Y
        Y.append(simpledialog.askfloat('新的天体', '新的天体的Y坐标:'))
        global Vx
        Vx.append(simpledialog.askfloat('新的天体', '新的天体的X速度:'))
        global Vy
        Vy.append(simpledialog.askfloat('新的天体', '新的天体的Y速度:'))
        edit_un()
        edit_window.quit()

    new_button = tkinter.Button(edit_window, text ="新的天体", font=("宋体-简", 30), width = 30, command=new_pl)
    new_button.pack()
    def save_un():
        file = open(Name, 'w+')
        file.write(str(Pl).replace('[', "").replace(']', "").replace("'", "")+'\n')
        file.write(str(G).replace('[', "").replace(']', "").replace("'", "")+'\n')
        file.write(str(T).replace('[', "").replace(']', "").replace("'", "")+'\n')
        file.write(str(M).replace('[', "").replace(']', "").replace("'", "")+'\n')
        file.write(str(X).replace('[', "").replace(']', "").replace("'", "")+'\n')
        file.write(str(Y).replace('[', "").replace(']', "").replace("'", "")+'\n')
        file.write(str(Vx).replace('[', "").replace(']', "").replace("'", "")+'\n')
        file.write(str(Vy).replace('[', "").replace(']', "").replace("'", "")+'\n')
        file.close()
    save_button = tkinter.Button(edit_window, text ="保存", font=("宋体-简", 30), width = 30, command=save_un)
    save_button.pack()
    run_button = tkinter.Button(edit_window, text ="开始", font=("宋体-简", 30), width = 30, command=run_un)
    run_button.pack()
    back_button = tkinter.Button(edit_window, text ="返回", font=("宋体-简", 30), width = 30, command=create_main_window)
    back_button.pack()
    edit_window.mainloop()


def create_un():
    create_window = tkinter.Tk()
    create_window.title('创建新的宇宙')
    create_window.geometry("500x500")
    create_window.configure(bg='black')
    title_label = tkinter.Label(create_window, text="创建新的宇宙", font=("宋体-简", 50), fg="white", background="black")
    title_label.pack()
    name_label = tkinter.Label(create_window, text="文件名:", font=("宋体-简", 30), fg="white", background="black")
    name_label.pack()
    filename_entry = tkinter.Entry(create_window, width = 40, font=("宋体-简", 20))
    filename_entry.pack()
    way_label = tkinter.Label(create_window, text="保存路径:", font=("宋体-简", 30), fg="white", background="black")
    way_label.pack()
    fileway_entry = tkinter.Entry(create_window, width = 40, font=("宋体-简", 20))
    fileway_entry.pack()
    def choose_way():
        global Way
        Way = filedialog.askdirectory()
        fileway_entry.select_clear()
        fileway_entry.insert(0, Way)
    choose_button = tkinter.Button(create_window, text ="选择路径", font=("宋体-简", 30), width = 30, command=choose_way)
    choose_button.pack()
    n_label = tkinter.Label(create_window, text="", font=("宋体-简", 10), fg="white", background="black")
    n_label.pack()
    def create():
        global Name
        Name = filename_entry.get()
        global Way
        Way = fileway_entry.get()
        os.chdir(Way)
        file = open(Name, 'w+')
        file.write(str(Pl)+'\n')
        file.write(str(G)+'\n')
        file.write(str(T)+'\n')
        file.write(str(M)+'\n')
        file.write(str(X)+'\n')
        file.write(str(Y)+'\n')
        file.write(str(Vx)+'\n')
        file.write(str(Vy)+'\n')
        file.close()
        edit_un()
    create_button = tkinter.Button(create_window, text ="创建", font=("宋体-简", 30), width = 30, command=create)
    create_button.pack()
    back_button = tkinter.Button(create_window, text ="返回", font=("宋体-简", 30), width = 30, command=create_main_window)
    back_button.pack()
    create_window.mainloop()

def moban_un():
    return

def open_un():
    open_window = tkinter.Tk()
    open_window.title("打开我的宇宙")
    open_window.geometry("500x500")
    open_window.configure(bg='black')
    title_label = tkinter.Label(open_window, text="打开我的宇宙", font=("宋体-简", 50), fg="white", background="black")
    title_label.pack()
    name_label = tkinter.Label(open_window, text="文件名:", font=("宋体-简", 30), fg="white", background="black")
    name_label.pack()
    filename_entry = tkinter.Entry(open_window, width = 40, font=("宋体-简", 20))
    filename_entry.pack()
    way_label = tkinter.Label(open_window, text="打开文件夹:", font=("宋体-简", 30), fg="white", background="black")
    way_label.pack()
    fileway_entry = tkinter.Entry(open_window, width = 40, font=("宋体-简", 20))
    fileway_entry.pack()
    def choose_way():
        global Way
        Way = filedialog.askdirectory()
        fileway_entry.select_clear()
        fileway_entry.insert(0, Way)
    choose_button = tkinter.Button(open_window, text ="选择路径", font=("宋体-简", 30), width = 30, command=choose_way)
    choose_button.pack()
    n_label = tkinter.Label(open_window, text="", font=("宋体-简", 10), fg="white", background="black")
    n_label.pack()
    def open_file():
        global Name
        Name = filename_entry.get()
        global Way
        Way = fileway_entry.get()
        os.chdir(Way)
        file = open(Name, 'a+')
        file.seek(0)
        file_lines = file.readlines()
        global Pl
        Pl = int(file_lines[0].replace('\n', ''))
        global G
        G = float(file_lines[1].replace('\n', ''))
        global T
        T = float(file_lines[2].replace('\n', ''))
        global M 
        M = file_lines[3].replace('\n', '').split(",")
        for i in range(len(M)): float(M[i])
        global X
        X = file_lines[4].replace('\n', '').split(",")
        for i in range(len(X)): float(M[i])
        global Y
        Y = file_lines[5].replace('\n', '').split(",")
        for i in range(len(Y)): float(M[i])
        global Vx
        Vx = file_lines[6].replace('\n', '').split(",")
        for i in range(len(Vx)): float(M[i])
        global Vy
        Vy = file_lines[7].replace('\n', '').split(",")
        for i in range(len(Vy)): float(M[i])
        file.close()
        edit_un()
    open_button = tkinter.Button(open_window, text ="打开", font=("宋体-简", 30), width = 30, command=open_file)
    open_button.pack()
    back_button = tkinter.Button(open_window, text ="返回", font=("宋体-简", 30), width = 30, command=create_main_window)
    back_button.pack()
    open_window.mainloop()

def teach():
    return

def about():
    return

def create_main_window():
    main_window = tkinter.Tk()
    main_window.title("多体运动模拟器")
    main_window.geometry("500x500")
    main_window.configure(bg='black')
    title_label = tkinter.Label(main_window, text="多体运动模拟器", font=("宋体-简", 50), fg="white", background="black")
    title_label.pack()
    create_button = tkinter.Button(main_window, text ="创建新的宇宙", font=("宋体-简", 30), width = 30, command=create_un)
    create_button.pack()
    moban_button = tkinter.Button(main_window, text ="选择模版宇宙", font=("宋体-简", 30), width = 30, command=moban_un)
    moban_button.pack()
    open_button = tkinter.Button(main_window, text ="打开我的宇宙", font=("宋体-简", 30), width = 30, command=open_un)
    open_button.pack()
    teach_button = tkinter.Button(main_window, text ="教程", font=("宋体-简", 30), width = 30, command=teach)
    teach_button.pack()
    about_button = tkinter.Button(main_window, text ="关于", font=("宋体-简", 30), width = 30, command=about)
    about_button.pack()
    main_window.mainloop()

    

create_main_window()

 

【提示】

部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:

https://python.codemao.cn


回复

上一页1 页 / 共 0下一页