/* * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package boofcv.app; import org.ddogleg.struct.GrowQueue_I64; import java.io.IOException; import java.io.PrintStream; /** * Outputs an EPS document describing a binary square fiducial that encodes the specified number * * @author Peter Abeles */ public class CreateFiducialSquareBinary extends BaseFiducialSquare { // list of the fiducial ID's it will print GrowQueue_I64 numbers = new GrowQueue_I64(); private int gridWidth = 4; @Override protected void printPatternDefinitions() { out.print(" /sl "+(innerWidth/gridWidth)+" def\n /w0 0 def\n"); // Handle different size grids. for(int i = 1; i < gridWidth; i++) { out.print(" /w" + i + " { w" + (i-1) + " sl add} def\n"); } out.print(" /box {newpath moveto sl 0 rlineto 0 sl rlineto sl neg 0 rlineto closepath fill} def\n"); for( int i = 0; i < numbers.size(); i++ ) { long patternNumber = numbers.get(i); out.print(" /"+getPatternPrintDef(i)+" {\n"+ "% Block corner used to identify orientation\n" + " 0 0 box\n"); final int bitCount = numberOfElements() - 4; for (int j = 0; j < bitCount; j++) { if( (patternNumber & (1L<<j)) != 0 ) { box(out, j); } } out.print("} def\n"); } } @Override protected int totalPatterns() { return numbers.size(); } @Override protected void addPattern(String name) { final long maxValue = (long) Math.pow(2, numberOfElements() - 4) - 1; long value = Long.parseLong(name); if( value < 0 || value > maxValue) throw new IllegalArgumentException("Values must be tween 0 and " +maxValue + ", inclusive"); numbers.add( value ); } @Override protected String getPatternName(int num) { return "grid: "+gridWidth+", value: "+numbers.get(num); } @Override public String defaultOutputFileName() { if( numbers.size() == 1 ) return "Fiducial"+numbers.get(0)+".ps"; else return "BinaryFiducials.ps"; } @Override public String selectDocumentName() { if( numbers.size() == 1 ) return ""+numbers.get(0); else return numbers.get(0)+" and more"; } private void box( PrintStream out , final int bit ) { int transitionBit0 = gridWidth-3; int transitionBit1 = transitionBit0 + gridWidth*(gridWidth-2); int transitionBit2 = transitionBit1 + gridWidth-2; final int adjustedBit; if( bit <= transitionBit0 ) adjustedBit = bit + 1; else if( bit <= transitionBit1 ) adjustedBit = bit + 2; else if( bit <= transitionBit2 ) adjustedBit = bit + 3; else throw new RuntimeException("Bit must be between 0 and " + transitionBit2); int x = adjustedBit % gridWidth; int y = adjustedBit / gridWidth; out.print(" w" + x + " w" + y +" box\n"); } private int numberOfElements() { return gridWidth*gridWidth; } public void setGridSize(int gridWidth) { this.gridWidth = gridWidth; } public static void main(String[] args) throws IOException { CommandParserFiducialSquare parser = new CommandParserFiducialSquare("number"); parser.setIsBinary(true); parser.setExampleNames("284","845"); parser.applicationDescription = "Generates postscript documents for square binary fiducials."; parser.execute(args,new CreateFiducialSquareBinary()); } }