|  |   | 
| (42 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.xArr = [this.pos[0]];
 |  |     t.fd(2*length) | 
|  |                 this.yArr = [this.pos[1]];
 |  |     node(length, angle, level) | 
|  |  |     t.bk(2*length) | 
|  |  | } | 
|  |  | function rbranch(length, angle, level) | 
|  |  | { | 
|  |  |     t.fd(length) | 
|  |  |     node(length, angle, level) | 
|  |  |     t.bk(length) | 
|  |  | } | 
|  | 
 |  | 
 | 
|  |                 this.isPenDown =true;
 |  | function node(length, angle, level) | 
|  |                 this.dir = 90;
 |  | { | 
|  |                 this.curve = this.board.createElement('curve',[this.xArr,this.yArr],{curveType:'plot'});
 |  |     if (level == 0) return; | 
|  |  |     t.lt(angle) | 
|  |  |     lbranch(length, angle, level -1) | 
|  |  |     t.rt(2*angle) | 
|  |  |     rbranch(length, angle, level-1) | 
|  |  |     t.lt(angle) | 
|  |  | } | 
|  | 
 |  | 
 | 
|  |                 /*
 |  | t.clearScreen() | 
|  |                 this.points = [];
 |  | t.hideTurtle(); | 
|  |                 var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
 |  | //branch(100,6) | 
|  |                 p.needsRegularUpdate = 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.arrow = this.board.createElement('line',[this.turtle,this.turtle2],
 |  | 
|  |                         {lastArrow:true,strokeColor:'#ff0000',straightFirst:false,straightLast:false});
 |  | 
|  |             }
 |  | 
|  | 
 |  | 
 | 
|  |             turtleObj.prototype.forward = function(len) {
 |  | t.setPenSize(5) | 
|  |                 if (len==0) { return; }
 |  | t.setPenColor("#008800") | 
|  |                 var dx = -len*Math.cos(this.dir*Math.PI/180.0);
 |  | t.setPos(30, -150) | 
|  |                 var dy = len*Math.sin(this.dir*Math.PI/180.0);
 |  | lbranch(25, 20, 7) | 
|  |                 if (!this.turtleIsHidden) {
 |  | </textarea><br /> | 
|  |                     var t= this.board.createElement('transform', [dx,dy], {type:'translate'});
 |  | <input type="button" value="run example 1" onClick="run(1)">  | 
|  |                     t.applyOnce(this.turtle);
 |  | <input type="button" value="run example 2" onClick="run(2)">  | 
|  |                     t.applyOnce(this.turtle2);
 |  | </form> | 
|  |                 }
 |  | </html> | 
|  |                 this.pos[0] += dx;
 |  | <jsxgraph width="600" height="600" box="box"> | 
|  |                 this.pos[1] += dy;
 |  | var brd = JXG.JSXGraph.initBoard('box', {boundingbox: [-300, 300, 300, -300]}); | 
|  |                 this.xArr.push(this.pos[0]);
 |  | var t = brd.create('turtle'); | 
|  |                 this.yArr.push(this.pos[1]);
 |  | function run(nr) { | 
|  |                 /*
 |  | 
|  |                 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() {
 |  | 
|  |                 for(var el in this.board.objects) {
 |  | 
|  |                     this.board.removeObject(el);
 |  | 
|  |                 }
 |  | 
|  |                 this.init();
 |  | 
|  |             }
 |  | 
|  |   |  | 
|  |             turtleObj.prototype.setPos = function(x,y) {
 |  | 
|  |                 this.pos = [x,y];
 |  | 
|  |                 if (!this.turtleIsHidden) {
 |  | 
|  |                     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});
 |  | 
|  |                 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);
 |  | 
|  |             t.curve.prototype.updateDataArray = function(){
 |  | 
|  |                 this.dataX = t.xArr;
 |  | 
|  |                 this.dataY = t.yArr;
 |  | 
|  |             };
 |  | 
|  |  
 |  | 
|  | 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"> | 
|  |             varturtleObj =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() {
 |  | function run(nr) { | 
|  |                 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() {
 |  | 
|  |                 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]] |