9 replaced http://codegolf.stackexchange.com/ with https://codegolf.stackexchange.com/
source | link
  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
  • flip if non-zero causes the turtles to flip direction for their return trip (as suggested by aslumaslum so that they are never moving backwards). As default they keep a fixed direction to avoid the visual distraction at the endpoints.
  • lines if non-zero displays the lines on which the turtles move, for consistency with the example image in the question.
  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
  • flip if non-zero causes the turtles to flip direction for their return trip (as suggested by aslum so that they are never moving backwards). As default they keep a fixed direction to avoid the visual distraction at the endpoints.
  • lines if non-zero displays the lines on which the turtles move, for consistency with the example image in the question.
  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
  • flip if non-zero causes the turtles to flip direction for their return trip (as suggested by aslum so that they are never moving backwards). As default they keep a fixed direction to avoid the visual distraction at the endpoints.
  • lines if non-zero displays the lines on which the turtles move, for consistency with the example image in the question.
8 Add example GIFs for flip and lines
source | link
  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
  • flip if non-zero causes the turtles to flip direction for their return trip (as suggested by aslum so that they are never moving backwards). As default they keep a fixed direction to avoid the visual distraction at the endpoints.
  • lines if non-zero displays the lines on which the turtles move, for consistency with the example image in the question.

Examples with flip set, with and without lines. I've left my main example above without flip as I prefer not to have the sporadic jump, but the edge of the circle does look smoother with all the turtles aligned, so the option is there for people to choose whichever style they prefer when running the code.

11 turtles with flip and lines11 turtles with flip

It might not be immediately obvious how the images above were all produced from this same code. In particular the image immediately above left,further up which has a slow outer loop and a fast inner loop (the one that looks like a cardioid that someone accidentally dropped). I've hidden the explanation of this one below in case anyone wants to delay finding out while experimenting/thinking.

The animation with an inner and outer loop of different sizes (the one that looks like a cardioid that someone accidentally dropped) was created by setting the number of loops to 15 and leaving the number of turtles at 23 (too low to represent 15 loops). Using a large number of turtles would result in 15 clearly defined loops. Using too few turtles results in aliasing (for the same reason as in image processing and rendering). Trying to represent too high a frequency for the number of turtles to display results in a lower frequency being displayed, with distortion.

Trying out different numbers I found some of these distortions more interesting thatthan the more symmetrical originals, so I wanted to include one here...

  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
  • flip if non-zero causes the turtles to flip direction for their return trip (as suggested by aslum). As default they keep a fixed direction to avoid the visual distraction at the endpoints.
  • lines if non-zero displays the lines on which the turtles move, for consistency with the example image in the question.

It might not be immediately obvious how the images above were all produced from this same code. In particular the image immediately above left, which has a slow outer loop and a fast inner loop. I've hidden the explanation of this one below in case anyone wants to delay finding out while experimenting/thinking.

The animation with an inner and outer loop of different sizes (the one that looks like a cardioid that someone accidentally dropped) was created by setting the number of loops to 15 and leaving the number of turtles at 23 (too low to represent 15 loops). Using a large number of turtles would result in 15 clearly defined loops. Using too few turtles results in aliasing (for the same reason as in image processing and rendering). Trying to represent too high a frequency for the number of turtles to display results in a lower frequency being displayed, with distortion.

Trying out different numbers I found some of these distortions more interesting that the symmetrical originals, so I wanted to include one here...

  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
  • flip if non-zero causes the turtles to flip direction for their return trip (as suggested by aslum so that they are never moving backwards). As default they keep a fixed direction to avoid the visual distraction at the endpoints.
  • lines if non-zero displays the lines on which the turtles move, for consistency with the example image in the question.

Examples with flip set, with and without lines. I've left my main example above without flip as I prefer not to have the sporadic jump, but the edge of the circle does look smoother with all the turtles aligned, so the option is there for people to choose whichever style they prefer when running the code.

11 turtles with flip and lines11 turtles with flip

It might not be immediately obvious how the images above were all produced from this same code. In particular the image further up which has a slow outer loop and a fast inner loop (the one that looks like a cardioid that someone accidentally dropped). I've hidden the explanation of this one below in case anyone wants to delay finding out while experimenting/thinking.

The animation with an inner and outer loop of different sizes was created by setting the number of loops to 15 and leaving the number of turtles at 23 (too low to represent 15 loops). Using a large number of turtles would result in 15 clearly defined loops. Using too few turtles results in aliasing (for the same reason as in image processing and rendering). Trying to represent too high a frequency results in a lower frequency being displayed, with distortion.

Trying out different numbers I found some of these distortions more interesting than the more symmetrical originals, so I wanted to include one here...

7 Add additional options: flip and lines
source | link
import turtle
import time
from math import sin, pi
from random import random


def circle_dance(population=11, resolution=480, loops=1, flip=0, lines=0):
    population = int(population)
    resolution = int(resolution)
    radius = 250
    screen = turtle.Screen()
    screen.tracer(0)
    if lines:
        arrange_lines(population, radius)
    turtles = [turtle.Turtle() for i in range(population)]
    for i in range(population):
        dancer = turtles[i]
        make_dancer(dancer, i, population)
    animate(turtles, resolution, screen, loops, flip, radius)


def arrange_lines(population, radius):
    artist = turtle.Turtle()
    for n in range(population):
        artist.penup()
        artist.setposition(0, 0)
        artist.setheading(n / population * 180)
        artist.forward(-radius)
        artist.pendown()
        artist.forward(radius * 2)
    artist.hideturtle()


def make_dancer(dancer, i, population):
    dancer.setheading(i / population * 180)
    dancer.color(random_turtle_colour())
    dancer.penup()
    dancer.shape('turtle')
    dancer.turtlesize(2)


def random_turtle_colour():
    return random() * 0.9, 0.5 + random() * 0.5, random() * 0.7


def animate(turtles, resolution, screen, loops, flip, radius):
    delay = 4 / resolution      # 4 seconds per repetition
    while True:
        for step in range(resolution):
            timer = time.perf_counter()
            phase = step / resolution * 2 * pi
            draw_dancers(turtles, phase, screen, loops, flip, radius)
            elapsed = time.sleepperf_counter(1) /- resolutiontimer
            adjusted_delay = max(0, delay - elapsed)
            time.sleep(adjusted_delay)


def draw_dancers(turtles, phase, screen, loops, flip, radius):
    population = len(turtles)
    for i in range(population):
        individual_phase = (phase + i / population * loops * pi) % (2*pi)
        dancer = turtles[i]
        if flip:
            if pi / 2 < individual_phase <= 3 * pi / 2:
                dancer.settiltangle(180)
            else:
                dancer.settiltangle(0)
        distance = 250radius * sin(individual_phase)
        dancer.setposition(0, 0)
        dancer.forward(distance)
    screen.update()


if __name__ == '__main__':
    import sys
    circle_dance(*(float(n) for n in sys.argv[1:]))

The code can be run with 35 optional arguments,: population, resolution and, loops, flip and lines.

  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
  • flip if non-zero causes the turtles to flip direction for their return trip (as suggested by aslum). As default they keep a fixed direction to avoid the visual distraction at the endpoints.
  • lines if non-zero displays the lines on which the turtles move, for consistency with the example image in the question.
import turtle
import time
from math import sin, pi
from random import random


def circle_dance(population=11, resolution=480, loops=1):
    population = int(population)
    resolution = int(resolution)
    screen = turtle.Screen()
    screen.tracer(0)
    turtles = [turtle.Turtle() for i in range(population)]
    for i in range(population):
        dancer = turtles[i]
        make_dancer(dancer, i, population)
    animate(turtles, resolution, screen, loops)


def make_dancer(dancer, i, population):
    dancer.setheading(i / population * 180)
    dancer.color(random_turtle_colour())
    dancer.penup()
    dancer.shape('turtle')
    dancer.turtlesize(2)


def random_turtle_colour():
    return random() * 0.9, 0.5 + random() * 0.5, random() * 0.7


def animate(turtles, resolution, screen, loops):
    while True:
        for step in range(resolution):
            phase = step / resolution * 2 * pi
            draw_dancers(turtles, phase, screen, loops)
            time.sleep(1 / resolution)


def draw_dancers(turtles, phase, screen, loops):
    population = len(turtles)
    for i in range(population):
        individual_phase = phase + i / population * loops * pi
        dancer = turtles[i]
        distance = 250 * sin(individual_phase)
        dancer.setposition(0,0)
        dancer.forward(distance)
    screen.update()


if __name__ == '__main__':
    import sys
    circle_dance(*(float(n) for n in sys.argv[1:]))

The code can be run with 3 optional arguments, population, resolution and loops.

  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
import turtle
import time
from math import sin, pi
from random import random


def circle_dance(population=11, resolution=480, loops=1, flip=0, lines=0):
    population = int(population)
    resolution = int(resolution)
    radius = 250
    screen = turtle.Screen()
    screen.tracer(0)
    if lines:
        arrange_lines(population, radius)
    turtles = [turtle.Turtle() for i in range(population)]
    for i in range(population):
        dancer = turtles[i]
        make_dancer(dancer, i, population)
    animate(turtles, resolution, screen, loops, flip, radius)


def arrange_lines(population, radius):
    artist = turtle.Turtle()
    for n in range(population):
        artist.penup()
        artist.setposition(0, 0)
        artist.setheading(n / population * 180)
        artist.forward(-radius)
        artist.pendown()
        artist.forward(radius * 2)
    artist.hideturtle()


def make_dancer(dancer, i, population):
    dancer.setheading(i / population * 180)
    dancer.color(random_turtle_colour())
    dancer.penup()
    dancer.shape('turtle')
    dancer.turtlesize(2)


def random_turtle_colour():
    return random() * 0.9, 0.5 + random() * 0.5, random() * 0.7


def animate(turtles, resolution, screen, loops, flip, radius):
    delay = 4 / resolution      # 4 seconds per repetition
    while True:
        for step in range(resolution):
            timer = time.perf_counter()
            phase = step / resolution * 2 * pi
            draw_dancers(turtles, phase, screen, loops, flip, radius)
            elapsed = time.perf_counter() - timer
            adjusted_delay = max(0, delay - elapsed)
            time.sleep(adjusted_delay)


def draw_dancers(turtles, phase, screen, loops, flip, radius):
    population = len(turtles)
    for i in range(population):
        individual_phase = (phase + i / population * loops * pi) % (2*pi)
        dancer = turtles[i]
        if flip:
            if pi / 2 < individual_phase <= 3 * pi / 2:
                dancer.settiltangle(180)
            else:
                dancer.settiltangle(0)
        distance = radius * sin(individual_phase)
        dancer.setposition(0, 0)
        dancer.forward(distance)
    screen.update()


if __name__ == '__main__':
    import sys
    circle_dance(*(float(n) for n in sys.argv[1:]))

The code can be run with 5 optional arguments: population, resolution, loops, flip and lines.

  • population is the number of turtles
  • resolution is the time resolution (number of animation frames per repetition)
  • loops determines how many times the turtles loop back on themselves. The default of 1 gives a standard circle, other odd numbers give that number of loops in the string of turtles, while even numbers give a string of turtles disconnected at the ends, but still with the illusion of curved motion.
  • flip if non-zero causes the turtles to flip direction for their return trip (as suggested by aslum). As default they keep a fixed direction to avoid the visual distraction at the endpoints.
  • lines if non-zero displays the lines on which the turtles move, for consistency with the example image in the question.
6 Add info about default arguments and spoiler explanation
source | link
5 Added loop and trefoil GIFs for comparison
source | link
4 Added syntax highlighting
source | link
3 Remove redundant code lines
source | link
2 Added small GIFs of 3 and 4 turtle circles
source | link
1
source | link