I did lotsa hack & slash to your code. Even to
Grid2D class!
I've changed
PVector to a customized
IntVector I did. Which just has 2 int fields ->
x,
y.
This way, all coordinates are assured to be always whole values.
I can't tell much whether it made any differences. But check it out:
Pattini.pde
/**
* Pattini (v2.23)
* by Arranger (2013/Jul)
* mod GoToLoop
*
* http://forum.processing.org/topic/rendering-imperfections-drawing-lines
* http://www.mediafire.com/?rptt5h2ctrgg2et
*/
import processing.pdf.*;
final static color BLACK = 0, WHITE = -1;
final static color GOLD = #FFD300, ORCHID = #EE2B7A;
final static int TRIANGS = 25, SMOOTHNESS = 2 << 4;
final Grid2D grid = new Grid2D(
new PVector(-100, -30), TRIANGS, TRIANGS, 40, 30);
final color[][] blackTriangles = new color[TRIANGS][TRIANGS];
final color[][] whiteTriangles = new color[TRIANGS][TRIANGS];
//final static String GFX = JAVA2D;
final static String GFX = P2D;
PGraphics pg;
boolean toDrawGrid;
void setup() {
size(800, 600, GFX);
noLoop();
mousePressed();
pg = createGraphics(width, height, GFX);
pg.beginDraw();
pg.background(BLACK);
pg.smooth(SMOOTHNESS);
pg.endDraw();
}
void draw() {
drawTriangles(pg, grid, blackTriangles, whiteTriangles);
if (toDrawGrid) grid.display(pg, GOLD);
image(pg, 0, 0);
}
void mousePressed() {
redraw();
if (mouseButton == CENTER) {
toDrawGrid = !toDrawGrid;
return;
}
initTriangleColor(blackTriangles, BLACK);
initTriangleColor(whiteTriangles, WHITE);
mutateTriangleColor(blackTriangles, WHITE, 25);
mutateTriangleColor(whiteTriangles, BLACK, 25);
mutateTriangleColor(whiteTriangles, GOLD, 30);
mutateTriangleColor(whiteTriangles, ORCHID, 30);
}
void keyPressed() {
if (keyCode == 'S')
selectOutput("Select a file to write to:", "exportToPDF");
else {
mouseButton = LEFT;
mousePressed();
}
}
void exportToPDF(File selection) {
if (selection == null) {
println("Window was closed or the user hit cancel.");
return;
}
String path = selection.getAbsolutePath();
if (!path.toLowerCase().endsWith(".pdf")) path += ".pdf";
final PGraphics pdf = createGraphics(width, height, PDF, path);
pdf.beginDraw();
pdf.background(WHITE);
pdf.smooth(SMOOTHNESS);
pdf.endDraw();
drawTriangles(pdf, grid, blackTriangles, whiteTriangles);
if (toDrawGrid) grid.display(pdf, GOLD);
pdf.dispose();
}
Functions.pde:
void initTriangleColor(color[][] triangles, color colour) {
final int rows = triangles.length;
final int cols = triangles[0].length;
for (int i = 0; i != rows; ++i) for (int j = 0; j != cols; ++j)
triangles[i][j] = colour;
}
void mutateTriangleColor(color[][] triangles, color colour, int prob) {
final int rows = triangles.length;
final int cols = triangles[0].length;
for (int i = 0; i != rows; ++i) for (int j = 0; j != cols; ++j)
if (random(prob) < 1) triangles[i][j] = colour;
}
void drawTriangles(
PGraphics layer,
Grid2D matrix,
color[][] darkTriangles,
color[][] lightTriangles)
{
final IntVector[][] points = matrix.points;
//final PVector[][] points = matrix.getPoints();
layer.beginDraw();
layer.noStroke();
for (int i = 0; i != TRIANGS; ++i) for (int j = 0; j != TRIANGS; ++j) {
if (j+1 >= TRIANGS | i-1 <= 0 | j-1 <= 0) continue;
int firstX, firstY, secondX, secondY, thirdX, thirdY;
//float firstX, firstY, secondX, secondY, thirdX, thirdY;
if ((i & 1) == 0) {
/* drawing black ones */
firstX = points[i][j].x;
firstY = points[i][j].y;
secondX = points[i][j + 1].x;
secondY = points[i][j + 1].y;
thirdX = (firstX + secondX) / 2;
thirdY = points[i - 1][0].y;
layer.fill(darkTriangles[i][j]);
layer.triangle(firstX, firstY, secondX, secondY, thirdX, thirdY);
/* drawing white ones */
firstX = (points[i - 1][j].x + points[i - 1][j + 1].x) / 2;
firstY = points[i - 1][0].y;
secondX = (points[i - 1][j + 1].x + points[i - 1][j + 2].x) / 2;
secondY = points[i - 1][0].y;
thirdX = points[i][j + 1].x;
thirdY = points[i][j + 1].y;
layer.fill(lightTriangles[i][j]);
layer.triangle(firstX, firstY, secondX, secondY, thirdX, thirdY);
}
else {
/* drawing black ones */
firstX = (points[i][j].x + points[i][j + 1].x) / 2;
firstY = points[i][0].y;
secondX = (points[i][j + 1].x + points[i][j + 2].x) / 2;
secondY = points[i][0].y;
thirdX = points[i - 1][j + 1].x;
thirdY = points[i - 1][j + 1].y;
layer.fill(darkTriangles[i][j]);
layer.triangle(firstX, firstY, secondX, secondY, thirdX, thirdY);
/* drawing white ones */
firstX = points[i - 1][j].x;
firstY = points[i - 1][j].y;
secondX = points[i - 1][j + 1].x;
secondY = points[i - 1][j + 1].y;
thirdX = (firstX + secondX) / 2;
thirdY = points[i][0].y;
layer.fill(lightTriangles[i][j]);
layer.triangle(firstX, firstY, secondX, secondY, thirdX, thirdY);
}
}
layer.endDraw();
}
Grid2D.pde:
/***************************************************************************
* Copyright (C) 2013 by Antonio Vergari *
* arranger1044@aim.com *
* *
* Department of Computer Science *
* University of Bari, Italy *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General License for more details. *
* *
* You should have received a copy of the GNU General License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
// Hacked by GoToLoop (2013/Jul)
class Grid2D {
final PVector origin;
IntVector[][] points;
int cellWidth, cellHeight;
int colPoints, rowPoints;
/* Constructors **********************************************************/
Grid2D(PVector orig, int cols, int rows, int cellW) {
this(orig, cols, rows, cellW, cellW);
}
Grid2D(PVector orig, int cols, int rows, int cellW, int cellH) {
origin = orig;
cellWidth = cellW;
cellHeight = cellH;
colPoints = cols + 1;
rowPoints = rows + 1;
initGridPoints();
}
/* Accessors **************************************************************/
PVector[][] getPoints() {
final PVector[][] p = new PVector[rowPoints][colPoints];
for (int i = 0; i != rowPoints; ++i) for (int j = 0; j != colPoints; ++j)
p[i][j] = points[i][j].get();
return p;
}
void setCellHeight(int newHeight) {
stretchGridPoints(0, newHeight - cellHeight);
cellHeight = newHeight;
}
void setCellWidth(int newWidth) {
stretchGridPoints(newWidth - cellWidth, 0);
cellWidth = newWidth;
}
void setRows(int rows) {
rowPoints = rows + 1;
initGridPoints();
}
void setColumns(int cols) {
colPoints = cols + 1;
initGridPoints();
}
/* Modifying the grid *****************************************************/
void initGridPoints() {
points = new IntVector[rowPoints][colPoints];
final int xStart = (int) origin.x, yStart = (int) origin.y;
for (int i = 0; i != rowPoints; ++i) {
final int yPos = yStart + i*cellHeight;
for (int j = 0; j != colPoints; ++j) {
final int xPos = xStart + j*cellWidth;
points[i][j] = new IntVector(xPos, yPos);
}
}
}
void stretchGridPoints(float xOffset, float yOffset) {
for (int i = 0; i != rowPoints; ++i) for (int j = 0; j != colPoints; ++j) {
final IntVector point = points[i][j];
point.x += j * xOffset;
point.y += i * yOffset;
}
}
/* Drawing ***************************************************************/
void display(PGraphics pg, color c) {
pg.stroke(c);
display(pg);
}
void display(PGraphics pg) {
pg.beginDraw();
/* Drawing row lines */
for (int i = 0; i != rowPoints; ++i) {
final IntVector startingPoint = points[i][0];
final IntVector endingPoint = points[i][colPoints - 1];
pg.line(startingPoint.x, startingPoint.y, endingPoint.x, endingPoint.y);
}
/* Drawing col lines */
for (int j = 0; j != colPoints; ++j) {
final IntVector startingPoint = points[0][j];
final IntVector endingPoint = points[rowPoints - 1][j];
pg.line(startingPoint.x, startingPoint.y, endingPoint.x, endingPoint.y);
}
pg.endDraw();
}
}
IntVector.pde:
class IntVector {
int x, y;
IntVector(float xx, float yy) {
set((int) xx, (int) yy);
}
IntVector(PVector p) {
set(p);
}
void set(int xx, int yy) {
x = xx;
y = yy;
}
void set(PVector p) {
x = (int) p.x;
y = (int) p.y;
}
PVector get() {
return new PVector(x, y);
}
}