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)))