84 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * Alignment pattern are fixed reference pattern in defined positions
 | |
|  * in a matrix symbology, which enables the decode software to re-synchronise
 | |
|  * the coordinate mapping of the image modules in the event of moderate amounts
 | |
|  * of distortion of the image.
 | |
|  *
 | |
|  * Alignment patterns are present only in QR Code symbols of version 2 or larger
 | |
|  * and their number depends on the symbol version.
 | |
|  */
 | |
| 
 | |
| const getSymbolSize = require('./utils').getSymbolSize
 | |
| 
 | |
| /**
 | |
|  * Calculate the row/column coordinates of the center module of each alignment pattern
 | |
|  * for the specified QR Code version.
 | |
|  *
 | |
|  * The alignment patterns are positioned symmetrically on either side of the diagonal
 | |
|  * running from the top left corner of the symbol to the bottom right corner.
 | |
|  *
 | |
|  * Since positions are simmetrical only half of the coordinates are returned.
 | |
|  * Each item of the array will represent in turn the x and y coordinate.
 | |
|  * @see {@link getPositions}
 | |
|  *
 | |
|  * @param  {Number} version QR Code version
 | |
|  * @return {Array}          Array of coordinate
 | |
|  */
 | |
| exports.getRowColCoords = function getRowColCoords (version) {
 | |
|   if (version === 1) return []
 | |
| 
 | |
|   const posCount = Math.floor(version / 7) + 2
 | |
|   const size = getSymbolSize(version)
 | |
|   const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2
 | |
|   const positions = [size - 7] // Last coord is always (size - 7)
 | |
| 
 | |
|   for (let i = 1; i < posCount - 1; i++) {
 | |
|     positions[i] = positions[i - 1] - intervals
 | |
|   }
 | |
| 
 | |
|   positions.push(6) // First coord is always 6
 | |
| 
 | |
|   return positions.reverse()
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Returns an array containing the positions of each alignment pattern.
 | |
|  * Each array's element represent the center point of the pattern as (x, y) coordinates
 | |
|  *
 | |
|  * Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}
 | |
|  * and filtering out the items that overlaps with finder pattern
 | |
|  *
 | |
|  * @example
 | |
|  * For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.
 | |
|  * The alignment patterns, therefore, are to be centered on (row, column)
 | |
|  * positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).
 | |
|  * Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns
 | |
|  * and are not therefore used for alignment patterns.
 | |
|  *
 | |
|  * let pos = getPositions(7)
 | |
|  * // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]
 | |
|  *
 | |
|  * @param  {Number} version QR Code version
 | |
|  * @return {Array}          Array of coordinates
 | |
|  */
 | |
| exports.getPositions = function getPositions (version) {
 | |
|   const coords = []
 | |
|   const pos = exports.getRowColCoords(version)
 | |
|   const posLength = pos.length
 | |
| 
 | |
|   for (let i = 0; i < posLength; i++) {
 | |
|     for (let j = 0; j < posLength; j++) {
 | |
|       // Skip if position is occupied by finder patterns
 | |
|       if ((i === 0 && j === 0) || // top-left
 | |
|           (i === 0 && j === posLength - 1) || // bottom-left
 | |
|           (i === posLength - 1 && j === 0)) { // top-right
 | |
|         continue
 | |
|       }
 | |
| 
 | |
|       coords.push([pos[i], pos[j]])
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return coords
 | |
| }
 | 
