Draws abstract shapes using a list of turtles where each turtle moves towards another turtle in the list.
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax // Line color Canvas.setpenopacity(-0.25); // Canvas is 200x200 const canvas_size = 200; // Number of turtles const turtles = 200; // min=1, max=500, step=1 // Offset between turtle and follower const follower_offset = 3; // min=1, max=10, step=1 // When initially positioning turtles, the length increment on each point in the spiral const spiral_length_increment = 5; // min=0, max=100, step=1 // When initially positioning turtles, the degree increment on each point in the spiral const spiral_degree_increment = 15; // min=1, max=360, step=1 // Number of generations to draw const generations = 400; // min=1, max=1000, step=5 // Number of generations to skip before putting the pen down const skip_generations = 40; // min=0, max=1000, step=5 // Step length when moving towards next turtle const step_length = 18; // min=1, max=100, step=1 // How much to change the step length on each generation const step_increment = -1; // min=-10, max=10, step=1 // Create and position the turtles const turtle_list = new Array(turtles); for (i=0; i<turtles; i++) { const turtle = new Turtle(); let position = pointAt(0, 0, radians(spiral_degree_increment * i), (spiral_length_increment * i)); turtle.penup(); turtle.goto(position[0], position[1]); turtle_list[i] = turtle; } // Connect each turtle to the target turtle it is following for (i=0; i<turtles; i++) { let target_index = i+follower_offset; if (target_index >= turtles) { target_index -= turtles; } turtle_list[i].target = turtle_list[target_index]; } let generation_index = 0; let phase = 0; let turtle_index = 0; let current_step_length = step_length; // The walk function will be called until it returns false. function walk(i) { const turtle = turtle_list[turtle_index]; if (phase == 0) { turtle.angle = angle_to(turtle.x(), turtle.y(), turtle.target.x(), turtle.target.y()); } else if (phase == 1) { let position = pointAt(turtle.x(), turtle.y(), turtle.angle, current_step_length); if (generation_index >= skip_generations) { turtle.pendown(); } turtle.goto(position[0], position[1]); } if (turtle_index >= (turtles - 1)) { turtle_index = 0; phase++; } else { turtle_index++; } if (phase > 1) { phase = 0; generation_index++; current_step_length += step_increment; if (current_step_length < 1) { current_step_length = 1; } } return generation_index < generations; } function radians(angle) { return angle * (Math.PI / 180); } function pointAt(x, y, radians, distance) { let new_x = x + (distance * Math.cos(radians)); let new_y = y + (distance * Math.sin(radians)); let clipped_x = new_x % (canvas_size / 2); let clipped_y = new_y % (canvas_size / 2); return [clipped_x, clipped_y]; } function angle_to(x1, y1, x2, y2) { atan_radians = Math.atan2(y2 - y1, x2 - x1); if (atan_radians >= 0) { return atan_radians; } else { return Math.PI * 2 + atan_radians; } }