title: Iterate over 2d array in an expanding circular spiral
body: <p>Given an <code>n</code> by <code>n</code> matrix <code>M</code>, at row <code>i</code> and column <code>j</code>, I'd like to iterate over all the neighboring values in a circular spiral. </p>
  
  <p>The point of doing this is to test some function, <code>f</code>, which depends on M, to find the radius away from <code>(i, j)</code> in which <code>f</code> returns <code>True</code>. So, <code>f</code> looks like this:</p>
  
  <pre><code>def f(x, y):
      """do stuff with x and y, and return a bool"""
  </code></pre>
  
  <p>and would be called like this:</p>
  
  <pre><code>R = numpy.zeros(M.shape, dtype=numpy.int)
  # for (i, j) in M
  for (radius, (cx, cy)) in circle_around(i, j):
      if not f(M[i][j], M[cx][cy]):
         R[cx][cy] = radius - 1
         break
  </code></pre>
  
  <p>Where <code>circle_around</code> is the function that returns (an iterator to) indices in a circular spiral. So for every point in <code>M</code>, this code would compute and store the radius from that point in which <code>f</code> returns <code>True</code>. </p>
  
  <p>If there's a more efficient way of computing <code>R</code>, I'd be open to that, too.</p>
  
  <hr>
  
  <h1><strong>Update:</strong></h1>
  
  <p>Thanks to everyone who submitted answers. I've written a short function to plot the output from your <code>circle_around</code> iterators, to show what they do. If you update your answer or post a new one, you can use this code to validate your solution.</p>
  
  <pre><code>from matplotlib import pyplot as plt
  def plot(g, name):
      plt.axis([-10, 10, -10, 10])
      ax = plt.gca()
      ax.yaxis.grid(color='gray')
      ax.xaxis.grid(color='gray')
  
      X, Y = [], []
      for i in xrange(100):
          (r, (x, y)) = g.next()
          X.append(x)
          Y.append(y)
          print "%d: radius %d" % (i, r)
  
      plt.plot(X, Y, 'r-', linewidth=2.0)
      plt.title(name)
      plt.savefig(name + ".png")
  </code></pre>
  
  <p>Here are the results:
  <code>plot(circle_around(0, 0), "F.J")</code>:
  <img src="https://i.stack.imgur.com/EUKdO.png" alt="circle_around by F.J"></p>
  
  <p><code>plot(circle_around(0, 0, 10), "WolframH")</code>:
  <img src="https://i.stack.imgur.com/5Nlfi.png" alt="circle_around by WolframH"></p>
  
  <p>I've coded up Magnesium's suggestion as follows:</p>
  
  <pre><code>def circle_around_magnesium(x, y):
      import math
      theta = 0
      dtheta = math.pi / 32.0
      a, b = (0, 1) # are there better params to use here?
      spiral = lambda theta : a + b*theta
      lastX, lastY = (x, y)
      while True:
          r = spiral(theta)
          X = r * math.cos(theta)
          Y = r * math.sin(theta)
          if round(X) != lastX or round(Y) != lastY:
              lastX, lastY = round(X), round(Y)
              yield (r, (lastX, lastY))
          theta += dtheta
  </code></pre>
  
  <p><code>plot(circle_around(0, 0, 10), "magnesium")</code>:
  <img src="https://i.stack.imgur.com/meVfW.png" alt="circle_around by Magnesium"></p>
  
  <p>As you can see, none of the results that satisfy the interface I'm looking for have produced a circular spiral that covers all of the indices around 0, 0. F.J's is the closest, although WolframH's hits the right points, just not in spiral order.</p>