#!/usr/bin/python
#copyright 2007 ben lipkowitz
#you may use and distribute this program under the terms of the
#GNU General Public License v2 or later
#
#draw_encoder.py - output an optical encoder mask suitable for laser printing
#output formats: postscript, svg, pdf
#this could have been written in postscript directly, but then i would have
#had to have turned my brains' insides out.

import cairo
import math
mm = 1/25.4

#set your parameters here
radius = 30*mm
track_width = 10*mm
slots = 100
with_index = True #False for no index mark
bullseye = 6*mm
line_width = 0.05*mm
spacing = 3*mm

page_width = 8.5 #inches
page_height = 11
page_margin = 0.5
#surface = cairo.PSSurface("encoder.ps", page_width*72, page_height*72)
#surface = cairo.SVGSurface("encoder.svg", page_width*72, page_height*72)
surface = cairo.PDFSurface("encoder.pdf", page_width*72, page_height*72)
cr = cairo.Context(surface)
cr.scale(72,72)

def draw_track(ri, ro, n):
	angle = 2 * math.pi / n
	cr.save() #zero our coordinate system
	#draw a wedge - a simple stroke will give a straight line
	for i in range(n):
		start = i * angle
		end = (i + 0.5) * angle
		cr.arc(0, 0, ri, start, end)
		#cairo draws a line connecting one arc to the next
		cr.arc_negative(0, 0, ro, end, start)
		cr.fill()
	cr.restore()

def draw_index(ri, ro, n):
	angle = 2* math.pi / n
	cr.save()
	start = 0
	end = 0.5 * angle
	cr.arc(0, 0, ri, start, end)
	cr.arc_negative(0, 0, ro, end, start)
	cr.fill()
	cr.restore()

def draw_encoder(r, dr, n, index = None, bullseye = None):
	draw_track(r - dr, r, n)
	if index:
		draw_index(r - 2 * dr, r - dr, n)
	if bullseye:
		cr.set_line_width(line_width)
		cr.arc(0, 0, bullseye/2, 0, 2 * math.pi)
		cross_radius = bullseye * 0.4
		cr.move_to(0, cross_radius)
		cr.line_to(0, -cross_radius)
		cr.move_to(cross_radius, 0)
		cr.line_to(-cross_radius, 0)
		cr.stroke()

def draw_page():
	cr.translate(page_margin, page_margin)
	cr.translate(radius, radius)
	
	l = 2 * radius + spacing
	cols = int((page_width - 2 * page_margin + spacing)/ l)
	rows = int((page_height - 2 * page_margin + spacing)/ l)
	for y in range(rows):
		for x in range(cols):
			draw_encoder(radius, track_width, slots, with_index, bullseye )
			cr.translate(l, 0)
		cr.translate(-cols * l, l) #carriage return

draw_page()