/*
* 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 java.io.FileNotFoundException;
import java.io.PrintStream;
/**
* Generates the actual calibration target.
*
* @author Peter Abeles
*/
public class CreateCalibrationTargetGenerator {
PaperSize paper;
int rows,cols;
Unit units;
PrintStream out;
boolean showInfo = true;
double patternWidth;
double patternHeight;
public double UNIT_TO_POINTS;
public static final double CM_TO_POINTS = 72.0/2.54;
public CreateCalibrationTargetGenerator( String documentName , PaperSize paper, int rows , int cols , Unit units ) {
this.paper = paper;
this.rows = rows;
this.cols = cols;
this.units = units;
UNIT_TO_POINTS = units.getUnitToMeter()*100.0*CM_TO_POINTS;
try {
out = new PrintStream(documentName);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
public void chessboard( double squareWidth ) {
double squarePoints = squareWidth*UNIT_TO_POINTS;
patternWidth = cols*squarePoints;
patternHeight = rows*squarePoints;
printHeader("Chessboard "+rows+"x"+cols+", squares "+squareWidth+" "+units.abbreviation);
out.println(
" /w "+squarePoints+" def\n"+
" /ww {w 2 mul} def\n" +
" /patternWidth "+(patternWidth-squarePoints)+" def\n" +
" /patternHeight "+(patternHeight-squarePoints)+" def\n" +
"\n" +
" % ----- Define procedure for drawing a box\n" +
" /box {w 0 rlineto 0 w rlineto -1 w mul 0 rlineto closepath} def\n" +
"\n" +
" % draw all the boxes it can across a single row\n"+
" /rowboxes {ww patternWidth {newpath y moveto box fill} for} def\n" +
"\n" +
" % increments the y variable and draws all the rows\n"+
" 0 ww patternHeight { /y exch def 0 rowboxes } for\n"+
" w ww patternHeight { /y exch def w rowboxes } for");
printTrailer();
}
public void squareGrid( double squareWidth , double spacing ) {
double squarePoints = squareWidth*UNIT_TO_POINTS;
double spacingPoints = spacing*UNIT_TO_POINTS;
patternWidth = cols*squarePoints +(cols-1)*spacingPoints;
patternHeight = rows*squarePoints+(rows-1)*spacingPoints;
printHeader("Square Grid "+rows+"x"+cols+", squares "+squareWidth+", space "+spacing+" "+units.abbreviation);
out.println(
" /w "+squarePoints+" def\n"+
" /s "+spacingPoints+" def\n"+
" /ww {w s add} def\n" +
" /patternWidth "+(patternWidth-squarePoints)+" def\n" +
" /patternHeight "+(patternHeight-squarePoints)+" def\n" +
"\n" +
" % ----- Define procedure for drawing a box\n" +
" /box {w 0 rlineto 0 w rlineto -1 w mul 0 rlineto closepath} def\n" +
"\n" +
" % draw all the boxes it can across a single row\n"+
" /rowboxes {ww patternWidth {newpath y moveto box fill} for} def\n" +
"\n" +
" % increments the y variable and draws all the rows\n"+
" 0 ww patternHeight { /y exch def 0 rowboxes } for\n");
printTrailer();
}
public void binaryGrid( double squareWidth , double spacing ) {
System.out.println("Binary grid not yet supported because the standard isn't fully defined yet");
System.exit(0);
}
public void circleAsymmetric( double diameter , double centerDistance ) {
double diameterPoints = diameter*UNIT_TO_POINTS;
double separationPoints = centerDistance*UNIT_TO_POINTS;
patternWidth = (cols-1)*(separationPoints/2.0) + diameterPoints;
patternHeight = (rows-1)*(separationPoints/2.0) + diameterPoints;
printHeader("Square Grid "+rows+"x"+cols+", diameter "+diameter+", separation "+centerDistance+" "+units.abbreviation);
out.println(
" /w "+separationPoints+" def\n"+
" /s "+(separationPoints/2)+" def\n"+
" /r "+(diameterPoints/2)+" def\n"+
" /patternWidth "+(patternWidth)+" def\n" +
" /patternHeight "+(patternHeight)+" def\n" +
"\n" +
" % ----- Define procedure for drawing a circle\n" +
" /circle {r 0 360 arc closepath} def\n" +
"\n" +
" % draw all the circles it can across a single row\n"+
" /rowcircles {w patternWidth {y r add circle fill} for} def\n" +
"\n" +
" % increments the y variable and draws all the rows\n"+
" 0 w patternHeight { /y exch def r rowcircles } for\n"+
" s w patternHeight { /y exch def r s add rowcircles } for\n");
printTrailer();
}
private void printHeader( String documentTitle ) {
double pageWidth = paper.convertWidth(units)*UNIT_TO_POINTS;
double pageHeight = paper.convertHeight(units)*UNIT_TO_POINTS;
out.println("%!PS-Adobe-3.0\n" +
"%%Creator: BoofCV\n" +
"%%DocumentMedia: Plain "+pageWidth+" "+pageHeight+" 80 white ( )\n" +
"%%Title: "+documentTitle+" on "+paper+"\n" +
"%%DocumentData: Clean7Bit\n" +
"%%LanguageLevel: 2\n" +
"%%BeginSetup\n" +
" << /PageSize ["+pageWidth+" "+pageHeight+"] /Orientation 0 >> setpagedevice\n" +
"%%EndSetup\n" +
"%%EndComments\n" +
"%%BeginProlog\n" +
"%%EndProlog\n" +
"%%Pages: 1\n");
if( showInfo ) {
double offX = Math.min(CM_TO_POINTS,(pageWidth-patternWidth)/4);
double offY = Math.min(CM_TO_POINTS,(pageHeight-patternHeight)/4);
out.print(" /Times-Roman findfont\n 7 scalefont setfont "+offX+" "+offY +
String.format(" moveto (BoofCV: %s) show\n\n",documentTitle));
}
out.println("% Center the pattern on the page");
out.println(" /offX "+(pageWidth-patternWidth)/2.0+" def");
out.println(" /offY "+(pageHeight-patternHeight)/2.0+" def");
out.println(" offX offY translate");
out.println();
out.println(" newpath");
out.println("% Render the pattern");
}
private void printTrailer() {
out.println(" showpage\n" +
"%%Trailer\n" +
"%%EOF\n");
out.close();
}
public void setShowInfo(boolean showInfo) {
this.showInfo = showInfo;
}
}