import numpy as npy
import pylab as pl


class PointMaker:
    """Class for plotting several identical shapes in different locations."""
    def __init__(self):
        self.linewidth = 2
        self.style = 'k-'


    def plot(self, x, y):
        """Plot a point at x,y."""
        pl.plot([x], [y], self.style, linewidth=self.linewidth)
        

class CircMaker(PointMaker):
    def __init__(self, radius, pts=600):
        PointMaker.__init__(self)
        self.radius = radius
        self.pts = pts

    def plot(self, x, y):
        """Plot a circle at the specified location."""
        X, Y = get_circle(x, y, self.radius, self.pts)
        pl.plot(X, Y, self.style, linewidth=self.linewidth)


def get_circle(x, y, r, pts=600):
    """Get arrays X and Y forming a circle."""
    angles = npy.linspace(0., 2. * npy.pi, num=pts, endpoint=False)
    return (x + npy.cos(angles) * r, y + npy.sin(angles) * r)


def mkgrid(symbolmaker, a, b, imin=-3, imax=3, jmin=-3, jmax=3, cap=3):
    a = npy.asarray(a)
    b = npy.asarray(b)
    for i in range(imin, imax+1):
        for j in range(jmin, jmax+1):
            if abs(i - j) <= cap:
                x, y = a * i + b * j
                symbolmaker.plot(x, y)

if __name__ == '__main__':
    pl.figure(figsize=(12,12))

    p = PointMaker()
    p.style = 'xb'
    c = CircMaker(0.1)
    c.style = 'r-'
    c.linewidth = 3
    
    mkgrid(c, (1.,0.), (-.5, 3.**.5/2.))

    pl.axis((-5., 5., -5., 5.))
    pl.show()

