Python中的太阳能系统

问题描述 投票:0回答:1

我正在尝试使用turtle库在Python中创建一个非常简化的Solar System模型。地球,地球的航天器,火星和坐标系的中心-太阳。我发现了一个非常有用的video,它显示了在质心周围绘制椭圆的最简单方法,尽管我看到了很多缺点。例如,此处的方程式数学是不合逻辑的。

尽管,我对这个视频中不切实际的数字没有疑问(例如神秘的1000)。我只需要创建简化的轨道,它们就不必与现实世界中的轨道一样精确,因此上述视频中的代码就足够了。在开始时,我创建了一个仅火星和地球绕太阳运行的模拟:

import turtle
import math

mars = turtle.Turtle()
earth = turtle.Turtle()

def way_to_orbit(x,y, object, colors):
    object.dot(50, "yellow")
    object.color("white")
    object.fillcolor(colors)
    object.shape("circle")
    object.penup()
    object.setposition(x, y)
    object.pendown()


def ellipse(object1, object2):

    loop = True
    object2_xvel = 0
    object2_yvel = 1
    object1_xvel = 0
    object1_yvel = 1

    while loop:
        object2_xvel += math.cos(math.radians(object2.towards(0, 0))) * (1000 / (object2.xcor() ** 2 + object2.ycor() ** 2))
        object2_yvel += math.sin(math.radians(object2.towards(0, 0))) * (1000 / (object2.xcor() ** 2 + object2.ycor() ** 2))
        object2.setposition(object2.xcor() + object2_xvel, object2.ycor() + object2_yvel)

        object1_xvel += math.cos(math.radians(object1.towards(0, 0))) * (1000 / (object1.xcor() ** 2 + object1.ycor() ** 2))
        object1_yvel += math.sin(math.radians(object1.towards(0, 0))) * (1000 / (object1.xcor() ** 2 + object1.ycor() ** 2))
        object1.setposition(object1.xcor() + object1_xvel, object1.ycor() + object1_yvel)



way_to_orbit(620, 0, mars, "red")
way_to_orbit(375, 0, earth, "blue")

ellipse(mars, earth)


turtle.done()

输出是一个有两个行星的运动模拟:

仅与行星一起输出

“”

一切都很好,所以我决定增加航天器,绕地球运行。在这种情况下,在object2函数中,地球(object3)是航天器(ellipse)的质量中心:

import turtle
import math

mars = turtle.Turtle()
earth = turtle.Turtle()
spacecraft = turtle.Turtle()



def way_to_orbit(x,y, object, colors):
    object.dot(50, "yellow")
    object.color("white")
    object.fillcolor(colors)
    object.shape("circle")
    object.penup()
    object.setposition(x, y)
    object.pendown()


def ellipse(object1, object2, object3):

    loop = True
    object2_xvel = 0
    object2_yvel = 1
    object1_xvel = 0
    object1_yvel = 1
    object3_xvel = 0
    object3_yvel = 1
    a = 0
    while loop:
        object2_xvel += math.cos(math.radians(object2.towards(0, 0))) * (1000 / (object2.xcor() ** 2 + object2.ycor() ** 2))
        object2_yvel += math.sin(math.radians(object2.towards(0, 0))) * (1000 / (object2.xcor() ** 2 + object2.ycor() ** 2))
        object2.setposition(object2.xcor() + object2_xvel, object2.ycor() + object2_yvel)

        object1_xvel += math.cos(math.radians(object1.towards(0, 0))) * (1000 / (object1.xcor() ** 2 + object1.ycor() ** 2))
        object1_yvel += math.sin(math.radians(object1.towards(0, 0))) * (1000 / (object1.xcor() ** 2 + object1.ycor() ** 2))
        object1.setposition(object1.xcor() + object1_xvel, object1.ycor() + object1_yvel)

        # object3_xvel += math.cos(math.radians(object3.towards(object2.xcor(), object2.ycor()))) * (1000 / ((object3.xcor()**2)-(object2.xcor()**2)) + ((object3.ycor()**2)-(object2.ycor()**2)))
        # object3_yvel += math.sin(math.radians(object3.towards(object2.xcor(), object2.ycor()))) * (1000 / ((object3.xcor()**2)-(object2.xcor()**2)) + ((object3.ycor()**2)-(object2.ycor()**2)))
        # object3.setposition(object3.xcor() + object3_xvel, object3.ycor() + object3_yvel)


way_to_orbit(620, 0, mars, "red")
way_to_orbit(375, 0, earth, "blue")
way_to_orbit(376, 0, spacecraft, "green")

ellipse(mars, earth, spacecraft)


turtle.done()

输出是疯狂的:用航天器输出

“”

我不知道这里发生了什么。我只希望尽可能简单地对围绕太阳和两个卫星绕行的两个物体进行运动仿真。在这种情况下,物理定律是次要的,所有这一切都是出于其他目的。

  1. 所以,如何固定模拟太空飞船/卫星的海龟的路径?
  2. 有没有更简单或更快速的方法可以在Python中创建这种模拟?
  3. 有人可以为我解释视频中用于椭圆绘制的方法吗?
python simulation astronomy orbit
1个回答
0
投票

我不知道好的解决方案,但是我发现了两个问题和一个解决方案。

首先:earthmars在不移动的sun周围移动,但是spacecraft在正在移动的earth周围移动。您可以在计算earthxvel yvel之前使用spacecraftxvelyvel移动spacercraft-这样,您将获得像在不移动spacecraft的情况下移动earth一样的效果

object3.setposition(object3.xcor() + object2_xvel, object3.ycor() + object2_yvel)

第二:如果我将1000/constant用作spacecraft,则其移动看起来不错。正常的计算结果不准确,它们的每一步变化都很小,但最终变化太大,spacecraft消失了。我不知道此问题的更好解决方案。

spacecraftearth的距离在屏幕上正在改变,因为它以椭圆而不是圆形移动,但始终保持接近earth

while loop:
    distance = 1000 / (object2.xcor()**2 + object2.ycor()**2)
    rad = math.radians(object2.towards(0, 0))
    object2_xvel += math.cos(rad) * distance
    object2_yvel += math.sin(rad) * distance
    object2.setposition(object2.xcor() + object2_xvel, object2.ycor() + object2_yvel)

    distance = (1000 / (object1.xcor() ** 2 + object1.ycor() ** 2))
    rad = math.radians(object1.towards(0, 0))
    object1_xvel += math.cos(rad) * distance
    object1_yvel += math.sin(rad) * distance
    object1.setposition(object1.xcor() + object1_xvel, object1.ycor() + object1_yvel)

    # move `spacecraft` with `earth`
    object3.setposition(object3.xcor() + object2_xvel, object3.ycor() + object2_yvel)

    #distance = ( (object3.xcor()**2)-(object2.xcor()**2) ) + ( (object3.ycor()**2)-(object2.ycor()**2) )
    distance = 1000/3441 # constant value
    rad = math.radians(object3.towards(object2.xcor(), object2.ycor()))
    object3_xvel += math.cos(rad) * distance
    object3_yvel += math.sin(rad) * distance
    object3.setposition(object3.xcor() + object3_xvel, object3.ycor() + object3_yvel)

我设置了从spacecraftearth的更大距离,因为spacecraft椭圆非常平坦,并且通过earth移动了

way_to_orbit(375, 0, earth, "blue")
way_to_orbit(436, 0, spacecraft, "green")

完整代码

import turtle
import math

mars = turtle.Turtle()
earth = turtle.Turtle()
spacecraft = turtle.Turtle()


def way_to_orbit(x,y, object, colors):
    object.dot(50, "yellow")
    object.color("white")
    object.fillcolor(colors)
    object.shape("circle")
    object.penup()
    object.setposition(x, y)
    object.pendown()


def ellipse(object1, object2, object3):

    loop = True
    object2_xvel = 0
    object2_yvel = 1
    object1_xvel = 0
    object1_yvel = 1
    object3_xvel = 0
    object3_yvel = 1
    a = 0

    while loop:
        distance = 1000 / (object2.xcor()**2 + object2.ycor()**2)
        rad = math.radians(object2.towards(0, 0))
        object2_xvel += math.cos(rad) * distance
        object2_yvel += math.sin(rad) * distance
        object2.setposition(object2.xcor() + object2_xvel, object2.ycor() + object2_yvel)

        distance = (1000 / (object1.xcor() ** 2 + object1.ycor() ** 2))
        rad = math.radians(object1.towards(0, 0))
        object1_xvel += math.cos(rad) * distance
        object1_yvel += math.sin(rad) * distance
        object1.setposition(object1.xcor() + object1_xvel, object1.ycor() + object1_yvel)

        # move `spacecraft` with `earth`
        object3.setposition(object3.xcor() + object2_xvel, object3.ycor() + object2_yvel)

        #distance = ( (object3.xcor()**2)-(object2.xcor()**2) ) + ( (object3.ycor()**2)-(object2.ycor()**2) )
        distance = 1000/3441 # constant value
        rad = math.radians(object3.towards(object2.xcor(), object2.ycor()))
        object3_xvel += math.cos(rad) * distance
        object3_yvel += math.sin(rad) * distance
        object3.setposition(object3.xcor() + object3_xvel, object3.ycor() + object3_yvel)


way_to_orbit(620, 0, mars, "red")
way_to_orbit(375, 0, earth, "blue")
way_to_orbit(436, 0, spacecraft, "green")

ellipse(mars, earth, spacecraft)

turtle.done()

[很久以前,我做了类似的事情,但移到circles而不是eclipses,它看起来更好。

对于spacecraft,我使用值代替计算以获得更好的效果。每个对象向角度添加不同的值以产生不同的速度。

import turtle
import math

def move_to_orbit(x,y, item, color):
    item.dot(50, "yellow")
    item.color("white")
    item.fillcolor(color)
    item.shape("circle")
    item.penup()
    item.setposition(x, y)
    item.pendown()


def move_on_orbits(object1, object2, object3):

    object1_angle = 0
    object2_angle = 0
    object3_angle = 0

    while True:

        object1_angle += .2
        rad = math.radians(object1_angle)
        x = object1.xcor()
        y = object1.ycor()
        center_x = 0 # sun
        center_y = 0 # sun
        distance = ((x-center_x)**2 + (y-center_y)**2)**.5 # calculation are precise 
        #distance = 420 # distance to sun
        x = center_x + math.cos(rad) * distance 
        y = center_y + math.sin(rad) * distance
        object1.setposition(x, y)

        object2_angle += .1
        rad = math.radians(object2_angle)
        x = object2.xcor()
        y = object2.ycor()
        center_x = 0 # sun
        center_y = 0 # sun
        distance = ((x-center_x)**2 + (y-center_y)**2)**.5 # calculation are precise 
        #distance = 175 # distance to sun
        x = center_x + math.cos(rad) * distance 
        y = center_y + math.sin(rad) * distance
        object2.setposition(x, y)

        object3_angle += 2
        rad = math.radians(object3_angle)
        x = object3.xcor()
        y = object3.ycor()
        center_x = object2.xcor() # earth
        center_y = object2.ycor() # earth
        #distance = ((x-center_x)**2 + (y-center_y)**2)**.5 calculation are NOT precise
        distance = 30 # distance to earth
        x = center_x + math.cos(rad) * distance 
        y = center_y + math.sin(rad) * distance
        object3.setposition(x, y)


mars = turtle.Turtle()
earth = turtle.Turtle()
spacecraft = turtle.Turtle()


move_to_orbit(420, 0, mars, "red")
move_to_orbit(175, 0, earth, "blue")
move_to_orbit(205, 0, spacecraft, "green")

move_on_orbits(mars, earth, spacecraft)


turtle.done()
© www.soinside.com 2019 - 2024. All rights reserved.