   run: ->
     @running = true
     @go()
+  tp: ( x, y, minDistance, distance ) ->
+    p = @trigPool.pop() || new TrigPair()
+    p.init( x, y, minDistance, distance )
+    p
   # calculate and store the geometric relationship between two things
   trig: ( t, o ) ->
     base = o.x - t.x
     height = o.y - t.y
-    tp = new TrigPair(base, height, @minDistance)
-    t.others[o.id] = tp
-    o.others[t.id] = tp.opposite()
+    ti = t.id
+    oi = o.id
+    t1 = t.others[oi]
+    t2 = o.others[ti]
+    @trigPool.push t1 if t1?
+    @trigPool.push t2 if t2? && !t2.tooFar
+    tp = @tp(base, height, @minDistance)
+    t.others[oi] = tp
+    o.others[ti] = tp.opposite(@)
   # finds the things within a particular distance of a reference thing and within a certain
   # wedge around the direction of the things movement
   # if the thing has a visual angle of 1, or the thing is motionless, all things within the distance are returned


# for easy angle comparison without converting sines and cosines to angles
class TrigPair
  constructor: ( x, y, minDistance, distance ) ->
    if distance?
      sine = @sine = x
      cosine = @cosine = y

  touching: ->
    @universe.near @, @radius, 1
  margins: ->
    m = @marges ||= []
    fi = Math.PI * @visualAngle() / 2
    t1 = @angle - fi
    t1 = @universe.tp( Math.sin(t1), Math.cos(t1) )
    t2 = @angle + fi
    t2 = @universe.tp( Math.sin(t2), Math.cos(t2) )
    m.push t1
    m.push t2
    m

class Stone extends Thing
  constructor: ( location, options = {} ) ->
