{"id":5969,"date":"2016-10-25T18:47:45","date_gmt":"2016-10-25T18:47:45","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/?page_id=5969"},"modified":"2016-10-25T23:45:54","modified_gmt":"2016-10-25T23:45:54","slug":"turtle-graphics","status":"publish","type":"page","link":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/turtle-graphics\/","title":{"rendered":"Turtle Graphics"},"content":{"rendered":"<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/REC-html40\/loose.dtd\">\n<html><body><p>&ldquo;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Turtle_graphics\">Turtle Graphics<\/a>&ldquo; is a conceptual model for teaching computational thinking, based on a &ldquo;first-person cursor&rdquo;. In this schema, developed in the 1960s by computer scientist and constructivist educator <a href=\"https:\/\/en.wikipedia.org\/wiki\/Seymour_Papert\">Seymour Papert<\/a>, and inspired by <a href=\"https:\/\/en.wikipedia.org\/wiki\/Jean_Piaget\">Jean Piaget<\/a>&lsquo;s studies of children&rsquo;s learning and embodied cognition, vector graphics are produced using a relative cursor (the &ldquo;turtle&rdquo;) upon a Cartesian plane.<\/p>\n<p>The Turtle object has the following methods or API (application programmer&rsquo;s interface):<\/p>\n<pre class=\"lang:js decode:true \" title=\"Turtle Graphics API for 15104\">\/\/ makeTurtle(x, y) -- make a turtle at x, y, facing right, pen down\r\n\/\/ left(d) -- turn left by d degrees\r\n\/\/ right(d) -- turn right by d degrees\r\n\/\/ forward(p) -- move forward by p pixels\r\n\/\/ back(p) -- move back by p pixels\r\n\/\/ penDown() -- pen down\r\n\/\/ penUp() -- pen up\r\n\/\/ goto(x, y) -- go straight to this location\r\n\/\/ setColor(color) -- set the drawing color\r\n\/\/ setWeight(w) -- set line width to w\r\n\/\/ face(d) -- turn to this absolute direction in degrees\r\n\/\/ angleTo(x, y) -- what is the angle from my heading to location x, y?\r\n\/\/ turnToward(x, y, d) -- turn by d degrees toward location x, y\r\n\/\/ distanceTo(x, y) -- how far is it to location x, y?<\/pre>\n<p>And here is the actual Turtle Graphics implementation for p5.js:<\/p>\n<pre class=\"lang:default decode:true \" title=\"Turtle Implementation for 15104\">function turtleLeft(d) {\r\n    this.angle -= d;\r\n}\r\n\r\n\r\nfunction turtleRight(d) {\r\n    this.angle += d;\r\n}\r\n\r\n\r\nfunction turtleForward(p) {\r\n    var rad = radians(this.angle);\r\n    var newx = this.x + cos(rad) * p;\r\n    var newy = this.y + sin(rad) * p;\r\n    this.goto(newx, newy);\r\n}\r\n\r\n\r\nfunction turtleBack(p) {\r\n    this.forward(-p);\r\n}\r\n\r\n\r\nfunction turtlePenDown() {\r\n    this.penIsDown = true;\r\n}\r\n\r\n\r\nfunction turtlePenUp() {\r\n    this.penIsDown = false;\r\n}\r\n\r\n\r\nfunction turtleGoTo(x, y) {\r\n    if (this.penIsDown) {\r\n      stroke(this.color);\r\n      strokeWeight(this.weight);\r\n      line(this.x, this.y, x, y);\r\n    }\r\n    this.x = x;\r\n    this.y = y;\r\n}\r\n\r\n\r\nfunction turtleDistTo(x, y) {\r\n    return sqrt(sq(this.x - x) + sq(this.y - y));\r\n}\r\n\r\n\r\nfunction turtleAngleTo(x, y) {\r\n    var absAngle = degrees(atan2(y - this.y, x - this.x));\r\n    var angle = ((absAngle - this.angle) + 360) % 360.0;\r\n    return angle;\r\n}\r\n\r\n\r\nfunction turtleTurnToward(x, y, d) {\r\n    var angle = this.angleTo(x, y);\r\n    if (angle &lt; 180) {\r\n        this.angle += d;\r\n    } else {\r\n        this.angle -= d;\r\n    }\r\n}\r\n\r\n\r\nfunction turtleSetColor(c) {\r\n    this.color = c;\r\n}\r\n\r\n\r\nfunction turtleSetWeight(w) {\r\n    this.weight = w;\r\n}\r\n\r\n\r\nfunction turtleFace(angle) {\r\n    this.angle = angle;\r\n}\r\n\r\n\r\nfunction makeTurtle(tx, ty) {\r\n    var turtle = {x: tx, y: ty,\r\n                  angle: 0.0, \r\n                  penIsDown: true,\r\n                  color: color(128),\r\n                  weight: 1,\r\n                  left: turtleLeft, right: turtleRight,\r\n                  forward: turtleForward, back: turtleBack,\r\n                  penDown: turtlePenDown, penUp: turtlePenUp,\r\n                  goto: turtleGoTo, angleto: turtleAngleTo,\r\n                  turnToward: turtleTurnToward,\r\n                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,\r\n                  setColor: turtleSetColor, setWeight: turtleSetWeight,\r\n                  face: turtleFace};\r\n    return turtle;\r\n}<\/pre>\n<h2>Turtle Example 1\n<h2>\n<\/h2><\/h2><p>Here is an example using Turtle Graphics. Note that in order to post such code on WordPress, the entire Turtle object code must be included into your p5.js sketch file. Note that the Turtle code has been &ldquo;minified&rdquo; to save space.<\/p>\n<p><a data-width=\"400\" data-height=\"400\" class=\"p5_sketch_link\" href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2016\/10\/turtle-ex1.js\">turtle-ex1<\/a><iframe src=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/plugins\/p5-embedder\/p5_iframe.html\" class=\"p5_exampleFrame\" width=\"400\" height=\"400\"><\/iframe><pre class=\"language-javascript\"><code class=\"p5_editor language-javascript\">\nfunction setup() {\n    createCanvas(400, 400);\n    background(0);\n    var turtle = makeTurtle(130, 80);\n    turtle.penDown();\n    turtle.setColor(255);\n    for (var i = 0; i &lt; 1000; i++) {\n        turtle.forward(150);\n        turtle.right(141.5);\n        turtle.forward(60);\n        if (i % 20 === 0) {\n            turtle.forward(70);\n        }\n    }\n    noLoop();\n}\n\n\nfunction draw() {\n}\n\n\nfunction turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}\nfunction turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;\nvar newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){\nthis.forward(-p);}function turtlePenDown(){this.penIsDown=true;}\nfunction turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){\nif(this.penIsDown){stroke(this.color);strokeWeight(this.weight);\nline(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){\nreturn sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){\nvar absAngle=degrees(atan2(y-this.y,x-this.x));\nvar angle=((absAngle-this.angle)+360)%360.0;return angle;}\nfunction turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle&lt; 180){\nthis.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}\nfunction turtleSetWeight(w){this.weight=w;}function turtleFace(angle){\nthis.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,\nangle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,\nright:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,\npenUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,\nturnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,\nsetColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};\nreturn turtle;}\n<\/code><\/pre><\/p>\n<h2>Turtle Example 2<\/h2>\n<p>If you want to see animated turtles, you can issue turtle commands in <code>draw()<\/code> without erasing (calling <code>background()<\/code>). In this case, <code>draw<\/code> becomes your loop. To get a turtle whose behavior changes over time, you would need to give it commands whose values were based on things like the <code>millis()<\/code>, <code>random()<\/code>, <code>frameCount<\/code>, or other progressively-modified global variables.<\/p>\n<p><a data-width=\"400\" data-height=\"400\" class=\"p5_sketch_link\" href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2016\/10\/turtle-ex2.js\">turtle-ex2<\/a><iframe src=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/plugins\/p5-embedder\/p5_iframe.html\" class=\"p5_exampleFrame\" width=\"400\" height=\"400\"><\/iframe><pre class=\"language-javascript\"><code class=\"p5_editor language-javascript\">\nvar myTurtle;\nvar startFrame;\n\nfunction setup() {\n    createCanvas(400, 400);\n    background(0);\n    myTurtle = makeTurtle(width \/ 2, height \/ 2);\n    myTurtle.setColor(color(255, 200, 200));\n    myTurtle.setWeight(2); \n    myTurtle.penDown();\n    resetCanvas();\n    frameRate(10);\n}\n\nfunction draw() {\n    var step = (frameCount - startFrame)\/30.0;\n    myTurtle.forward(step);\n    myTurtle.left(6.0);\n    if (myTurtle.y &gt; height) resetCanvas();\n}\n\nfunction resetCanvas() {\n    background(0);\n    startFrame = frameCount;\n    myTurtle.penUp();\n    myTurtle.goto(width \/ 2, height \/ 2);\n    myTurtle.penDown();\n}\n\n\nfunction turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}\nfunction turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;\nvar newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){\nthis.forward(-p);}function turtlePenDown(){this.penIsDown=true;}\nfunction turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){\nif(this.penIsDown){stroke(this.color);strokeWeight(this.weight);\nline(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){\nreturn sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){\nvar absAngle=degrees(atan2(y-this.y,x-this.x));\nvar angle=((absAngle-this.angle)+360)%360.0;return angle;}\nfunction turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle&lt; 180){\nthis.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}\nfunction turtleSetWeight(w){this.weight=w;}function turtleFace(angle){\nthis.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,\nangle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,\nright:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,\npenUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,\nturnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,\nsetColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};\nreturn turtle;}\n<\/code><\/pre><\/p>\n<h2>Turtle Example 3<\/h2>\n<p>Here&rsquo;s an example of three Turtles (red, green and blue) chasing a gray &ldquo;target&rdquo;, whose location is based on Perlin noise. The turtles &ldquo;overshoot&rdquo; the target because they always move forward but can only turn 1 degree per frame (plus or minus a random 5 degrees to introduce some wandering into their paths).<\/p>\n<p><a data-width=\"400\" data-height=\"400\" class=\"p5_sketch_link\" href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2016\/10\/turtle-ex3.js\">turtle-ex3<\/a><iframe src=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/plugins\/p5-embedder\/p5_iframe.html\" class=\"p5_exampleFrame\" width=\"400\" height=\"400\"><\/iframe><pre class=\"language-javascript\"><code class=\"p5_editor language-javascript\">var t1, t2, t3;\nfunction setup() {\n    createCanvas(400, 400);\n    background(0);\n    t1 = makeTurtle(width \/ 2 + random(-100, 100), height \/ 2 + random(-100, 100));\n    t2 = makeTurtle(width \/ 2 + random(-100, 100), height \/ 2 + random(-100, 100));\n    t3 = makeTurtle(width \/ 2 + random(-100, 100), height \/ 2 + random(-100, 100));\n    t1.penDown();\n    t1.setColor(color(255, 0, 0));\n    t1.setWeight(3);\n    t2.penDown();\n    t2.setColor(color(0, 255, 0));\n    t2.setWeight(3);\n    t3.penDown();\n    t3.setColor(color(100, 100, 255));\n    t3.setWeight(3);\n    frameRate(10);\n}\n \nfunction draw() {\n    t1.forward(1);\n    t2.forward(2);\n    t3.forward(3);\n    var targetX = width * noise(frameCount \/ 1000);\n    var targetY = height * noise(100 + frameCount \/ 1000);\n    strokeWeight(1);\n    stroke(128);\n    point(targetX, targetY);\n    t1.turnToward(targetX, targetY, 1);\n    t2.turnToward(targetX, targetY, 1);\n    t3.turnToward(targetX, targetY, 1);\n    t1.left(random(-5, 5));\n    t2.left(random(-5, 5));\n    t3.left(random(-5, 5));\n    fill(0); \/\/ erase the area to show angles\n    noStroke();\n    stroke(2);\n    rect(0, 0, 120, 40);\n    push();\n        translate(20, 20);\n        push();\n            rotate(radians(t1.angleTo(targetX, targetY), 5, 25));\n            stroke(t1.color);\n            line(0, 0, 0, -20);\n        pop();\n        translate(40, 0);\n        push();\n            rotate(radians(t2.angleTo(targetX, targetY), 5, 25));\n            stroke(t2.color);\n            line(0, 0, 0, -20);\n        pop();\n        translate(40, 0);\n        push();\n            rotate(radians(t3.angleTo(targetX, targetY), 5, 25));\n            stroke(t3.color);\n            line(0, 0, 0, -20);\n        pop();\n    pop();\n    fill(255);\n    text(\"Angle from turtle to target\", 3, 52);\n}\n\n\nfunction turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}\nfunction turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;\nvar newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){\nthis.forward(-p);}function turtlePenDown(){this.penIsDown=true;}\nfunction turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){\nif(this.penIsDown){stroke(this.color);strokeWeight(this.weight);\nline(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){\nreturn sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){\nvar absAngle=degrees(atan2(y-this.y,x-this.x));\nvar angle=((absAngle-this.angle)+360)%360.0;return angle;}\nfunction turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle&lt; 180){\nthis.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}\nfunction turtleSetWeight(w){this.weight=w;}function turtleFace(angle){\nthis.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,\nangle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,\nright:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,\npenUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,\nturnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,\nsetColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};\nreturn turtle;}\n<\/code><\/pre><\/p><\/body><\/html>\n","protected":false},"excerpt":{"rendered":"<p>&ldquo;Turtle Graphics&ldquo; is a conceptual model for teaching computational thinking, based on a &ldquo;first-person cursor&rdquo;. In this schema, developed in the 1960s by computer scientist and constructivist educator Seymour Papert, and inspired by Jean Piaget&lsquo;s studies of children&rsquo;s learning and embodied cognition, vector graphics are produced using a relative cursor (the &ldquo;turtle&rdquo;) upon a Cartesian &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/turtle-graphics\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Turtle Graphics&#8221;<\/span><\/a><\/p>\n","protected":false},"author":535,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/pages\/5969"}],"collection":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/users\/535"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/comments?post=5969"}],"version-history":[{"count":3,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/pages\/5969\/revisions"}],"predecessor-version":[{"id":5975,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/pages\/5969\/revisions\/5975"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/media?parent=5969"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}