Ошибка «максимальная глубина рекурсии превышена», нужно ли реструктурировать свой код? - PullRequest
0 голосов
/ 09 мая 2019

Я создаю приложение, которое вращает несколько точек вокруг центральной точки. Цель состоит в том, чтобы соединить каждую точку, используя, например. линии / дуги и точки / (последующий чертеж) вращаются вокруг центральной точки.

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

(Для дальнейшего использования мне также понадобятся некоторые виджеты tkinter, работающие вдоль кода, например, записи для получения пользовательского ввода.)

Мой текущий код просто рисует круг для каждой точки, а не соединяет их. В настоящее время я не понимаю пару вещей:

  1. Мой код на короткое время работает нормально, а затем закрывается с Error: maximum recursion depth exceeded. - Это плохо, чтобы очистить холст с помощью .delete?

  2. Значение функции .after, похоже, не оказывает никакого влияния, поэтому использование time.sleep.

(Я также использовал цикл while True: для запуска кода в более ранней версии, но я прочитал, что запускать бесконечный цикл внутри цикла событий GUI - это плохая практика. И я редактировал его из-за мерцания)

Было бы лучше структурировать мой код по-другому? Извините за неправильную терминологию, за грязный и длинный пост / код, я новый не-английский студент Python.

class Create_gear:

    def __init__(self, location, ox, oy, rpm, n):
        self.location = location
        self.ox = ox
        self.oy = oy
        self.rpm = rpm
        self.n = n
        self.rotation_from_normal = 0

    #Rotates point px1, py1 by value of "rpm" each time method is called.
    def draw_rotating_gear(self, px1, py1, px2, py2, r):
        self.rotation_from_normal = self.rotation_from_normal +self.rpm
        self.location.delete("all")

        #rotates point px1, py1 n times around to form a circle. 
        for i in range (0, self.n):
            angle = (math.radians(self.rotation_from_normal + 360/self.n *i) )

            qx = ( self.ox + math.cos(angle) * (px1 - self.ox) - math.sin(angle) * (py1 - self.oy) )
            qy = ( self.oy + math.sin(angle) * (px1 - self.ox) + math.cos(angle) * (py1 - self.oy) )

            x0 = qx - r
            y0 = qy - r
            x1 = qx + r
            y1 = qy + r
            self.location.create_oval(x0, y0, x1, y1, fill = "black")
        self.location.update()
        time.sleep(0.01)
        self.location.after(1000000000, self.draw_rotating_gear(480, 200, 500, 300, 5))

Ответы [ 2 ]

1 голос
/ 09 мая 2019

Вы не предоставили достаточно кода для рабочего примера решения, но я считаю, что проблема в том, что вы вызываете метод .after() с неверными аргументами. Первый аргумент должен быть целым числом , числом миллисекунд до вызова, а не значением с плавающей запятой . Второй аргумент должен быть функцией для вызова после этой задержки, а не вызовом функции , что вы и сделали. Исправив их и слегка упростив ваш пример, я ожидал что-то вроде:

def draw_rotating_gear(self, px1, py1, r):
    self.rotation_from_normal = self.rotation_from_normal + self.rpm
    self.location.delete("all")

    # rotates point px1, py1 n times around to form a circle.
    for i in range(0, self.n):
        angle = (math.radians(self.rotation_from_normal + 360/self.n * i))

        qx = (self.ox + math.cos(angle) * (px1 - self.ox) - math.sin(angle) * (py1 - self.oy))
        qy = (self.oy + math.sin(angle) * (px1 - self.ox) + math.cos(angle) * (py1 - self.oy))

        x0 = qx - r
        y0 = qy - r
        x1 = qx + r
        y1 = qy + r
        self.location.create_oval(x0, y0, x1, y1, fill="black")

    self.location.update()
    self.location.after(100, lambda px1=qx, py1=qy, r=r: self.draw_rotating_gear(px1, py1, r))

(возможно, я передаю неверные переменные в вызов lambda, так как у меня недостаточно контекста кода для работы.) Полученная вами ошибка рекурсии была вызвана неверным вторым аргументом .after(), т.е. ложная рекурсия из-за ошибки программирования.

1 голос
/ 09 мая 2019

Ничто в описании вашей проблемы не указывает на необходимость рекурсии вообще, и способ ее реализации в коде всегда будет неудачным.У вас есть вызов draw_rotating_gear () в конце функции draw_rotating_gear () без каких-либо условий для остановки рекурсии, поэтому он будет бесконечно углублен при первом вызове.Реорганизуйте его, чтобы использовать простой цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...