There isn't a particular reason why the filter isn't passed into the *float sample( float, float )* method. It can be. If we do this then we have solved your second point... 

As for the Filter::construct() method, I have been thinking about this one myself and am very much open to suggestions. As filters are essentially 1D kernels which can be convolved in 2D against an image, the construct() method was intended to be a way of hiding the process of discretization. By hiding the code that offsets the center of the filter and just returning the location of the first discrete array index that it should be convolved against, the construct() method makes using the filter class much more simple. One of the motivations for this is that the Filters can be used in several ways apart from within the Sampler. For example, they can act as Sampling Filters, Reconstruction Filters and Convolution Filters (such as a Gaussian blur). In all these cases the Filter is convolved against the image but in some cases the center of the filter needs offsetting every time a set of pixels is convolved with it. An example would be when we take multiple random sub-samples of an image where we always have to adjust the center of the weights depending on the sub-pixel location of the sample. But, if we were to do multiple sub-samples which all have the same sub-pixel offset - such as with a translation or a Gaussian blur - the same weights can be used for all samples. In these cases we only need to call construct() once and then simply convolve the resulting weights with the whole image. 

I think we could change the interface so that calls to weight() are made directly instead of calling construct(), forcing the different implementations to cache the values if they need to. However, I don't think that it should be the responsibility of the code that uses the filter to handle it's discretization as that would break the filters encapsulation concept and require knowledge of it's internal workings outside of the class; It should just be a dumb kernel that you build and convolve with. I have some ideas but let's discuss them in person as in retrospect, this is turning out to be quite long winded.