/* * GraphPaper: PDF graph paper generator. * * Draws multi-weight grid lines, borders and cross grid, * using metric or imperial measures. * * Copyright (c) Daniel Jones 2010. * * * This program can be freely distributed and modified under the * terms of the GNU General Public License version 2. * * *--------------------------------------------------------------*/ import processing.core.*; import processing.pdf.*; /*----------------------------------------------------------------- * Config: grid lines *----------------------------------------------------------------*/ boolean drawLines = true; float majorLinesPerUnit = 0.5; float minorLinesPerUnit = 2; float microLinesPerUnit = 10; int majorLineColor = color(255, 0, 0); int minorLineColor = color(128); int microLineColor = color(192); float majorLineWeight = 1.f; float minorLineWeight = 0.8f; float microLineWeight = 0.3f; /*----------------------------------------------------------------- * Config: borders *----------------------------------------------------------------*/ boolean drawBorders = true; int outerLineColor = color(0); float outerLineWeight = 2.0f; /*----------------------------------------------------------------- * Config: dots or pluses *----------------------------------------------------------------*/ boolean drawPluses = false; float majorPlusesPerUnit = 0.5f; float minorPlusesPerUnit = 2.0f; int majorPlusColor = color(0); int minorPlusColor = color(128); float majorPlusWeight = 2.0f; float minorPlusWeight = 1.0f; float majorPlusLength = 0.2f; float minorPlusLength = 0.1f; /*----------------------------------------------------------------- * Config: margins, pages, units *----------------------------------------------------------------*/ float marginUnits = 2.5f; int pages = 2; boolean useImperial = false; /*----------------------------------------------------------------- * Config: page size (mapped to pixels at 300 DPI) *----------------------------------------------------------------*/ int [] PAPER_SIZE_A4 = new int[] { 2480, 3508 }; // int'l A4 int [] PAPER_SIZE_A3 = new int[] { 3508, 4961 }; // int'l A3 int [] PAPER_SIZE_LETTER = new int[] { 2550, 3300 }; // US letter (8.5 x 11) int [] PAPER_SIZE_TABLOID = new int[] { 3300, 5100 }; // US tabloid (11 x 17) int [] paperSize = PAPER_SIZE_A4; // change me /*----------------------------------------------------------------- * Misc fields *----------------------------------------------------------------*/ float oneCentimetre = 118.0f; float oneInch = 300.0f; float oneUnit = oneCentimetre; static Hashtable paperSizes; void setup() { size(paperSize[0], paperSize[1], PDF, "sheet.pdf"); this.setImperial(useImperial); } public void draw() { background(255); noFill(); drawGraph(); PGraphicsPDF pdf = (PGraphicsPDF) g; if (frameCount == pages) exit(); else pdf.nextPage(); } public void drawGraph() { /*----------------------------------------------------------------- * Calculate global measurements, truncating to nearest integer * number of major lines. *----------------------------------------------------------------*/ PVector totalAvailableSize = new PVector ( (float) Math.floor(width - (2 * marginUnits * oneUnit)), (float) Math.floor(height - (2 * marginUnits * oneUnit)) ); float majorLineWidth = oneUnit / majorLinesPerUnit; float minorLineWidth = oneUnit / minorLinesPerUnit; float microLineWidth = oneUnit / microLinesPerUnit; PVector totalMajorLineCount = new PVector ( (float) Math.floor(totalAvailableSize.x / majorLineWidth), (float) Math.floor(totalAvailableSize.y / majorLineWidth) ); PVector totalMinorLineCount = new PVector ( totalMajorLineCount.x * (minorLinesPerUnit / majorLinesPerUnit), totalMajorLineCount.y * (minorLinesPerUnit / majorLinesPerUnit) ); PVector totalMicroLineCount = new PVector ( totalMajorLineCount.x * (microLinesPerUnit / majorLinesPerUnit), totalMajorLineCount.y * (microLinesPerUnit / majorLinesPerUnit) ); PVector totalGraphSize = new PVector ( (float) totalMajorLineCount.x * majorLineWidth, (float) totalMajorLineCount.y * majorLineWidth ); translate(marginUnits * oneUnit, marginUnits * oneUnit); /*----------------------------------------------------------------- * Draw: lines *----------------------------------------------------------------*/ if (drawLines) { stroke(microLineColor); strokeWeight(microLineWeight); for (int x = 0; x <= totalMicroLineCount.x; x++) line(x * microLineWidth, 0, x * microLineWidth, totalGraphSize.y); for (int y = 0; y <= totalMicroLineCount.y; y++) line(0, y * microLineWidth, totalGraphSize.x, y * microLineWidth); stroke(minorLineColor); strokeWeight(minorLineWeight); for (int x = 0; x <= totalMinorLineCount.x; x++) line(x * minorLineWidth, 0, x * minorLineWidth, totalGraphSize.y); for (int y = 0; y <= totalMinorLineCount.y; y++) line(0, y * minorLineWidth, totalGraphSize.x, y * minorLineWidth); stroke(majorLineColor); strokeWeight(majorLineWeight); for (int x = 0; x <= totalMajorLineCount.x; x++) line(x * majorLineWidth, 0, x * majorLineWidth, totalGraphSize.y); for (int y = 0; y <= totalMajorLineCount.y; y++) line(0, y * majorLineWidth, totalGraphSize.x, y * majorLineWidth); } /*----------------------------------------------------------------- * Draw: outer border *----------------------------------------------------------------*/ if (drawBorders) { stroke(outerLineColor); strokeWeight(outerLineWeight); rect(0, 0, totalGraphSize.x, totalGraphSize.y); } /*----------------------------------------------------------------- * Draw: pluses *----------------------------------------------------------------*/ if (drawPluses) { float majorPlusWidth = oneUnit / majorPlusesPerUnit; float minorPlusWidth = oneUnit / minorPlusesPerUnit; PVector totalMajorPlusCount = new PVector ( (float) Math.floor(totalAvailableSize.x / majorPlusWidth), (float) Math.floor(totalAvailableSize.y / majorPlusWidth) ); PVector totalMinorPlusCount = new PVector ( (float) totalMajorPlusCount.x * (minorPlusesPerUnit / majorPlusesPerUnit), (float) totalMajorPlusCount.y * (minorPlusesPerUnit / majorPlusesPerUnit) ); stroke(minorPlusColor); strokeWeight(minorPlusWeight); float halfMinorPlus = minorPlusLength * oneUnit * 0.5f; float halfMajorPlus = majorPlusLength * oneUnit * 0.5f; for (int x = 1; x < totalMinorPlusCount.x; x++) for (int y = 1; y < totalMinorPlusCount.y; y++) { line(x * minorPlusWidth - halfMinorPlus, y * minorPlusWidth, x * minorPlusWidth + halfMinorPlus, y * minorPlusWidth); line(x * minorPlusWidth, y * minorPlusWidth - halfMinorPlus, x * minorPlusWidth, y * minorPlusWidth + halfMinorPlus); } stroke(majorPlusColor); strokeWeight(majorPlusWeight); for (int x = 1; x < totalMajorPlusCount.x; x++) for (int y = 1; y < totalMajorPlusCount.y; y++) { line(x * majorPlusWidth - halfMajorPlus, y * majorPlusWidth, x * majorPlusWidth + halfMajorPlus, y * majorPlusWidth); line(x * majorPlusWidth, y * majorPlusWidth - halfMajorPlus, x * majorPlusWidth, y * majorPlusWidth + halfMajorPlus); } } } public void setImperial(boolean value) { useImperial = value; oneUnit = useImperial ? oneInch : oneCentimetre; }