Difference between revisions of "Turtle Graphics"

From JSXGraph Wiki
Jump to navigationJump to search
 
(53 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.board = board;
+
    t.lt(45)
                if (attributes==null) {
+
    branch(length/2, level-1)
                    this.attributes = {
+
    t.rt(90)
                        strokeColor:'#000000'
+
    branch(length/2, level-1)
                    };
+
    t.lt(45)
                } else {
+
    t.bk(length)
                    this.attributes = attributes;
+
}
                }
 
                this.attributes.straightFirst = false;
 
                this.attributes.straightLast = false;
 
                this.init();
 
            };
 
  
            turtleObj.prototype.init = function() {
+
function lbranch(length, angle, level)
                this.points = [];
+
{
                this.pos = [0,0];
+
    t.fd(2*length)
                this.isPenDown = true;
+
    node(length, angle, level)
                this.dir = 90;
+
    t.bk(2*length)
                var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
+
}
                this.points.push(p);
+
function rbranch(length, angle, level)
                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});
+
    t.fd(length)
                this.board.createElement('line',[this.turtle,this.turtle2],
+
    node(length, angle, level)
                        {lastArrow:true,strokeColor:'#ff0000',straightFirst:false,straightLast:false});
+
    t.bk(length)
            }
+
}
  
            turtleObj.prototype.forward = function(len) {
+
function node(length, angle, level)
                if (len==0) { return; }
+
{
                var dx = -len*Math.cos(this.dir*Math.PI/180.0);
+
    if (level == 0) return;
                var dy = len*Math.sin(this.dir*Math.PI/180.0);
+
    t.lt(angle)
                var t = this.board.createElement('transform', [dx,dy], {type:'translate'});
+
    lbranch(length, angle, level -1)
                t.applyOnce(this.turtle);
+
    t.rt(2*angle)
                t.applyOnce(this.turtle2);
+
    rbranch(length, angle, level-1)
                this.pos[0] += dx;
+
    t.lt(angle)
                this.pos[1] += dy;
+
}
                var p = this.board.createElement('point',this.pos,{fixed:true,name:' ',visible:false});
 
                this.points.push(p);
 
  
                if (this.isPenDown) {
+
t.clearScreen()
                    this.board.createElement('line',[this.points[this.points.length-2],p],this.attributes);
+
t.hideTurtle();
                }
+
//branch(100,6)
                //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() {
+
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>
                this.turtle.setPositionDirectly(JXG.COORDS_BY_USER,x,y);
+
<jsxgraph width="600" height="600" box="box">
                this.turtle2.setPositionDirectly(JXG.COORDS_BY_USER,x,y+20);
+
var brd = JXG.JSXGraph.initBoard('box', {boundingbox: [-300, 300, 300, -300]});
                var t = this.board.createElement('transform', [-this.dir*Math.PI/180.0,this.turtle], {type:'rotate'});
+
var t = brd.create('turtle');
                t.applyOnce(this.turtle2);
+
function run(nr) {
                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(document.getElementById('input'+nr).value);
 
   brd.unsuspendUpdate();
 
   brd.unsuspendUpdate();
 
}
 
}
</script>
+
</jsxgraph>
</html>
 
  
 
===References===
 
===References===
* The snowflake example is 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]]

Latest revision as of 09:40, 9 June 2011

This is a very basic implementation of turtle graphics in JavaScript with JSXGraph. CanvasTurtle does the same on browsers which support the canvas element.

Snowflake and Branches Example


References

  • The snowflake and branches example have been adapted from the excellent CanvasTurtle

The turtle graphics code

<form><textarea id="input1" rows=7 cols=35 wrap="off" style="width:300px; float:left;">
turtle code...
</textarea>
<input type="button" value="run example 1" onClick="run(1)">
var brd = JXG.JSXGraph.initBoard('box', {boundingbox: [-300, 300, 300, -300]});
var t = brd.create('turtle');

function run(nr) {
  brd.suspendUpdate();
  eval($('input'+nr).value);
  brd.unsuspendUpdate();
}