diff --git a/README.md b/README.md index 54ba0e3..fc620d8 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,66 @@ usage: required default: [none] ``` -apologies for the `radius`, `circle-radius`, and `polish` parameters. -they should be properly described or removed. +the `radius` and `polish` parameters should probably be +properly described or removed. + +### neighborhood + +offsets are sorted in ascending distance from the center (the 0,0 point). + +the order of equal distances is undefined. +this probably doesn't matter matter, +considering the algorithm handles non-circular +neighborhoods just fine — more on that later. + +consider the first 29 offsets, +which is the default number of neighbors: + +* distance of 0: + `{ 0, 0}` +* distance of 1: + `{ 0,-1}, {+1, 0}, {-1, 0}, { 0,+1}` +* distance of sqrt(2): + `{-1,-1}, {-1,+1}, {+1,+1}, {+1,-1}` +* distance of 2: + `{+2, 0}, {-2, 0}, { 0,+2}, { 0,-2}` +* distance of sqrt(5): + `{-1,-2}, {-2,+1}, {-2,-1}, {+1,+2}, {-1,+2}, {+2,-1}, {+1,-2}, {+2,+1}` +* distance of sqrt(8): + `{+2,-2}, {-2,-2}, {-2,+2}, {+2,+2}` +* distance of 3: + `{+3, 0}, { 0,-3}, {-3, 0}, { 0,+3}` + +the default neighborhood of 29 yields a (pixelated) circle, +as in this crude ascii art: +``` + X + XXXXX + XXXXX +XXXXXXX + XXXXX + XXXXX + X +``` + +resynth provides a portion of [the associated integer sequence A057961,][A057961] +allowing the neighborhood to be specified as a radius-like size, +with guaranteed symmetry about the X and Y axes. +this is the `-R` flag, and the first few values are visualized here: +``` + -R1 -R2 -R3 -R4 -R5 -R6 -R7 + + X + X XXX XXXXX XXXXX + X XXX XXX XXXXX XXXXX XXXXX + X XXX XXX XXXXX XXXXX XXXXX XXXXXXX + X XXX XXX XXXXX XXXXX XXXXX + X XXX XXXXX XXXXX + X + equivalent to + -N1 -N5 -N9 -N13 -N21 -N25 -N29 +``` +[A057961]: http://oeis.org/A057961 ## notes diff --git a/resynth.c b/resynth.c index a9bfb23..f9a4e0f 100644 --- a/resynth.c +++ b/resynth.c @@ -209,13 +209,15 @@ static void make_offset_list(Resynth_state *s) { } } - // TODO: describe how/why this is sorted + // sort offsets in ascending distance from the center zero-point. + // the order of equal distances is undefined. (it doesn't seem to matter) + // (for a more detailed description of what's going on, refer to the README) qsort(s->sorted_offsets, sb_count(s->sorted_offsets), sizeof(Coord), coord_compare); } INLINE void try_point(Resynth_state *s, const Coord point) { - // consider a pixel and its neighbors as candidates for the best-fit. + // consider a candidate pixel for the best-fit by considering its neighbors. int sum = 0; for (int i = 0; i < s->n_neighbors; i++) { @@ -299,6 +301,7 @@ static void run(Resynth_state *s, Parameters parameters) { for (int p = 0; p < parameters.polish + 1; p++) { for (int i = 0; i < data_area; i++) { // shuffle in-place + // (we could use a better random function here) int j = rand() % data_area; Coord temp = s->data_points[i]; s->data_points[i] = s->data_points[j]; @@ -435,7 +438,7 @@ int main(int argc, char *argv[]) { Parameters parameters = {0}; parameters.v_tile = true; parameters.h_tile = true; - // blah = our default; // original resynthizer default + // blah = our default; // original resynthesizer default parameters.magic = 192; // 192 (3/4) parameters.autism = 32. / 256.; // 30. / 256. parameters.neighbors = 29; // 30