Yah... This version uses the "pixel distance" (as in, number of pixels Bresenham's line-drawing algorithm would plot), which creates a square rather than a circle...
It also removes randomness altogether by rearranging points counter-clockwise based on the last point encountered, so that it constantly moves in one direction.
Code:int ax, ay; // Current pixel under evaluation
int bx, by; // Last evaluated pixel
// Maps our array of coordinates counter-clockwise
int[][] clockmap = { { 3, 5, 6, 7, 4, 2, 1 },
{ 0, 3, 5, 6, 7, 4, 2 },
{ 1, 0, 3, 5, 6, 7, 4 },
{ 5, 6, 7, 4, 2, 1, 0 },
{ 2, 1, 0, 3, 5, 6, 7 },
{ 6, 7, 4, 2, 1, 0, 3 },
{ 7, 4, 2, 1, 0, 3, 5 },
{ 4, 2, 1, 0, 3, 5, 6 } };
void setup() {
size(500, 500);
background(255);
// Start in the center
bx = (int)Math.round(width / 2);
by = (int)Math.round(height / 2);
set(bx, by, color(0));
// Move outward one pixel
ax = bx + 1;
ay = by;
}
void draw() {
// Mark our current position
set(ax, ay, color(0));
// These are the possible points to choose from
int[][] pxls = { { ax - 1, ay - 1 }, { ax, ay - 1 }, { ax + 1, ay - 1 },
{ ax - 1, ay }, /* CENTER, */ { ax + 1, ay },
{ ax - 1, ay + 1 }, { ax, ay + 1 }, { ax + 1, ay + 1 } };
// Determine which of the possible points is the one we were last in
int bidx = 0xC0DEDBAD;
for(int i = 0; i < 8; i ++) {
if(pxls[i][0] == bx && pxls[i][1] == by) {
bidx = i;
break;
}
}
// Re-map the possible points based on our counter-clockwise map
int[][] ccwpxls = new int[7][2];
for(int i = 0; i < 7; i ++) {
ccwpxls[i][0] = pxls[ clockmap[bidx][i] ][0];
ccwpxls[i][1] = pxls[ clockmap[bidx][i] ][1];
}
// Remove any impossible points
for(int i = 0; i < 7; i ++) {
int x = ccwpxls[i][0];
int y = ccwpxls[i][1];
// Is it out of bounds?
if(x < 0 || x >= width || y < 0 || y >= height) {
ccwpxls[i][0] = 0xDEADBEEF;
ccwpxls[i][1] = 0xFEEDFACE;
continue;
}
// Has it already been evaluated?
color c = get(x, y);
if((c | 0xFF000000) != 0xFFFFFFFF) {
ccwpxls[i][0] = 0xDEADBEEF;
ccwpxls[i][1] = 0xFEEDFACE;
}
}
// Calculate each point's distance from the center
int[] dists = new int[7];
int mindist = 0xC0DEDBAD;
for(int i = 0; i < 7; i ++) {
dists[i] = pxlDist(ccwpxls[i][0], ccwpxls[i][1]);
if(dists[i] < mindist || i == 0)
mindist = dists[i];
}
// Void any points that are not the closest
for(int i = 0; i < 7; i ++) {
if(dists[i] > mindist) {
ccwpxls[i][0] = 0xDEADBEEF;
ccwpxls[i][1] = 0xFEEDFACE;
}
}
// Look for the first non-voided point
int nextidx = 0xC0DEDBAD;
for(int i = 0; i < 7; i ++) {
if(ccwpxls[i][0] != 0xDEADBEEF && ccwpxls[i][1] != 0xFEEDFACE) {
nextidx = i;
break;
}
}
// Plot the point and move on
if(nextidx != 0xC0DEDBAD) {
bx = ax; by = ay;
ax = ccwpxls[nextidx][0];
ay = ccwpxls[nextidx][1];
} else {
println("Something horrible has happened!");
noLoop();
}
}
int pxlDist(int x, int y) {
int cx = (int)Math.round(width / 2);
int cy = (int)Math.round(height / 2);
return max(abs(x - cx), abs(y - cy));
//return (int)Math.round(dist(x, y, cx, cy));
}
Any idea of another way to measure distance so that I get a circular shape, rather than one that creates squares or octagons?
(I understand why it's doing what it's doing, my problem is how to fix it!)