试图让圆点绕更大的圆点

Trying to make dots orbit bigger dot

所以我一直在尝试让一些点不仅朝向一个圆圈而且还使它们绕着圆圈旋转。为此,我使用了余弦和正弦,但是我 运行 遇到了让点向前移动以及设置它们的距离的问题。使用下面的代码,点能够围绕较大的点形成一个圆圈,并跟随它,但它们不会接近该点,当坐标按与 t1 的距离缩放时,它们也不会到达该位置,而是做时髦的事情。这是特指行

t2.goto(2 * (t1.xcor() + math.degrees(math.cos(math.radians(t1.towards(t2)))) // 1), 2 * (t1.ycor() + math.degrees(math.sin(math.radians(t1.towards(t2)))) // 1))

我已经替换为:

t2.goto(dist * (t1.xcor() + math.degrees(math.cos(math.radians(t1.towards(t2)))) // 1), dist * (t1.ycor() + math.degrees(math.sin(math.radians(t1.towards(t2)))) // 1))

这让我零星地看到那些点试图跟随更大的点。

这一行是在 follow() 函数中找到的。 Create() 生成较小的点,move() 移动较大的点,而 grow() 在与较小的点碰撞时增大较大的点。 Produce() 和 redraw() 应该是程序的第 2 阶段,但这些功能与问题无关。最后,quit() 只是退出 Screen() 并退出程序。

感谢 cdlane 帮助组织数据和更有效地更新屏幕。

截至目前的代码:

from turtle import Turtle, Screen
import sys
import math

CURSOR_SIZE = 20


def move(x, y):
    """ has it follow cursor """

    t1.ondrag(None)

    t1.goto(x, y)

    screen.update()

    t1.ondrag(move)

def grow():
    """ grows t1 shape """

    global t1_size, g

    t1_size += 0.1
    t1.shapesize(t1_size / CURSOR_SIZE)
    g -= .1
    t1.color((r/255, g/255, b/255))

    screen.update()

def follow():
    """ has create()'d dots follow t1 """

    global circles, dist

    new_circles = []

    for (x, y), stamp in circles:

        t2.clearstamp(stamp)

        t2.goto(x, y)

        dist = t2.distance(t1) / 57.29577951308232 // 1
        t2.goto(2 * (t1.xcor() + math.degrees(math.cos(math.radians(t1.towards(t2)))) // 1), 2 * (t1.ycor() + math.degrees(math.sin(math.radians(t1.towards(t2)))) // 1))

        t2.setheading(t2.towards(t1))

        if t2.distance(t1) < t1_size // 1:
            if t2.distance(t1) > t1_size * 1.2:
                t2.forward(500/t2.distance(t1)//1)
            else:
                t2.forward(3)





        if t2.distance(t1) > t1_size // 2:
            new_circles.append((t2.position(), t2.stamp())) 
        else:
            grow()  # we ate one, make t1 fatter

    screen.update()

    circles = new_circles

    if circles:
        screen.ontimer(follow, 10)
    else:
        phase = 1
        produce()

def create():
    """ create()'s dots with t2 """

    count = 0
    nux, nuy = -400, 300

    while nuy > -400:
        t2.goto(nux, nuy)

        if t2.distance(t1) > t1_size // 2:
            circles.append((t2.position(), t2.stamp()))

        nux += 20
        count += 1
        if count == 40:
            nuy -= 50
            nux = -400
            count = 0

    screen.update()

def quit():
    screen.bye()
    sys.exit(0)

def redraw():
    t2.color("black")
    t2.shapesize((t2_size + 4) / CURSOR_SIZE)
    t2.stamp()
    t2.shapesize((t2_size + 2) / CURSOR_SIZE)
    t2.color("white")
    t2.stamp()

def produce():
    #create boundary of star
    global t2_size, ironmax
    t1.ondrag(None)
    t1.ht()
    t2.goto(t1.xcor(), t1.ycor())
    t2.color("black")
    t2.shapesize((t1_size + 4) / CURSOR_SIZE)
    t2.stamp()
    t2.shapesize((t1_size + 2) / CURSOR_SIZE)
    t2.color("white")
    t2.stamp()
    #start producing helium
    while t2_size < t1_size:

        t2.color("#ffff00")
        t2.shapesize(t2_size / 20)
        t2.stamp()
        t2_size += .1
        redraw()
        screen.update()
        ironmax = t2_size
        t2_size = 4
    while t2_size < ironmax:
        t2.shapesize(t2_size / 20)
        t2.color("grey")
        t2.stamp()
        t2_size += .1
        screen.update()


# variables
t1_size = 6
circles = []
phase = 0


screen = Screen()
screen.screensize(900, 900)
#screen.mode("standard")


t2 = Turtle('circle', visible=False)
t2.shapesize(4 / CURSOR_SIZE)
t2.speed('fastest')
t2.color('purple')
t2.penup()
t2_size = 4

t1 = Turtle('circle')
t1.shapesize(t1_size / CURSOR_SIZE)
t1.speed('fastest')
r = 190
g = 100
b = 190
t1.color((r/255, g/255, b/255))
t1.penup()

t1.ondrag(move)

screen.tracer(False)

screen.listen()
screen.onkeypress(quit, "Escape")

create()

follow()
#print(phase)

screen.mainloop()

我对此又进行了一次破解,只是研究了流星围绕行星的问题。或者在这种情况下,月亮,因为我选择了 Deimos 作为我的模型。我试图按比例工作,使坐标系 1 像素 = 1 公里。一开始,Deimos 坐在一片流星中,每颗流星都有一个随机的方向,但它们的大小和速度都相同:

from turtle import Turtle, Screen
from random import random

METEOR_VELOCITY = 0.011  # kilometers per second

METEOR_RADIUS = 0.5  # kilometers

SECONDS_PER_FRAME = 1000  # each updates represents this many seconds passed

UPDATES_PER_SECOND = 100

DEIMOS_RADIUS = 6.2  # kilometers

G = 0.000003  # Deimos gravitational constant in kilometers per second squared

CURSOR_SIZE = 20

def follow():

    global meteors

    new_meteors = []

    t = SECONDS_PER_FRAME

    for (x, y), velocity, heading, stamp in meteors:

        meteor.clearstamp(stamp)
        meteor.goto(x, y)
        meteor.setheading(heading)
        meteor.forward(velocity * t)

        meteor.setheading(meteor.towards(deimos))
        meteor.forward(G * t * t)

        meteor.setheading(180 + meteor.towards(x, y))

        if meteor.distance(deimos) > DEIMOS_RADIUS * 2:
            new_meteors.append((meteor.position(), velocity, meteor.heading(), meteor.stamp()))

    screen.update()

    meteors = new_meteors
    if meteors:
        screen.ontimer(follow, 1000 // UPDATES_PER_SECOND)

def create():
    """ create()'s dots with meteor """

    count = 0
    nux, nuy = -400, 300

    while nuy > -400:
        meteor.goto(nux, nuy)

        if meteor.distance(deimos) > DEIMOS_RADIUS * 2:
            heading = random() * 360
            meteor.setheading(heading)  # all meteors have random heading but fixed velocity
            meteors.append((meteor.position(), METEOR_VELOCITY, meteor.heading(), meteor.stamp()))

        nux += 20
        count += 1
        if count % 40 == 0:
            nuy -= 50
            nux = -400

    screen.update()

meteors = []

screen = Screen()
screen.screensize(1000, 1000)
screen.setworldcoordinates(-500, -500, 499, 499)  # 1 pixel = 1 kilometer

meteor = Turtle('circle', visible=False)
meteor.shapesize(2 * METEOR_RADIUS / CURSOR_SIZE)
meteor.speed('fastest')
meteor.color('purple')
meteor.penup()

deimos = Turtle('circle')
deimos.shapesize(2 * DEIMOS_RADIUS / CURSOR_SIZE)
deimos.color("orange")
deimos.penup()

screen.tracer(False)

create()
follow()

screen.mainloop()

要调查的第一个变量是 METEOR_VELOCITY。在提供的设置下,大多数流星将撞击月球,但少数会获得轨道速度。如果你减半它的价值,所有的流星都会坠入月球。如果你加倍它的值,一些流星获得逃逸速度,留下window;少数可能会坠入月球;大多数会形成一个越来越小、越来越紧的轨道云。

我扔掉了三角函数的东西并恢复为度数而不是弧度。我使用矢量加法逻辑来计算运动。

归根结底,这只是一个粗略的模型。

通过在 代码中的 def follow() 中将 180 更改为其他一些偏移量,例如 195,

meteor.setheading(195 + meteor.towards(x, y))

然后流星将不会直线(180 度)朝向火卫二,而是会向中心显示出一些螺旋运动。

提供了很好的例子!