I need to know how to calculate the positions of the QR Code alignment patterns as defined in the table of ISO/IEC 18004:2000 Annex E.
I don't understand how it's calculated. If you take the Version 16, for example, the positions are calculated using {6,26,50,74} and distance between the points are {20,24,24}. Why isn't it {6,28,52,74}, if the distances between the points, {22,24,22}, is distributed more equally?
I would like to know how this can be generated procedurally.
While the specification does provide a table of the alignment, this is a reasonable question (and one I found myself with :-)) - the possibility of generating the positions procedurally has its merits (less typo-prone code, smaller code footprint, knowing pattern/properties of the positions).
I'm happy to report that, yes, a procedure exists (and it is even fairly simple).
The specification itself says most of it:
[The alignment patterns] are spaced as evenly as possible between the Timing Pattern and the opposite side of the symbol, any uneven spacing being accommodated between the timing pattern and the first alignment pattern in the symbol interior.
That is, only the interval between the first and second coordinate may differ from the rest of the intervals. The rest must be equal.
Another important bit is of course that, for the APs to agree with the timing patterns, the intervals must be even.
The remaining tricky bit is just getting the rounding right.
Anyway - here's code printing the alignment position table:
def size_for_version(version):return 17 + 4 * versiondef alignment_coord_list(version):if version == 1:return []divs = 2 + version // 7size = size_for_version(version)total_dist = size - 7 - 6divisor = 2 * (divs - 1)# Step must be even, for alignment patterns to agree with timing patternsstep = (total_dist + divisor // 2 + 1) // divisor * 2 # Get the rounding rightcoords = [6]for i in range(divs - 2, -1, -1): # divs-2 down to 0, inclusivecoords.append(size - 7 - i * step)return coordsfor version in range(1, 40 + 1): # 1 to 40 inclusiveprint("V%d: %s" % (version, alignment_coord_list(version)))