Ask
StoreFeaturesDocsShareSupport News Sign UpSign In

Sage Turtle via JSXGraph

Views: 421

## CoCalc Turtle Graphics using JSXGraph

Authors: Norbert Domes (sagenb version), William Stein (modified for CoCalc)

examples (sage code see below)

```def displacement(s,alpha):
"""
returns the displacement vector with length s and
direction alpha

INPUT::

s  -  number

alpha  -  number (degrees from 0 to 360)

"""
return s*vector(RR,(cos(pi*alpha/180),sin(pi*alpha/180)))

class Turtle():
jsx_template = u"""
<p><!-- JSXGraph MediaWiki extension 0.3.1 -->
<link rel='stylesheet' type='text/css' href='http://jsxgraph.uni-bayreuth.de/distrib/jsxgraph.css' />
<script src='https://cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.99.5/jsxgraphcore.js' type='text/javascript'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.99.5/geonext.min.js' type='text/javascript'></script>

<div id='jxgbox-_id_' class='jxgbox' style='width:600px; height:600px;'></div>

<script type='text/javascript'>

// board options see JSXGraph reference
var brd = JXG.JSXGraph.initBoard('jxgbox-_id_', _board_options_ );

// create turtle at point (0,0) looking in direction 0
var t = brd.create('turtle',[[0,0],0]);

Code = _code_list_

function run() {
eval(Code.shift());
setTimeout(run,delay);
if (Code.length < 1) return;
}

delay = _delay_;
run()

</script>
</p>
"""

def __init__(self,board_options="{boundingbox:[-300,300,300,-300]}"):
"""
create a new turtle and the 'board' to be moved on.

the geometry of the board is fixed to 600x600px

origin (0,0) in the center

valid board options see JSXGraph reference

set turtle to (0,0) and direction to 0 (turtle looking to the right)

TODO::

create more than one turtle on one board

NOTE:

only those python turtle methods with a counterpart in JSXGraph are implemented

AUTHORS:

Norbert Domes

"""
import uuid
self.html = Turtle.jsx_template.replace('_id_', str(uuid.uuid4())).replace('_board_options_',board_options)
self.code = []
self.position = vector((0,0))
self.heading = 0

def forward(self,x):
"""
move turtle x units in turtle's direction
"""
self.code.append("t.forward(%s);"%str(x))
self.position += displacement(x,self.heading)
fd = forward

def backward(self,x):
"""
move turtle x units backward to turtle's direction
"""
self.code.append("t.back(%s);"%str(x))
self.position -= displacement(x,self.heading)
back = backward
bk = backward

def left(self,alpha):
"""
turn turtle alpha degrees to the left

``alpha``  -  number
"""
self.code.append("t.left(%s);"%str(alpha))
self.heading += alpha
self.heading = self.heading%360
lt = left

def right(self,alpha):
"""
turn turtle alpha degrees to the right

``alpha``  -  number
"""
self.code.append("t.right(%s);"%str(alpha))
self.heading -= alpha
self.heading = self.heading%360
rt = right

def setheading(self,alpha):
"""
set turtle's direction (degrees from 0 to 360)

``alpha``  -  number
"""
self.code.append("t.left(%s);"%str(alpha - self.heading))
self.heading = alpha
self.heading = self.heading%360

def goto(self,*args):
"""
move turtle to new position with drawing
"""
if len(args) == 2:
x = args[0]
y = args[1]
elif len(args)==1:
x = args[0][0]
y = args[0][1]
else:
raise ValueError('error message')
self.code.append("t.moveTo(%s);"%str(list((x,y))))
self.position  = vector((x,y))

def setpos(self,*args):
"""
move turtle to new position without drawing

INPUT::

x , y  -  two numbers

or

(x,y)  - pair of numbers

"""
if len(args) == 2:
x = args[0]
y = args[1]
elif len(args)==1:
x = args[0][0]
y = args[0][1]
else:
raise ValueError('error message')
self.code.append("t.setPos(%s);"%str(list((x,y))))
self.position  = vector((x,y))

def penup(self):
"""
further turtle movements without drawing
"""
self.code.append("t.penUp();")
pu = penup

def pendown(self):
"""
further turtle movements with drawing
"""
self.code.append("t.penDown();")
pd = pendown

def home(self):
"""
set turtle to (0,0) and direction to 0 (turtle looking to the right)
"""
self.code.append("t.home();")
self.position  = vector((0,0))
self.heading = 0

def clear(self):
"""
erase all drawings
not changing turtle's position and direction
"""
self.code.append("t.clean();")

def reset(self):
"""
set turtle to (0,0) and direction to 0 (turtle looking to the right)
and erase all drawings
"""
self.code.append("t.clearScreen();")
self.position  = vector((0,0))
self.heading=0

def hideturtle(self):
"""
make turtle invisible
"""
self.code.append("t.hideTurtle();")

def showturtle(self):
"""
make turtle visible
"""
self.code.append("t.showTurtle();")

def color(self,color):
"""
set color of turtle's pen

``color``  -  color string like 'red' or '#ff0000'
"""
self.code.append("t.setPenColor('%s');"%(color))

def pensize(self,size):
"""
set size of turtle's pen

``size``  -  integer
"""
self.code.append("t.setPenSize(%s);"%(str(size)))

def show(self, delay=10):
"""
creates html file containing javascript code
using JSXGraph library
returns link to the file

TODO:
automatically reload html when changed
"""
salvus.html(self.html.replace('_delay_',str(delay)).replace('_code_list_',str(self.code)))
```

### Spirals

```t = Turtle()
t.pensize(2)
t.color('red')
t.penup()
t.goto(0,100)
t.pendown()
t.left(90)
t.hideturtle()
for k in range(1,100):
t.fd(10+k/6)
t.rt(10)
t.color('green')
for k in range(1,100):
t.fd(10+k/6)
t.left(10)
t.show(delay=30)
```

[removed]

### Tree

```t = Turtle()
t.pensize(4)
t.color('pink')
t.hideturtle()

def tree(pos,dx,dy,n):
if n <= 0:
return
x,y = pos
pos_left = (x-dx,y-dy)
pos_right = (x+dx,y-dy)
t.setpos(pos)
t.goto(pos_left)
tree(pos_left,dx/2,4/5*dy,n-1)
t.setpos(pos)
t.goto(pos)
t.goto(pos_right)
tree(pos_right,dx/2,4/5*dy,n-1)

tree((0,200),128,80,5)
t.show()
```

[removed]