C++ is designed with the principal that speed is more important than safety and error-checking. This differs from the majority of other programming languages, which tend to be considerably more restrictive in regards to aspects such as memory allocations and resource management. C++ is translated to โmachine languageโ when it is compiled, which is a step skipped by other languages.
This difference is what allows C++ to be as fast as it is, which also makes it particularly good for graphically-intensive applications. Graphical applications heavily leverage memory management to display every pixel you see on your screen. Many languages do not allow for the creation of arrays like in C++, which are just โchunksโ of memory of a fixed size. Furthermore, running directly on the hardware allows C++ to communicate better with other components of your computer, such as your graphics processing unit, or โGPUโ. This is one of many reasons C++ is considered an industry standard for high-performance graphics applications, such as video games or software used for visual effects in movies.
Turtle graphics are a popular and simple way for introducing programming to beginners. It was part of the original Logo programming language developed by Wally Feurzeig, Seymour Papert and Cynthia Solomon in 1967.
Imagine Turtles as being a digital marker used for drawing various shapes, images, and designs. Drawing with Turtles can be as basic as a simple triangle and as complex as a highly detailed fractal image. Nearly all commands used when drawing with Turtles are as simple as telling your Turtle to move forward, backward, left, and right in as few or many steps as desired.
Visual representations afford students an opportunity to observe a facet of computer science from an alternative point of view: rather than waiting anxiously for the print statement to come around after your program churns, you get a visual representation of the concept itself. This is particularly useful for abstract concepts such as recursion and iteration.
For C++, a library titled C-Turtle is used to provide an equivalent of Pythonโs Turtles. It acts as a close replacement to provide easy to use graphics to C++, while maintaining the objects and commands present in Python. It was developed by Jesse Walker-Schadler at Berea College during the summer of 2019 and can be found on GitHub here: https://github.com/walkerje/C-Turtle/
Explorationย 1.14.1 is a comparison of two versions, C++ and Python, which should do the same thing. Try running both and comparing how the code looks between the two versions.
ct::TurtleScreen screen;
ct::Turtle turtle(screen);
//Notice how the Screen is given to our Turtle when we create it.
Closing a TurtleScreen when youโre done with it is fairly simple to do. For this chapter, only the method bye is used. Calling it is not completely necessary, as it is also called automatically if it, or an equivalent method, hasnโt been called. When working outside of the textbook, the exitonclick method is also available.
Turtles are based on the following premise: โThere is a turtle on a canvas with a colored pen attached to their tail.โ In this case, the canvas is a TurtleScreen. This Turtle will follow any command you give it, which consist of telling it to go certain directions, what color of pen to use, when to raise or lower its pen, and others. Tableย 1.14.1 has an outline of commonly used methods when working with turtles.
turns the turtle a certain number of units to the left.
turtle.right
turns the turtle a certain number of units to the right.
turtle.penup
raises the paint pen on the end of the turtleโs tail.
turtle.pendown
lowers the paint pen on the end of the turtleโs tail.
turtle.fillcolor
tells the turtle what color the inside of the shape will be.
turtle.beginfill
tells the turtle to begin filling a shape as it moves.
turtle.endfill
tells the turtle to finish filling the shape it has created as it moved.
turtle.pencolor
tells the turtle what color it will draw with.
turtle.width
tells the turtle how large of a paint pen to use.
turtle.speed
tells the turtle how fast it should go, faster or slower than the hare.
turtle.back
moves the turtle back a number of units.
turtle.forward
moves the turtle forward a number of units.
turtle.goto
tells the turtle to move to a specific coordinate.
turtle.write
tells the turtle to write some kind of text.
Many of these methods are used alongside one-another to create different images. All speeds (Tableย 1.14.2are measured on a range of 1 to 10, the latter being the fastest and the former being the slowest. The exception is the fastest speed, TS_FASTEST, which is set to 0. The TS prefix represents โTurtle Speedโ.
#include <CTurtle.hpp>
namespace ct = cturtle;
int main() {
//Create a turtle screen, and add our turtle to it.
ct::TurtleScreen screen;
ct::Turtle turtle(screen);
//Set the turtle speed to the slowest available option.
turtle.speed(ct::TS_SLOWEST);
//Any number from 0 to 10 would work as well.
//turtle.speed(7);
//Sets the turtle's fill color to purple.
turtle.fillcolor({"purple"});
//Tells the turtle to begin filling a shape as it moves.
turtle.begin_fill();
//Tells the turtle to make a square.
//Iterates once for every corner of the square.
for (int i = 0; i < 4; i++) {
//Tells the turtle to move forward 50 units.
turtle.forward(50);
//Tells the turtle to turn 90 degrees to the right.
turtle.right(90);
}
//Tells the turtle to finish filling the shape it has outlined.
turtle.end_fill();
//Closes the turtle screen.
screen.bye();
return 0;
}
The order of operations given to a turtle is important, as some actions must be completed one after another. A good example of this is the begin_fill and end_fill pattern, which must be called in that specified order to actually fill a shape.
Every basic shape in CTurtle is a set of coordinates. Within the CTurtle library we have the choice of a select few shapes that we can me our Turtles inhabit. To change the appearance of your Turtle, you can use shape to set your Turtle to one of four default shapes, or a custom shape. CTurtle features four default shapes, triangle, indented_triangle, square, and arrow.
Given that all primitive shapes are defined as a collection of points, all of the default shapes are also defined this way Tableย 1.14.4. Polygons, for custom and default shapes, must have their points defined in counter-clockwise order to appear correctly. This is due to the mathematics behind filling arbitrary shapes, and is a limitation almost all computer graphics need to abide by. Consider the order of their points in the following table, and how they could be considered โcounter-clockwiseโ. They are in order from top to bottom, and one edge exists between the first last points for each of these shapes. Please note that positive Y coordinates are lower on the screen, while negative Y coordinates are higher on the screen. Coordinates at the originโ that is, coordinate 0x, 0yโ is at the โpointโ or โtipโ of the turtle. This is why most of the default shapes have their first coordinate there.
Graphic illustrating an indented triangle with coordinate points. At the top vertex, the point is labeled โ0, 0โ. The bottom left vertex is labeled โ-5, 10โ, and the bottom right vertex is labeled โ5, 10โ. An arrow curves above the triangle, indicating rotation or flipping. Each vertex is marked with a green circle. The image defines the shape and position of an indented triangle in a coordinate system.
The example code below illustrates how to create your own shape. We use the Polygon class to represent our shape. For this example, we take the triangle default shape and make every Y coordinate negative to make it appear upside-down.
ct::Polygon upside_down_triangle = {
{0, 0}, //First point
{-5, -5}, //Second point
{5, -5} //and so on.
};
The following code is a full example for setting your turtle to a custom shape. Feel free to mess around with the coordinates of the polygon, you might surprise yourself with what shape you end up with!
#include <CTurtle.hpp>
namespace ct = cturtle;
int main(){
ct::TurtleScreen screen;
ct::Turtle turtle(screen);
ct::Polygon upside_down_triangle = {
{0, 0}, //First point
{-5, -5}, //Second point
{5, -5} //and so on.
};
turtle.shape(upside_down_triangle);
turtle.forward(50);
screen.bye();
return 0;
}
Stamps provide a way to make several copies of the shape of the turtle across the screen without having to trace each shape individually with the turtle. This can be used for a variety of visual effects, however it is often used as a time-saving utility. Stamps can be placed with the stamp method of Turtle objects, which returns an integer that acts as the ID of the stamp that has been placed. The clearstamp method of the Turtle object can be used to delete a single stamp from the screen, while the clearstamps method is used to delete multiple stamps at once.
#include <CTurtle.hpp>
namespace ct = cturtle;
int main(){
ct::TurtleScreen screen;
ct::Turtle turtle(screen);
ct::Polygon upside_down_triangle = {
{0, 0}, //First point
{-5, -5}, //Second point
{5, -5} //and so on.
};
turtle.shape(upside_down_triangle);
//Draw a square where each edge is 50 units long.
for(int i = 0; i < 4; i++){
//Stamp at the corner of the square.
int corner_stamp = turtle.stamp();
turtle.forward(25);
turtle.stamp(); //Stamp half-way across the edge of the square.
turtle.forward(25);
turtle.right(90);
//Clear the corner stamp.
turtle.clearstamp(corner_stamp);
}
turtle.clearstamps();
screen.bye();
return 0;
}
Turtles are a large tool, and thus have a lot of options dictating how they function. Some features and functionality are more complicated than others, relating to the inner workings of turtles themselves. A few of these include the tracer and undo methods, and also screen modes.
Screen modes dictate the direction of angle measurements. This means that, depending on which mode a TurtleScreen object is in, positive angles could represent clockwise rotations or counterclockwise rotations. The mode method for TurtleScreen allows you to set which mode a screen is in, see Tableย 1.14.6.
Regarding angles, Turtles can use both degrees and radians for their rotations. You can choose between the two using the radians and degrees methods for the Turtle object. By default, all angles are measured in degrees. This option only effects methods regarding rotation, such as left and right.
turtle.degrees();
turtle.right(90);//90-degree turn to the right
turtle.radians();
turtle.left(1.5708f);//Equivalent rotation in radians to the left.
The tracer(N) method is used to control how many times the Turtle is actually drawn on the screen. This method belongs to the TurtleScreen object, and effects all turtles that are on the screen. The N in the method represents the input, only allowing the TurtleScreen to display one frame out every N.
screen.tracer(12);
//Show one out of every 12 frames of animation.
This can be combined with the speed method available to turtles to achieve very quickly drawn images. The maximum speed a Turtle can have, TS_FASTEST, completely disables animation for Turtles between movements and rotations. This allows the tracer setting to directly relate to the total number of actions the turtle makes. The actions the turtle takes happen regardless of whether or not they are actually shown on the screen.
screen.tracer(3); //Show one out of every 3 frames of animation.
turtle.speed(ct::TS_FASTEST); //Disables Turtle animation
turtle.forward(50);//This is not shown on-screen...
turtle.right(90);//Neither is this...
turtle.forward(50);//But this action is, because it is third out of three.
A frame of animation is added for almost every action a turtle takes, regardless of whether or not the turtle is moving or adding something to the screen. This includes methods like begin_fill and end_fill, which donโt do anything visually but do tell the turtle to start or stop tracking its own movements.
#include <CTurtle.hpp>
namespace ct = cturtle;
int main(){
ct::TurtleScreen screen;
ct::Turtle turtle(screen);
turtle.speed(ct::TS_FASTEST);
screen.tracer(6);
for(int i = 0; i < 3; i++){
turtle.right(60);
turtle.forward(50);
}
screen.bye();
return 0;
}
Similarly to tracer settings, every action a turtle takes is also added to the undo queue. This allows it to keep track of actions it is performing over a period of time. The queue is only allowed to grow to a certain size, starting at 100 actions total. This is modifiable through the setundobuffer method that belongs to turtles. Every action is added, even if the action doesnโt change anything visually. This feature is comparable to the โundoโ tool available in most text editors. Turtles can โundoโ their progress with the undo method.