92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
import math
|
|
import sys
|
|
|
|
class SvgTurtle():
|
|
def __init__(self, homex=0, homey=0):
|
|
self.homex = homex
|
|
self.homey = homey
|
|
self.cvtangle = math.tau/360
|
|
self.reset()
|
|
|
|
def penup(self):
|
|
self.pen = False
|
|
|
|
def pendown(self):
|
|
self.pen = True
|
|
|
|
def forward(self, distance):
|
|
if self.pen and (self.path == ''):
|
|
self.path = "M %.2f,%.2f" % (self.x,self.y)
|
|
dx = distance*math.cos(self.heading)
|
|
dy = distance*math.sin(self.heading)
|
|
self.x += dx
|
|
self.y += dy
|
|
if self.pen:
|
|
if abs(dy) < .01:
|
|
self.path += " h %.2f" % dx
|
|
elif abs(dx) < .01:
|
|
self.path += " v %.2f" % dy
|
|
else:
|
|
self.path += " l %.2f,%.2f" % (dx, dy)
|
|
elif self.path != '':
|
|
self.path += " m %.2f, %.2f" % (dx, dy)
|
|
|
|
def back(self, distance):
|
|
self.forward(-distance)
|
|
|
|
def left(self, angle):
|
|
self.right(-angle)
|
|
|
|
def right(self, angle):
|
|
self.heading = (self.heading + angle*self.cvtangle) % math.tau
|
|
|
|
def circle(self, radius, extent=360, steps=None):
|
|
if steps:
|
|
w = 1.0*extent/steps
|
|
w2 = 0.5*w
|
|
l = 2.0*radius*math.sin(w2*math.pi/180.0)
|
|
if radius < 0:
|
|
l, w, w2 = -l, -w, -w2
|
|
self.left(w2)
|
|
for i in range(steps):
|
|
self.forward(l)
|
|
self.left(w)
|
|
self.right(w2)
|
|
else:
|
|
if extent>355:
|
|
self.circle(radius, 355)
|
|
extent -= 355
|
|
ra = self.cvtangle*(extent if radius < 0 else -extent)
|
|
cx = self.x+radius*math.cos(self.heading-.5*math.pi)
|
|
cy = self.y+radius*math.sin(self.heading-.5*math.pi)
|
|
th = self.heading+.5*math.pi+ra
|
|
dx = cx+radius*math.cos(th)-self.x
|
|
dy = cy+radius*math.sin(th)-self.y
|
|
lg = 1 if extent >= 180 else 0
|
|
sw = 0 if radius > 0 else 1
|
|
if self.pen:
|
|
if self.path == '':
|
|
self.path = "M %.2f,%.2f" % (self.x,self.y)
|
|
self.path += " a %.2f %.2f %.2f %d %d %.2f %.2f" % (radius, radius, extent, lg, sw, dx, dy)
|
|
elif self.path != '':
|
|
self.path += " m %.2f, %.2f" % (dx, dy)
|
|
self.x += dx
|
|
self.y += dy
|
|
self.heading = (self.heading + ra) % math.tau
|
|
|
|
|
|
def to_s(self):
|
|
return self.path
|
|
|
|
def home(self):
|
|
self.x = self.homex
|
|
self.y = self.homey
|
|
self.heading = 0
|
|
if self.path != '':
|
|
self.path += " M %.2f, %.2f" % (self.x, self.y)
|
|
|
|
def reset(self):
|
|
self.path = ''
|
|
self.pen = True
|
|
self.home()
|