Графика черепахи Python постоянно выходит за пределы - PullRequest
0 голосов
/ 24 сентября 2018

Я пытаюсь, чтобы Черепаха в питоне рисовал количество диктуемых пользователем случайных чисел.У меня возникли проблемы с удержанием моей черепахи в границах, которые я определил.Например, границы черепахи:

border = 300

def drawBorder(border):
    t.pensize(3)
    x = 0
    while x <= 4:
        t.pendown()
        t.forward(border)
        t.left(90)
        t.penup()
        x = x + 1

, которая рисует квадрат 300x300.

Следующая функция должна - когда координата X или Y + длина треугольникаон собирается нарисовать за пределами границы - в течение первых двух итераций попытайтесь повернуть черепаху на 180 градусов (в противоположном направлении) и переместить ее вперед вдвое больше, чем первоначально предполагалось, чтобы переместить ее вперед.Если это не может привести черепаху в пределы границы, черепаха должна вернуться к середине границы - в данном случае (150 150).Это не всегда происходит.Из-за «случайной» природы поколения, чаще всего черепаха оказывается за пределами границы, хотя иногда она рисует все треугольники внутри границы.

 if t.xcor() + lengthOfTriangle > border or t.xcor() + lengthOfTriangle < 0 or \
    t.ycor() + lengthOfTriangle > border or t.ycor() + lengthOfTriangle < 0:
x = 0
while x < 2:
    t.penup()
    t.left(180)
    t.forward(2 * lengthOfTriangle)
    t.pendown()
    x = x + 1
else:
    t.penup()
    if t.xcor() > border:
        t.seth(180)
    if t.xcor() < border:
        t.seth(0)
    t.forward(t.xcor() - (t.xcor() + border/2))
    if t.ycor() > border:
        t.seth(90)
    if t.ycor() < border:
        t.seth(270)
    t.forward(t.ycor() - (t.ycor() + border/2))

print("Turtle was going to be out of bounds. Xcor would be: ", t.xcor() + lengthOfTriangle,
      ". And Ycor would be: ", t.ycor() + lengthOfTriangle)
return drawFigureRec(numTriangles, lengthOfTriangle=random.randint(1, 20),
                     distanceTriangle=random.randint(1, 40),
                     angleTriangle=random.randint(0, 360), sum=sum)

Если вам нужен контекст дляпеременные функции и тому подобное Я связал пастбин здесь .

Вот картинка, показывающая проблему. Черепаха должна оставаться в пределах «границ» (красный квадрат), новыходит наружу, как показано на выходе консоли

1 Ответ

0 голосов
/ 25 сентября 2018

Есть несколько проблем с вашим кодом.Например, эта логика проверки границы полностью игнорирует текущий курс черепахи:

   if t.xcor() + lengthOfTriangle > border or ... t.ycor() + lengthOfTriangle > border or ...

Т.е. она всегда принимает +45 градусов, поэтому не может работать.Вы можете либо выполнить тригонометрию, либо просто переместить черепаху в новое положение и проверить, не выходит ли она за пределы.Если за пределами, вы можете переместить его обратно, настроить и попробуйте снова.Здесь полезен метод turtle.undo().

Ваши drawFigure*() функции иногда явно возвращают значения, иногда нет.Как только функция явно возвращает значение, она должна явно возвращать единицу со всех точек выхода, а не возвращать неявно иногда None.

Ваша квадратная граница имеет пять сторон:

   x = 0
   while x <= 4:

, посколькупоследний перекрывает первый, это не очевидно визуально.

Давайте попробуем более простой итеративный подход, в котором мы используем turtle.circle() для рисования наших треугольников, но думаем о каждом треугольнике как о круге при определении, находится ли он в границах,Мы также будем центрировать наш рисунок вместо того, чтобы использовать только верхний правый квадрант и положительные числа:

from turtle import Screen, Turtle
from random import randint

NUMBER_TRIANGLES = 80
PEN_SIZE = 3
BORDER = 300

def drawBorder(border):
    turtle.pensize(PEN_SIZE)

    turtle.penup()
    turtle.goto(-border/2, -border/2)
    turtle.pendown()

    for _ in range(4):
        turtle.forward(border)
        turtle.left(90)

    turtle.penup()
    turtle.home()

def drawFigure(numTriangles):
    if not 0 < numTriangles < 500:
        exit("Number of triangles is out of range!")

    for _ in range(numTriangles):

        radius = randint(3, 20)
        distance = randint(2, 60)

        turtle.forward(distance)

        while not(radius - BORDER/2 < turtle.xcor() < BORDER/2 - radius and radius - BORDER/2 < turtle.ycor() < BORDER/2 - radius):
            turtle.undo()  # undo last forward()
            turtle.left(37)  # rotate and try again (relative prime angle)
            distance += 1  # increase distance slightly on failure
            turtle.forward(distance)

        angle = randint(1, 360)
        turtle.setheading(angle)

        turtle.right(90)  # turtle represents center so need to adjust
        turtle.forward(radius)  # as turtle.circle() doesn't think that way
        turtle.left(90)

        turtle.pendown()
        turtle.circle(radius, steps=3)
        turtle.penup()

        turtle.left(90)  # undo adjustment to move turtle back to center
        turtle.forward(radius)
        turtle.right(90)

screen = Screen()
screen.tracer(False)

turtle = Turtle()
turtle.speed('fastest')

drawBorder(BORDER)
drawFigure(NUMBER_TRIANGLES)

turtle.hideturtle()

screen.tracer(True)
screen.mainloop()

enter image description here

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

...