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[1]):
origin = (self.plane.pixel_size *
(column - self.plane.resolution[0] / 2.0 + 0.5)
,
self.plane.pixel_size *
(self.row - self.plane.resolution[1] / 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[0]):
yield IterRow(self, row)
return genR()
Briefly stated: 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.
self.resolution = resolutionifresolutionis already available to the whole class (among others)? \$\endgroup\$self.pixel_size. Or am I missing something? \$\endgroup\$