xxxxxxxxxx
// An animation of a data shuffling algorithm and a data sorting algorithm.
// boolean, array, class, color, TWO_PI, sin, cos, lerpColor, arc, ellipse, mousePressed, mouseButton
// Left mouse to shuffle, right mouse to sort.
Shape s;
boolean isShuffling, isSorting;
void setup() {
size(700, 620);
s = new Shape();
s.fillDataArray();
isShuffling = false;
isSorting = false;
}
void draw() {
background(#C6DCC6);
showText();
if (isShuffling)s.shuffleDataArray();
if (isSorting) s.sortDataArray();
s.drawDataArray();
}
class Shape {
Vals[] data;
int num, num2, index, n, rndm, limit;
float ang, len, x1, y1, x2, y2,
incr, rds, rdsInner, dst, hold;
boolean hasSwapped;
color c1, holdCol;
Shape() {
data = new Vals[50];
incr = TWO_PI/float(50);
rdsInner = 50;
num = data.length -1;
num2 = limit = 0;
hasSwapped = false;
}
void fillDataArray() {
index = 0;
rds = 1;
for (float i = incr; i <= TWO_PI+ incr; i += incr) {
x1 = cos(i) * rdsInner;
y1 = sin(i) * rdsInner;
x2 = x1 + (cos(i) * rds*4);
y2 = y1 + (sin(i) * rds*4);
rds++;
dst = dist(x1, y1, x2, y2);
c1 = lerpColor(#99C19D, #387754, float(index)/60.0);
data[index] = new Vals(i, dst, c1);
index++;
}
}
// sin/cos calcs only needed for 'line' version of sketch.
// see commented out drawShape() function
void drawDataArray() {
translate(width/2, height/2);
for (int i = 0; i < data.length; i++) {
x1 = cos(data[i].whichDir) * rdsInner;
y1 = sin(data[i].whichDir) * rdsInner;
x2 = x1 + cos(data[i].whichDir) * data[i].howLong;
y2 = y1 + sin(data[i].whichDir) * data[i].howLong;
fill(data[i].c);
stroke(90);
strokeWeight(1);
arc(0, 0, (data[i].howLong)*2 +100,
(data[i].howLong)*2+100,
data[i].whichDir-.05,
data[i].whichDir+.05);
// stroke(#FFFF79, 200);
// strokeWeight(4);
// line(x1, y1, x2, y2);
// stroke(0);
// strokeWeight(.5);
// line(x1, y1, x2, y2);
}
fill(#C6DCC6);
noStroke();
ellipse(0, 0, 100, 100);
}
// Fisher-Yates-Durstenfeld Algorithm
void shuffleDataArray() {
if (num > 0) {
rndm = int(random(num + 1));
hold = data[rndm].howLong;
data[rndm].howLong = data[num].howLong;
data[num].howLong = hold;
holdCol = data[rndm].c;
data[rndm].c = data[num].c;
data[num].c = holdCol;
num--;
} else isShuffling = false;
}
// Bubble sort
void sortDataArray() {
if (num2 < (data.length-1) - limit) {
if (data[num2].howLong > data[num2 + 1].howLong) {
hold = data[num2].howLong;
data[num2].howLong = data[num2 + 1].howLong;
data[num2 + 1].howLong = hold;
holdCol = data[num2].c;
data[num2].c = data[num2 + 1].c;
data[num2 + 1].c = holdCol;
hasSwapped = true;
}
}
num2++;
if (num2 == data.length-1) {
limit++;
num2 = 0;
if (hasSwapped == true) hasSwapped = false;
else {
isSorting = false;
limit = 0;
}
}
}
void printArray() { // debug aid
for (int j = 0; j< data.length; j ++) {
println(data[j].whichDir, data[j].howLong);
}
}
}
class Vals {
float whichDir, howLong;
color c;
Vals(float angIn, float lenIn, color cin) {
whichDir = angIn; // not used in this sketch
howLong = lenIn;
c = cin;
}
}
void mousePressed() {
if (mouseButton == LEFT && isSorting == false) {
isShuffling = true;
s.num = s.data.length -1;
} else if (mouseButton == RIGHT && isShuffling == false)isSorting = true;
}
void showText() {
fill(100);
textSize(20);
if (isShuffling) text("shuffling", 50, 550);
else if (isSorting) text("sorting", 50, 550);
else text("waiting", 50, 550);
}
/*
// arc center x/y, arc size, number of arcs
void drawShape(float x, float y, float radius, int n) {
float incr = TWO_PI/float(n);
float val = .04;
float limit = 450.0;
for (float ang = 0; ang <= TWO_PI+ incr; ang += incr) {
float s = ang - val;
float f = s + val*2; // = ang + val
fill(255);
radius += limit/float(numArcs);
arc(x, y, radius, radius, s, f);
}
fill(0);
ellipse(300, 300, 100, 100);
}
*/