search


Draw a Triangle
Mon Mar 12 00:00:00 UTC 2018
Summary of last class.

By definition, one complete rotation in a plane is 360 degrees. A regular polygon is a polygon with sides of equal length which also implies the angles are also equal. Therefore to draw a regular n-sided polygon your turtle must rotate at an angle of (/ 360 n) and move forward a distance of d repeated n times.

For the case of a triangle n is 3. Since the rotation angle is (/ 360 n) we subsitute n=3 into that formula to get (/ 360 3) which means 360 divided by 3. Type that into power turtle and you will get the number 120 which is our rotation angle. We can arbitarily pick the distance of 100 for d.

To draw a triangle we tell our turtle to turn right 120, move forward 100, turn right 120, move forward 100, turn right 120, move forward 100. translating that into code.


(right 120)
(forward 100)
(right 120)
(forward 100)
(right 120)
(forward 100)

If you type the code above into power turtle, it draws a triangle. It is tedious to repeatedly type that code everytime we want to draw a triangle. The sequence of code above to draw a triangle is too low-level. It is not obvious from reading it that it draws a triangle. We will use the Power of Names to give a name to that sequence of code. We can define a function to do this

(defn triangle [] 
	(right 120)
	(forward 100)
	(right 120)
	(forward 100)
	(right 120)
	(forward 100))
Type that into power turtle. Whenever we need to draw a triangle, we just call the triangle function like this (triangle). There are two main benefits for creating a function to draw a trinagle instead of using low-level commands:
  • High level communication
  • Decrease repetition
Notice that this triangle function does not have any parameters. We hard-coded the distance the turtle moves to 100. Let's make our triangle function better by extracting out hard-coded distance of 100 into the parameter. Let's call this parameter d for distance. We will use a new name so that it does not over-write the previous triangle function. Lets call this new function triangle2
(defn triangle2 [d] 
	(right 120)
	(forward d)
	(right 120)
	(forward d)
	(right 120)
	(forward d))
Copy and paste that code into power turtle to redefine the triangle function. The new triangle function takes a parameter d. We can call it like this (triangle2 300). This triangle function can draw a triangle of any size. Perform some experiments. Repeatedly call the triangle functions with various values of d. Is this behavior what you expected?

The triangle2 function is better than the triangle function because we extracted a hard-coded value into a parameter of the function. This allowed us to create a triangle of any size.

The REPL is your laboratory

The process of incremental improvement from the triangle function to the triangle2 function is very similar to the scientific method of improving and refining hypothesis. The scientific method requires experimentation. In the Clojure world, experimentation is done in whats called the REPL (Read Eval Print Loop). Power Turtle is a REPL that runs in the web browser. The area where you type in code is the power turtle REPL. It is where you can perform code experiments and hypothesis testing

We can improve triangle2. Lets create our improvement in a new function called triangle3. What can be improved with triangle2? We are repeating (right 120) (forward d). Let's extract reptition of code that into a function called right-forward

(defn right-forward [d]
                     (right 120)
                     (forward d))
 (defn triangle3 [d]
                     (right-forward d)
                     (right-forward d)
                     (right-forward d))

Compare triangle2 with triangle3. triangle3 is just a simple subsittion of the common code fragment extracted into a function called right-forward. We still have repeated code (right-forward d) is called 3 times. Fortunately power turtle has a built-in function called called repeat to allow us to repeatedly call a function

(defn triangle4 [d]
                     (repeat 3 #(right-forward d)))

I will not explain what that # means here. triangle4 calls the function right-forward 3 times. The function right-forward turns 120 degrees and draws a line of distance d I rename the function from right-forward to turn-draw to better reflect its intention. I also want to replace the 120 degree with a parameter called angle. I will also rename the d to distance. The result of this transformation is this function

(defn turn-draw [angle distance]
                     (right angle)
                     (forward distance))
                   
 (defn triangle5 [d]
                     (repeat 3 #(turn-draw 120 d)))

Finally since triangle5 is an equilateral-triangle i should create a function with that name

(defn equilateral-triangle [d]
                     (repeat 3 #(turn-draw 120 d)))

The steps I did getting from the function triangle, triangle2, triangle3, triangle4, triangle5 to finally equalaterial-triangle is a mini application of the scientific method of refining the triangle code. Evolution of animals go through a similar process. Evolution and the scientific method are similar or homomorphic processes.