| 
				   | 
				
| (47 intermediate revisions by 2 users not shown) | 
| Line 1: | 
Line 1: | 
 | This is a very basic implementation of turtle graphics with [http://jsxgraph.org JSXGraph].  |  | This is a very basic implementation of turtle graphics in JavaScript with [http://jsxgraph.org JSXGraph].    | 
 | ===List of commands===
  |  | [http://u2d.com/turtle_js/index.html CanvasTurtle] does the same on browsers which support the ''canvas'' element.  | 
 | There is a predefined turtle object ''t''. Therefore, all commands
  |  | 
 | start with ''t'', like ''t.fd(100)'';
  |  | 
 | * t.forward(len); or t.fd(len);
  |  | 
 | * t.back(len); or t.bk(len);
  |  | 
 | * t.right(angle); or t.rt(angle);
  |  | 
 | * t.left(angle); or t.lt(angle);
  |  | 
 | * t.penUp();
  |  | 
 | * t.penDown();
  |  | 
 | * t.clean();
  |  | 
 | * t.setPos(x,y);
  |  | 
 | 
  |  | 
  | 
 | ===Snowflake Example===  |  | * [[List of available commands]]  | 
 |  |    | 
 |  | ===Snowflake and Branches Example===  | 
 | <html>  |  | <html>  | 
 | <link rel="stylesheet" type="text/css" href="http://jsxgraph.uni-bayreuth.de/distrib/jsxgraph.css" />
  |  | <form><textarea id="input1" rows=7 cols=35 wrap="off" style="width:300px; float:left;">  | 
 | <script type="text/javascript" src="http://jsxgraph.uni-bayreuth.de/distrib/prototype.js"></script>
  |  | 
 | <script type="text/javascript" src="http://jsxgraph.uni-bayreuth.de/distrib/jsxgraphcore.js"></script>
  |  | 
 | <form><textarea id="input" rows=7 cols=35 wrap="off" style="width:600px">  |  | 
 | function side(size, level) {  |  | function side(size, level) {  | 
 |      if (level==0) {  |  |      if (level==0) {  | 
| Line 33: | 
Line 22: | 
 | 
  |  | 
  | 
 | function snowflake(size, level) {  |  | function snowflake(size, level) {  | 
 |      (3).times(function() {  |  |      for (var i=0;i<3;i++) {  | 
 |          side(size, level);  |  |          side(size, level);  | 
 |          t.rt(120);  |  |          t.rt(120);  | 
 |      });  |  |      };  | 
 | }  |  | }  | 
 | 
  |  | 
  | 
 | t.clean();  |  | t.clearScreen();  | 
 |  | t.hideTurtle();  | 
 |  | t.setPenSize(1)  | 
 |  | t.setPenColor("#000000")  | 
 | t.lt(30);  |  | t.lt(30);  | 
 | t.setPos(0,-100);  |  | t.setPos(0,-100);  | 
 | snowflake(250, 3);  |  | snowflake(250, 4);  | 
 | </textarea><br />  |  | </textarea>  | 
 | <input type="button" value="run" onClick="run()">   |  | <textarea id="input2" rows=7 cols=35 wrap="off" style="width:300px">  | 
 | </form>
  |  | function branch(length, level)  | 
 | <div id="box" class="jxgbox" style="width:600px; height:600px;"></div>
  |  | {  | 
 | <script language="JavaScript">
  |  |     if(level == 0) return  | 
 |             var turtleObj = function(board,attributes) {
  |  |     t.fd(length)  | 
 |                 this.turtleIsHidden = false;
  |  |     t.lt(45)  | 
 |                 this.board = board;
  |  |     branch(length/2, level-1)  | 
 |                 if (attributes==null) {
  |  |     t.rt(90)  | 
 |                     this.attributes = {
  |  |     branch(length/2, level-1)  | 
 |                         strokeColor:'#000000'
  |  |     t.lt(45)  | 
 |                     };
  |  |     t.bk(length)  | 
 |                 } else {
  |  | }  | 
 |                     this.attributes = attributes;
  |  | 
 |                 }
  |  | 
 |                 this.attributes.straightFirst = false;
  |  | 
 |                 this.attributes.straightLast = false;
  |  | 
 |                 this.init();
  |  | 
 |             };
  |  | 
 | 
  |  | 
  | 
 |             turtleObj.prototype.init = function() {
  |  | function lbranch(length, angle, level)  | 
 |                 this.pos = [0,0];
  |  | {  | 
 |                 this.isPenDown = true;
  |  |     t.fd(2*length)  | 
 |                 this.dir = 90;
  |  |     node(length, angle, level)  | 
 |                 /*
  |  |     t.bk(2*length)  | 
 |                 this.points = [];
  |  | }  | 
 |                 var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
  |  | function rbranch(length, angle, level)  | 
 |                 p.needsRegularUpdate = false;
  |  | {  | 
 |                 this.points.push(p);
  |  |     t.fd(length)  | 
 |                 */
  |  |     node(length, angle, level)  | 
 |                 
  |  |     t.bk(length)  | 
 |                 this.xArr = [this.pos[0]];
  |  | }  | 
 |                 this.yArr = [this.pos[1]];
  |  | 
 | 
  |  | 
  | 
 |                 this.turtle = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
  |  | function node(length, angle, level)  | 
 |                 this.turtle2 = this.board.createElement('point',[this.pos[0],this.pos[1]+20],{fixed:true,name:' ',visible:false});
  |  | {  | 
 |                 this.arrow = this.board.createElement('line',[this.turtle,this.turtle2],
  |  |     if (level == 0) return;  | 
 |                         {lastArrow:true,strokeColor:'#ff0000',straightFirst:false,straightLast:false});
  |  |     t.lt(angle)  | 
 |             }
  |  |     lbranch(length, angle, level -1)  | 
 |  |     t.rt(2*angle)  | 
 |  |     rbranch(length, angle, level-1)  | 
 |  |     t.lt(angle)  | 
 |  | }  | 
 | 
  |  | 
  | 
 |             turtleObj.prototype.forward = function(len) {
  |  | t.clearScreen()  | 
 |                 if (len==0) { return; }
  |  | t.hideTurtle();  | 
 |                 var dx = -len*Math.cos(this.dir*Math.PI/180.0);
  |  | //branch(100,6)  | 
 |                 var dy = len*Math.sin(this.dir*Math.PI/180.0);
  |  | 
 |                 if (!this.turtleIsHidden) {
  |  | 
 |                     var t = this.board.createElement('transform', [dx,dy], {type:'translate'});
  |  | 
 |                     t.applyOnce(this.turtle);
  |  | 
 |                     t.applyOnce(this.turtle2);
  |  | 
 |                 }
  |  | 
 |                 this.pos[0] += dx;
  |  | 
 |                 this.pos[1] += dy;
  |  | 
 |                 this.xArr.push(this.pos[0]);
  |  | 
 |                 this.yArr.push(this.pos[1]);
  |  | 
 |                 /*
  |  | 
 |                 var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
  |  | 
 |                 p.needsRegularUpdate = false;
  |  | 
 |                 this.points.push(p);
  |  | 
 |                 
  |  | 
 |                 if (this.isPenDown) {
  |  | 
 |                     var li = this.board.createElement('line',[this.points[this.points.length-2],p],this.attributes);
  |  | 
 |                     li.needsRegularUpdate = false;
  |  | 
 |                 }
  |  | 
 |                 */
  |  | 
 |             };
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.back = function(len) {
  |  | 
 |                 this.forward(-len);
  |  | 
 |             }
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.right = function(angle) {
  |  | 
 |                 this.dir += angle;
  |  | 
 |                 if (!this.turtleIsHidden) {
  |  | 
 |                     var t = this.board.createElement('transform', [-angle*Math.PI/180.0,this.turtle], {type:'rotate'});
  |  | 
 |                     t.applyOnce(this.turtle2);
  |  | 
 |                 }
  |  | 
 |             }
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.left = function(angle) {
  |  | 
 |                 this.right(-angle);
  |  | 
 |             }
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.penUp = function() {
  |  | 
 |                 this.isPenDown = false;
  |  | 
 |             }
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.penDown = function() {
  |  | 
 |                 this.isPenDown = true;
  |  | 
 |             }
  |  | 
 | 
  |  | 
  | 
 |             turtleObj.prototype.clean = function() {
  |  | t.setPenSize(5)  | 
 |                 for(var el in this.board.objects) {
  |  | t.setPenColor("#008800")  | 
 |                     this.board.removeObject(el);
  |  | t.setPos(30, -150)  | 
 |                 }
  |  | lbranch(25, 20, 7)  | 
 |                 this.init();
  |  | </textarea><br />  | 
 |             }
  |  | <input type="button" value="run example 1" onClick="run(1)">   | 
 |    |  | <input type="button" value="run example 2" onClick="run(2)">   | 
 |             turtleObj.prototype.setPos = function(x,y) {
  |  | </form>  | 
 |                 this.pos = [x,y];
  |  | </html>  | 
 |                 if (!this.turtleIsHidden) {
  |  | <jsxgraph width="600" height="600" box="box">  | 
 |                     this.turtle.setPositionDirectly(JXG.COORDS_BY_USER,x,y);
  |  | var brd = JXG.JSXGraph.initBoard('box', {boundingbox: [-300, 300, 300, -300]});  | 
 |                     this.turtle2.setPositionDirectly(JXG.COORDS_BY_USER,x,y+20);
  |  | var t = brd.create('turtle');  | 
 |                     var t = this.board.createElement('transform', [-this.dir*Math.PI/180.0,this.turtle], {type:'rotate'});
  |  | function run(nr) {  | 
 |                     t.applyOnce(this.turtle2);
  |  | 
 |                 }
  |  | 
 |                 /*
  |  | 
 |                 var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
  |  | 
 |                 p.needsRegularUpdate = false;
  |  | 
 |                 this.points.push(p);
  |  | 
 |                 */
  |  | 
 |             }
  |  | 
 |             turtleObj.prototype.showTurtle = function() { 
  |  | 
 |                 this.turtleIsHidden = false; 
  |  | 
 |             };
  |  | 
 |             turtleObj.prototype.hideTurtle = function() { 
  |  | 
 |                 this.turtleIsHidden = true;
  |  | 
 |                 this.setPos(this.pos[0],this.pos[1]);
  |  | 
 |             };
  |  | 
 |    |  | 
 |             turtleObj.prototype.fd = function(len) { this.forward(len); };
  |  | 
 |             turtleObj.prototype.bk = function(len) { this.back(len); };
  |  | 
 |             turtleObj.prototype.lt = function(angle) { this.left(angle); };
  |  | 
 |             turtleObj.prototype.rt = function(angle) { this.right(angle); };
  |  | 
 |    |  | 
 |             var brd = JXG.JSXGraph.initBoard('box', {originX: 300, originY: 300, unitX: 1, unitY: 1});
  |  | 
 |             var t = new turtleObj(brd);
  |  | 
 |  
  |  | 
 | function run() {  |  | 
 |    brd.suspendUpdate();  |  |    brd.suspendUpdate();  | 
 |   //t.hideTurtle();
  |  |    eval(document.getElementById('input'+nr).value);  | 
 |    eval($('input').value);  |  | 
 |    brd.unsuspendUpdate();  |  |    brd.unsuspendUpdate();  | 
 | }  |  | }  | 
 | </script>  |  | </jsxgraph>  | 
 | </html>
  |  | 
 | 
  |  | 
  | 
 | ===References===  |  | ===References===  | 
 | * The snowflake example has been adapted from the excellent [http://u2d.com/turtle_js/index.html CanvasTurtle]  |  | * The snowflake and branches example have been adapted from the excellent [http://u2d.com/turtle_js/index.html CanvasTurtle]  | 
 | 
  |  | 
  | 
 | ===The turtle graphics code===  |  | ===The turtle graphics code===  | 
 | <source lang="html4strict">  |  | <source lang="html4strict">  | 
 | <link rel="stylesheet" type="text/css" href="http://jsxgraph.uni-bayreuth.de/distrib/jsxgraph.css" />  |  | <form><textarea id="input1" rows=7 cols=35 wrap="off" style="width:300px; float:left;">  | 
 | <script type="text/javascript" src="http://jsxgraph.uni-bayreuth.de/distrib/prototype.js"></script>
  |  | turtle code...  | 
 | <script type="text/javascript" src="http://jsxgraph.uni-bayreuth.de/distrib/jsxgraphcore.js"></script>
  |  | </textarea>  | 
 | <div id="box" class="jxgbox" style="width:600px; height:600px;"></div>  |  | <input type="button" value="run example 1" onClick="run(1)">    | 
 | </source>  |  | </source>  | 
 | 
  |  | 
  | 
 | <source lang="javascript">  |  | <source lang="javascript">  | 
 |             var turtleObj = function(board,attributes) {
  |  | var brd = JXG.JSXGraph.initBoard('box', {boundingbox: [-300, 300, 300, -300]});  | 
 |                 this.board = board;
  |  | var t = brd.create('turtle');  | 
 |                 if (attributes==null) {
  |  | 
 |                     this.attributes = {
  |  | 
 |                         strokeColor:'#000000'
  |  | 
 |                     };
  |  | 
 |                 } else {
  |  | 
 |                     this.attributes = attributes;
  |  | 
 |                 }
  |  | 
 |                 this.attributes.straightFirst = false;
  |  | 
 |                 this.attributes.straightLast = false;
  |  | 
 |                 this.init();
  |  | 
 |             };
  |  | 
 |    |  | 
 |             turtleObj.prototype.init = function() {
  |  | 
 |                 this.points = [];
  |  | 
 |                 this.pos = [0,0];
  |  | 
 |                 this.isPenDown = true;
  |  | 
 |                 this.dir = 90;
  |  | 
 |                 var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
  |  | 
 |                 this.points.push(p);
  |  | 
 |                 this.turtle = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
  |  | 
 |                 this.turtle2 = this.board.createElement('point',[this.pos[0],this.pos[1]+20],{fixed:true,name:' ',visible:false});
  |  | 
 |                 this.board.createElement('line',[this.turtle,this.turtle2],
  |  | 
 |                         {lastArrow:true,strokeColor:'#ff0000',straightFirst:false,straightLast:false});
  |  | 
 |             }
  |  | 
 |    |  | 
 |             turtleObj.prototype.forward = function(len) {
  |  | 
 |                 if (len==0) { return; }
  |  | 
 |                 var dx = -len*Math.cos(this.dir*Math.PI/180.0);
  |  | 
 |                 var dy = len*Math.sin(this.dir*Math.PI/180.0);
  |  | 
 |                 var t = this.board.createElement('transform', [dx,dy], {type:'translate'});
  |  | 
 |                 t.applyOnce(this.turtle);
  |  | 
 |                 t.applyOnce(this.turtle2);
  |  | 
 |                 this.pos[0] += dx;
  |  | 
 |                 this.pos[1] += dy;
  |  | 
 |                 var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
  |  | 
 |                 this.points.push(p);
  |  | 
 |    |  | 
 |                 if (this.isPenDown) {
  |  | 
 |                     this.board.createElement('line',[this.points[this.points.length-2],p],this.attributes);
  |  | 
 |                 }
  |  | 
 |                 //this.board.update();
  |  | 
 |             };
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.back = function(len) {
  |  | 
 |                 this.forward(-len);
  |  | 
 |             }
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.right = function(angle) {
  |  | 
 |                 this.dir += angle;
  |  | 
 |                 var t = this.board.createElement('transform', [-angle*Math.PI/180.0,this.turtle], {type:'rotate'});
  |  | 
 |                 t.applyOnce(this.turtle2);
  |  | 
 |                 //this.board.update();
  |  | 
 |             }
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.left = function(angle) {
  |  | 
 |                 this.right(-angle);
  |  | 
 |             }
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.penUp = function() {
  |  | 
 |                 this.isPenDown = false;
  |  | 
 |             }
  |  | 
 |             
  |  | 
 |             turtleObj.prototype.penDown = function() {
  |  | 
 |                 this.isPenDown = true;
  |  | 
 |             }
  |  | 
 | 
  |  | 
  | 
 |             turtleObj.prototype.clean = function() {
  |  | function run(nr) {  | 
 |                 for(var el in this.board.objects) {
  |  | 
 |                     this.board.removeObject(el);
  |  | 
 |                 }
  |  | 
 |                 this.init();
  |  | 
 |             }
  |  | 
 |    |  | 
 |             turtleObj.prototype.setPos = function(x,y) {
  |  | 
 |                 this.pos = [x,y];
  |  | 
 |                 this.turtle.setPositionDirectly(JXG.COORDS_BY_USER,x,y);
  |  | 
 |                 this.turtle2.setPositionDirectly(JXG.COORDS_BY_USER,x,y+20);
  |  | 
 |                 var t = this.board.createElement('transform', [-this.dir*Math.PI/180.0,this.turtle], {type:'rotate'});
  |  | 
 |                 t.applyOnce(this.turtle2);
  |  | 
 |                 var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
  |  | 
 |                 this.points.push(p);
  |  | 
 |                 //this.board.update();
  |  | 
 |             }
  |  | 
 |    |  | 
 |             turtleObj.prototype.fd = function(len) { this.forward(len); };
  |  | 
 |             turtleObj.prototype.bk = function(len) { this.back(len); };
  |  | 
 |             turtleObj.prototype.lt = function(angle) { this.left(angle); };
  |  | 
 |             turtleObj.prototype.rt = function(angle) { this.right(angle); };
  |  | 
 |    |  | 
 |             var brd = JXG.JSXGraph.initBoard('box', {originX: 300, originY: 300, unitX: 1, unitY: 1});
  |  | 
 |             var t = new turtleObj(brd);
  |  | 
 |  
  |  | 
 | function run() {  |  | 
 |    brd.suspendUpdate();  |  |    brd.suspendUpdate();  | 
 |    eval($('input').value);  |  |    eval($('input'+nr).value);  | 
 |    brd.unsuspendUpdate();  |  |    brd.unsuspendUpdate();  | 
 | }  |  | }  | 
 | </source>  |  | </source>  | 
 |  |  | 
 | [[Category:Examples]]  |  | [[Category:Examples]]  | 
 |  | [[Category:Turtle Graphics]]  | 
 |  | [[Category:Fractals]]  |