SchrodingersCat
SchrodingersCat

Reputation: 1589

How to sync animation using turtle-graphics module?

I have written the following python code to create an animation of a rotating graph using python turtle. The problem I am facing is that, the animation is not properly synchronizing. I don't want to show the people exactly how the thing is rotating. So, I have to carefully choose the frame rate in the turtle.tracer command. Well, if you observe carefully, each value of r creates a rotation, so I must update the screen at the end of each r. And for each value of r, there are 1202 iterations inside the loop for r. But this does not produce the desired effect.

What must I do to correct this?

import turtle
import math

am = turtle
am.ht()
am.tracer(1202,0)

for r in range(0,600):
    #axes
    am.pu()
    am.setpos(0,500)
    am.pd()
    am.setpos(0,-500)
    am.pu()
    am.setpos(-650,0)
    am.pd()
    am.setpos(0,0)
    am.write("0",align="right",font=("Times New Roman",14,"normal"))
    am.setpos(650,0)
    am.pu()
    am.setpos(-300*math.cos(r*math.pi/100),300*math.sin(r*math.pi/100))
    am.pd()
    #axes
    am.pencolor("red")
    for x in range(-300,301):
        g=math.sin(x)
        t=math.cos(x)
        y =100*g*t*math.sin(2*(x**2)*math.pi/100)
        am.setpos(x*math.cos(r*math.pi/100)+y*math.sin(r*math.pi/100),-x*math.sin(r*math.pi/100)+y*math.cos(r*math.pi/100))
    #if(x%4==0):
       #am.write(x)
    am.pu()
    am.setpos(-300*math.sin(r*math.pi/100),-300*math.cos(r*math.pi/100))
    am.pd()
    am.pencolor("blue")
    for y in range(-300,301):
        c=math.sin(y)
        d=math.cos(y)
        x =100*c*d*math.cos(2*(y**2)*math.pi/100)
        am.setpos(x*math.cos(r*math.pi/100)+y*math.sin(r*math.pi/100),-x*math.sin(r*math.pi/100)+y*math.cos(r*math.pi/100))
    am.reset()

am.exitonclick()

Upvotes: 1

Views: 848

Answers (1)

cdlane
cdlane

Reputation: 41903

I believe the following will do what you desire. I've changed the tracer logic to be more manual with an explicit .update() when you're ready to show the user something. I've also separated the axis drawing from the main loop as we really don't need to clear and redraw it each time:

import math
from turtle import Turtle, Screen

screen = Screen()
screen.tracer(0)

# axes
axes = Turtle(visible=False)
axes.pu()
axes.setpos(0, 500)
axes.pd()
axes.setpos(0, -500)
axes.pu()
axes.setpos(-650, 0)
axes.pd()
axes.setpos(0, 0)
axes.write("0", align="right", font=("Times New Roman", 14, "normal"))
axes.setpos(650, 0)

am = Turtle(visible=False)

for r in range(0, 600):

    am.pu()
    am.setpos(-300 * math.cos(r * math.pi / 100), 300 * math.sin(r * math.pi / 100))
    am.pd()
    am.pencolor("red")

    for x in range(-300, 301):
        g = math.sin(x)
        t = math.cos(x)
        y = 100 * g * t * math.sin(2 * x**2 * math.pi / 100)
        am.setpos(x * math.cos(r * math.pi / 100) + y * math.sin(r * math.pi / 100), -x * math.sin(r * math.pi / 100) + y * math.cos(r * math.pi / 100))

    am.pu()
    am.setpos(-300 * math.sin(r * math.pi / 100), -300 * math.cos(r * math.pi / 100))
    am.pd()
    am.pencolor("blue")

    for y in range(-300, 301):
        c = math.sin(y)
        d = math.cos(y)
        x = 100 * c * d * math.cos(2 * y**2 * math.pi / 100)
        am.setpos(x * math.cos(r * math.pi / 100) + y * math.sin(r * math.pi / 100), -x * math.sin(r * math.pi / 100) + y * math.cos(r * math.pi / 100))

    screen.update()
    am.reset()
    am.hideturtle()  # made visible by reset()

screen.exitonclick()

Finally, this was likely an error:

am = turtle

and not doing what you think it was (module name alias instead of an actual turtle.)

Upvotes: 2

Related Questions