Skip to content

Commit

Permalink
added Turtle Graphics exercises
Browse files Browse the repository at this point in the history
  • Loading branch information
dobbs committed Dec 23, 2011
1 parent 53820b7 commit 330e0ee
Show file tree
Hide file tree
Showing 2 changed files with 273 additions and 0 deletions.
57 changes: 57 additions & 0 deletions tg.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html><head>
<title>Turtle Geometry</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="turtle.min.js"></script>
<script type="text/javascript" src="tg.js"></script>
<style type="text/css">
.column {
display: block;
float: left;
width: 30em;
margin-right: 3em;
}
canvas.tg {border: 1pt solid black;}
.turtle-hide {display:none;}
#tg-commandline-history-show {text-decoration: none;}
#tg-exercises a {display: block;}
</style>
</head>
<body>
<div class="column">
<h1>Turtle Geometry exercises</h1>
<canvas width="500" height="500" id="tg-tracks" class="tg"></canvas>
<form><input id="tg-commandline" type="text" size="95" name="tg-commandline"></form>
<a href="" id="tg-commandline-history-show">&#x25BA; History</a><section id="tg-commandline-history" class="turtle-hide"></section>
</div>
<div class="column">
<p>
Exercises and examples from chapter one of

<a href="http://books.google.com/books/about/Turtle_geometry.html?id=3geYp44hJVcC">Turtle Geometry by Abelson and diSessa</a>

implemented in javascript. Kinda blown away by this book: only on
chapter one and this page already offers a pretty fun playground for
exploring geometry and rudimentary graphics programming.
</p>
<p>
Click some of the links below for examples and inspiration. You can
also type commands into the form below the turtle's sandbox.
Commands you type will be saved in the history below the sandbox.
</p>
<p>
Pen controls include <code>penup</code>, <code>pendown</code>,
<code>pensize <em>pixels</em></code>, and <code>pencolor
<em>color</em></code>. Any CSS color name or hex value will work
for color:
<a href="http://en.wikipedia.org/wiki/Web_colors">Wikipedia: Web Colors</a>
</p>
<p>
Have a look at the source code for these exercises if you like:
<a href="tg.js">tg.js</a>
</p>
<div id="tg-exercises" class="column">
</div>
</div>
</body>
</html>
216 changes: 216 additions & 0 deletions tg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
var tg = tg || {};
(function ($, Turtle, window, document, undefined) {

function init(that) {
$.extend(that, {
thing: function thing() {
var segments = [100, 100, 50, 50, 100, 25, 25];
$.each(segments, function (i, pixels) {
that.move(pixels).turn(90);
});
that.move(50);
},

arcr: function arcr(r, deg) {
for(var i = 0; i < deg; i++) {
that.move(r).turn(1);
}
return that;
},

arcl: function arcl(r, deg) {
for(var i = 0; i < deg; i++) {
that.move(r).turn(-1);
}
return that;
},

arc: function arc(r, deg, ccw) {
var step = 2*Math.PI*r/360;
for(var i = 0; i < deg; i++) {
that.move(step).turn(ccw ? -1 : 1);
}
return that;
},

poly: function poly(side, angle) {
var sum = 0;
do {
that.move(side).turn(angle);
sum = sum + parseInt(angle);
} while (sum % 360 != 0);
return that;
},

newpoly: function newpoly(side, angle, reps) {
if (!reps)
reps = 360 / (3*parseInt(angle));
for (var i=0; i<reps; i++) {
that.move(side).turn(angle);
that.move(side).turn(2*angle);
}
return that;
},

circles: function circles() {
for(var i=0; i<9; i++) {
that.poly(15, 15);
that.turn(40);
}
return that;
},

polyspi: function polyspi(side, angle, inc, reps) {
side = parseInt(side);
angle = parseInt(angle);
inc = parseInt(inc);
if (!inc)
inc = 3;
if (!reps)
reps = 3600 / angle;
for(var i=0; i < reps; i++) {
that.move(side + i*inc).turn(angle);
}
return that;
},

inspi: function inspi(side, angle, inc, reps) {
if (!reps)
reps = 500;
for (var i=0; i<reps; i++) {
that.move(parseInt(side)).turn(parseInt(angle) + parseInt(inc)*i);
}
return that;
},

doublepoly: function doublepoly(side1, side2, angle, reps) {
if (!reps)
reps = 180 / parseInt(angle);
for (var i=0; i<reps; i++) {
that.move(side1).turn(angle);
that.move(side2).turn(angle);
}
return that;
},

spiro: function spiro(side, angle, inc, reps) {
var sum = 0;
angle = parseInt(angle);
do {
that.polyspi(side, angle, inc, reps);
sum = sum + angle;
} while (sum % 360 != 0);
return that;
},

gspiro: function gspiro(side, angle, max /*rest*/) {
var corners = [];
for (var i = 3; i < arguments.length; i++)
corners.push(parseInt(arguments[i]));
for (var j = 1; j <= max; j++)
that.move(side*j).turn(corners.indexOf(j) < 0 ? -angle : angle);
return that;
}

});
that.pendown();
return that;
}

$.extend(tg, {
examples: {
crestagon: 'arc 100 180. turn 134. arc 141 90 ccw. turn 135',
thing1: '4x: thing',
thing2: '9x: thing. turn 10. move 50',
thing3: '8x: thing. turn -45. move 100',
circle: '360x: move 1. turn 1',
circles: '9x: poly 15 10. turn 40',
clickme9x: 'arcl 1 90. arcr 1 90. turn -160',
flower: '6x: arcr 3 60. turn 120. arcr 3 60. turn 180',
poly72: 'clear. poly 50 72 5',
poly144: 'clear. poly 60 144 5',
poly60: 'clear. poly 50 60 6',
poly108: 'clear. poly 80 108 10',
poly135: 'clear. poly 80 135 8',
newpoly30: 'clear. newpoly 50 30 4',
newpoly144: 'clear. newpoly 30 144 5',
newpoly45: 'clear. newpoly 30 45 8',
newpoly125: 'clear. newpoly 10 125 24',
polyspi95: 'clear. polyspi 1 95',
polyspi90: 'clear. polyspi 1 90',
polyspi120: 'clear. polyspi 1 120',
polyspi117: 'clear. polyspi 1 117',
inspi_0_7: 'clear. inspi 10 0 7 550',
inspi_2_20: 'clear. inspi 30 2 20 100',
inspi_20_40: 'clear. inspi 30 40 30 100',
spiro_90_10: 'clear. spiro 10 90 10 10',
spiro_144_8: 'clear. spiro 10 144 8 8',
spiro_60_10: 'clear. spiro 10 60 10 10',
gspiro_45_11_89: '8x: gspiro 2 45 11 8 9',
gspiro_120_6_13: '3x: gspiro 10 120 6 1 3',
gspiro_90_11_345: '4x: gspiro 10 90 11 3 4 5',
gspiro_90_8_48: 'clear. gspiro 10 90 8 4 8',
gspiro_120_11_3467: 'clear. gspiro 10 120 11 3 4 6 7'
}
});

$(function () {
var $commandline = $('#tg-commandline');
var $canvas = $('#tg-tracks');
Turtle.interactiveCanvas(
$canvas.get(0).getContext('2d'),
$commandline.get(0)
);
window.tg_commandline_history = new Turtle.History($commandline.get(0), window.localStorage, {
useInputValueForRevisionName: true
});
window.tg_commandline_history.syncLocalStorage();

$("#tg-commandline-history-show").click(function (event) {
event.stopPropagation();
event.preventDefault();
$history = $(window.tg_commandline_history.element);
if ($history.hasClass('turtle-hide')) {
$(event.target).html('&#x25ba History');
}
else {
$(event.target).html('&#x25bc History');
}
$history.toggleClass('turtle-hide');
return false;
});

function dispatchChangeEvent($element) {
var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true ); // event type,bubbling,cancelable
$element.get(0).dispatchEvent(event);
}

var $exercises = $('#tg-exercises');
$.each(Object.keys(tg.examples).sort(), function (i, example) {
var $link = $('<a href="">');
var command = tg.examples[example];
$link.html('<b>' + example + '</b> ' + command);
$link.click(function (e) {
e.preventDefault();
$commandline.val(command);
dispatchChangeEvent($commandline);
return false;
} );
$exercises.append($link);
});

tg.T = init(Turtle.interactiveTurtle);

setTimeout(function flowerAndStem () {
tg.T.pensize(6).pencolor('green').turn(45).arc(100, 60).arc(100, 60, 'ccw');
tg.T.home().pensize(12).pencolor('red');
for(var i=0; i<5; i++)
tg.T.arc(80, 60).turn(120).arc(80, 60).turn(120+72);
tg.T.penup().turn(-90).move(150).turn(90).pendown().pencolor('blue').pensize(1);
}, 100);
});



})(jQuery, Turtle, this, this.document);

0 comments on commit 330e0ee

Please sign in to comment.