/* Choosing sampling points and rays. */ /* Last edited on 2024-12-06 14:12:02 by stolfi */ #ifndef multifok_sampling_H #define multifok_sampling_H #include #include #include #include #include #include #include #include #include typedef struct multifok_sampling_t { uint32_t NS; /* Number os sub-sampling points per pixel. */ r2_t *uSmp; /* Positions of sub-sampling points rel to pixel center. */ double *wSmp; /* Weights of sub-sampling points in pixel averages. */ uint32_t NR; /* Number of ray tilts available. */ r2_t *tRay; /* Ray tilts. */ double *wRay; /* Ray weights for computing the sub-sampling average. */ } multifok_sampling_t; /* Features of the simulated camera lens, defined by a table of pixel susbample position {usmp[0..NS-1]} and associated weight {wSmp[0..NS-1]}; and a table of relative ray tilts {tRay[0..NR-1]} and associated weights {wRay[0..NR-1]}. The count {NR} must be a multiple of {NS}, and it is implied that {KR=NR/NS} rays will be cast for each sub-sampling point. */ multifok_sampling_t *multifok_sampling_choose(uint32_t HS, uint32_t KR_min, bool_t verbose); /* Returns a {} record with sampling parameters for ray traciing. Pixel sub-sampling point positions and weights: Chooses a number {NS} pixel sub-sampling points, their deviations {uSmp[0..NS-1} from the pixel's center, and their weights {wSmp[0..NS-1]}. Allocates the arrays and returns the choices in {*NS_P}, {*uSmp_P}, {*wSmp_P}. The weights {wSmp[0..NS-1]} will be all positive. For any {HS}, the first sample {uSmp[0]} will be {(0,0)} and {wSmp[0]} will be the largest weight. Any other rays will have {uSmp} distinct from {(0,0)}. Both arrays will be sorted so that {|uSmp[ks]|} increases with {ks}. If {HS} is zero, {NS} will be 1, so there will be just the {(0,0)} point. Otherwise the number of sampling points will be greater than 1, about {(2*HS+1)^2}. Ray tilts and weights: Chooses a number {NR} of rays, their relative deviations from the vertical {tRay[0..NR-1}, and their weights {wRay[0..NR-1]}. Allocates the arrays and returns the choices in {*NR_P}, {*tRay_P}, {*wRay_P}. If {KR=0}, the procedure will generate a single ray direction ({NR = 1}) irrespective of {NS}. If {KR>=1}, the number of rays {NR} will be {KR*NS} rounded up to the smallest odd square that is a multiple of {NS}. The weights {wRay[0..NR-1]} will be positive. For any {NR}, the first ray will be strictly vertical, with {tRay[0] = (0,0)} and {wRay[0]} maximum. Any other rays will have {tRay} distinct from {(0,0)}. Both arrays will be sorted so that {|tRay[ks]|} increases with {ks}. If {NR} is 1, there will be just that vertical ray. Otherwise the RMS radius of the points {tRay}, (namely the square root of the weighted average of {|tRay[ir]|^2} with the {wRay} weights, including {tRay[0]) will be 1.0. */ void multifok_sampling_free(multifok_sampling_t *samp); /* Reclaims the storage used by {samp}, including internal tables. */ #endif