I am writing a simple raytracer just for fun. I want to iterate over rows, and each row must be an iterator over columns. A strategy I produced is the following:
class ViewPlane(object): def __init__(self, resolution, pixel_size, gamma): self.resolution = resolution self.pixel_size = pixel_size self.gamma = gamma def __iter__(self): def genR(): class IterRow(object): def __init__(self, plane, row): self.plane = plane self.row = row def __iter__(self): def genC(): for column in xrange(self.plane.resolution): origin = (self.plane.pixel_size * (column - self.plane.resolution / 2.0 + 0.5) , self.plane.pixel_size * (self.row - self.plane.resolution / 2.0 + 0.5) , 100.0 ) yield ( Ray(origin = origin, direction = (0.0,0.0,-1.0)), (self.row,column) ) return return genC() def __str__(self): return "Row iterator on row "+str(self.row) for row in xrange(self.resolution): yield IterRow(self, row) return genR()
ViewPlane contains the pixel plane. This class implements
__iter__ which defines and returns a generator function. This generator function yields instances of an internal class
IterRow, which in turn has a
__iter__ method that returns a generator iterating over the columns.
I personally think that it's difficult to understand, so I was wondering if there's a cleaner strategy to achieve the same result.