Попытка сделать точки вокруг орбиты - PullRequest
0 голосов
/ 03 июня 2018

Итак, я пытался заставить некоторые точки не только приблизиться к кругу, но и заставить их вращаться вокруг него.Для этого я использую косинус и синус, но у меня возникают проблемы с перемещением точек вперед, а также с установкой их расстояния.С помощью приведенного ниже кода точки могут образовывать окружность вокруг большой точки, а также следовать за ней, но они не приближаются к точке и не достигают этой точки, когда координаты, масштабированные по их расстоянию от 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 () должны быть вторым этапом программы, но эти функции не имеют отношения к вопросу.Наконец, 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()

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

При изменении 180 на некоторые другие смещения, например, 195, в коде def follow() в cdlane в

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

тогда метры не будут идти прямо (180 градусов)в сторону Деймоса, но вместо этого покажет некоторое спиральное движение к центру.

Отличный пример!

0 голосов
/ 04 июня 2018

Я предпринял еще одну попытку, просто глядя на проблему метеоров, роящихся вокруг планеты.Или в этом случае, Луна, поскольку я выбрал Деймоса в качестве моей модели.Я пытался работать в масштабе, делая систему координат 1 пиксель = 1 километр.В начале Деймос сидит в поле метеоров, каждый из которых имеет случайный заголовок, но все они имеют одинаковый размер и скорость:

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.При заданной настройке большинство метеоров упадут на Луну, но некоторые из них достигнут орбитальной скорости.Если вы уменьшите вдвое его значение, все метеоры упадут на Луну.Если вы удвоите его значение, несколько метеоров получат скорость выхода, покидая окно;немногие могут врезаться в луну;большинство из них образуют орбитальное облако, которое становится меньше и плотнее.

Я бросил тригонометрические элементы и вернулся к градусам вместо радианов.Я использую логику сложения векторов для проработки движения.

В конце концов, это просто грубая модель.

...