getSize(); echo "Testing Data Placement for Version 1 (21x21)\n\n"; // Laut ISO/IEC 18004: Data placement beginnt bottom-right, geht nach oben // Dann zwei Spalten nach links, geht nach unten, usw. // Simulate data placement to verify order function isOccupied(int $row, int $col, int $size): bool { // Finder patterns + separators if ( ($row <= 8 && $col <= 8) || ($row <= 7 && $col >= $size - 8) || ($row >= $size - 8 && $col <= 7) ) { return true; } // Timing patterns if ($row === 6 || $col === 6) return true; // Format information if ($row === 8 || $col === 8) return true; // Dark module if ($row === 13 && $col === 8) return true; return false; } echo "First 20 data positions (should be in zigzag pattern):\n"; $positions = []; $count = 0; for ($col = $size - 1; $col >= 1 && $count < 20; $col -= 2) { if ($col === 6) $col--; $upward = ((int)(($size - 1 - $col) / 2) % 2) === 0; for ($i = 0; $i < $size && $count < 20; $i++) { $row = $upward ? ($size - 1 - $i) : $i; for ($c = 0; $c < 2 && $count < 20; $c++) { $currentCol = $col - $c; if (isOccupied($row, $currentCol, $size)) continue; $count++; $positions[] = "({$row},{$currentCol})"; if ($count <= 20) { echo sprintf("Position %2d: (%2d,%2d)\n", $count, $row, $currentCol); } } } } echo "\n=== Expected vs Actual First Bits ===\n"; // Expected data (from encoding): // Mode: 0100 (Byte) // Count: 00001011 (11 characters) // First char 'H': 01001000 $expectedBits = "0100" . "00001011" . "01001000"; echo "Expected first 20 bits: {$expectedBits}\n"; // Get actual bits from matrix function applyMask(int $row, int $col, int $mask): bool { return match ($mask) { 2 => $col % 3 === 0, // Current mask default => false }; } $actualBits = ''; $count = 0; for ($col = $size - 1; $col >= 1 && $count < 20; $col -= 2) { if ($col === 6) $col--; $upward = ((int)(($size - 1 - $col) / 2) % 2) === 0; for ($i = 0; $i < $size && $count < 20; $i++) { $row = $upward ? ($size - 1 - $i) : $i; for ($c = 0; $c < 2 && $count < 20; $c++) { $currentCol = $col - $c; if (isOccupied($row, $currentCol, $size)) continue; $module = $matrix->getModuleAt($row, $currentCol); $bit = $module->isDark() ? 1 : 0; // Unmask if (applyMask($row, $currentCol, 2)) { $bit = $bit === 1 ? 0 : 1; } $actualBits .= $bit; $count++; } } } echo "Actual first 20 bits: {$actualBits}\n\n"; // Compare $matches = 0; for ($i = 0; $i < 20; $i++) { if ($expectedBits[$i] === $actualBits[$i]) { $matches++; } else { echo "❌ Bit {$i}: expected {$expectedBits[$i]}, got {$actualBits[$i]}\n"; } } echo "\nMatch: {$matches}/20 bits\n"; if ($matches === 20) { echo "✅ Data placement order is CORRECT!\n"; } else { echo "❌ Data placement order is WRONG!\n"; } // Visualisiere die ersten Data-Positionen echo "\n=== Visual Data Placement Map ===\n"; echo "Legend: # = Function Pattern, D = Data (numbered)\n\n"; $dataMap = []; for ($r = 0; $r < $size; $r++) { $dataMap[$r] = []; for ($c = 0; $c < $size; $c++) { $dataMap[$r][$c] = isOccupied($r, $c, $size) ? '#' : ' '; } } // Mark first 20 data positions $count = 0; for ($col = $size - 1; $col >= 1 && $count < 20; $col -= 2) { if ($col === 6) $col--; $upward = ((int)(($size - 1 - $col) / 2) % 2) === 0; for ($i = 0; $i < $size && $count < 20; $i++) { $row = $upward ? ($size - 1 - $i) : $i; for ($c = 0; $c < 2 && $count < 20; $c++) { $currentCol = $col - $c; if (isOccupied($row, $currentCol, $size)) continue; $count++; $dataMap[$row][$currentCol] = (string)($count % 10); } } } // Print map echo " "; for ($c = 0; $c < $size; $c++) { echo str_pad((string)$c, 2, ' ', STR_PAD_LEFT); } echo "\n"; for ($r = 0; $r < $size; $r++) { echo str_pad((string)$r, 2, ' ', STR_PAD_LEFT) . ' '; for ($c = 0; $c < $size; $c++) { echo $dataMap[$r][$c] . ' '; } echo "\n"; }