/**
* Food Triad
*
*
Elie Zananiri
* silentlyCrashing::net
* Feb 2010
* Drag the points to set the corresponding parameter.
* Press 's' to save a new entry.
*/
static final int TASTE = 0;
static final int HEALTH = 1;
static final int COST = 2;
static final String[] LABELS = { "taste", "health", "cost" };
static final int[] ANGLES = { 270, 150, 30 };
int centerX;
int centerY;
PFont font;
Param[] params;
Param selected;
float[][] history;
int currEntry;
int lastEntry;
void setup() {
size(400, 400, P3D);
noStroke();
font = createFont("alex.ttf", 36);
textFont(font, 20);
textAlign(CENTER, CENTER);
centerX = width/2;
centerY = height/2 + 35;
// set up parameters
params = new Param[3];
params[TASTE] = new Param(ANGLES[TASTE], 0xFFDB1818);
params[HEALTH] = new Param(ANGLES[HEALTH], 0xFF4F6401);
params[COST] = new Param(ANGLES[COST], 0xFFFAE11E);
selected = null;
reload();
}
void draw() {
background(255);
// update the offset for the selected parameter, if any
if (selected != null) {
selected.off = min(max(Param.MIN, dist(centerX, centerY, mouseX, mouseY)), Param.MAX);
selected.update();
saveEntry();
}
// draw the text labels
smooth();
fill(0);
text(LABELS[TASTE], width/2, params[TASTE].y - 20);
text(LABELS[HEALTH], params[HEALTH].x, params[HEALTH].y + 20);
text(LABELS[COST], params[COST].x, params[COST].y + 20);
// draw the parameter handles
noSmooth();
for (int i=0; i < params.length; i++) {
params[i].draw();
}
smooth();
beginShape(TRIANGLES);
{
// draw the current polygon
for (int i=0; i < params.length; i++) {
fill(params[i].col, map(params[i].off, Param.MIN, Param.MAX, 10, 255));
vertex(params[i].x, params[i].y);
}
}
endShape();
noFill();
beginShape(TRIANGLES);
{
// draw the old polygons
for (int j=0; j < currEntry; j++) {
stroke(0, (j+1)/(currEntry*1.f) * 255);
for (int i=0; i < history[j].length; i++) {
vertex(calcX(history[j][i], radians(ANGLES[i])), calcY(history[j][i], radians(ANGLES[i])));
}
}
}
endShape();
noStroke();
}
void saveEntry() {
history[lastEntry][TASTE] = params[TASTE].off;
history[lastEntry][HEALTH] = params[HEALTH].off;
history[lastEntry][COST] = params[COST].off;
}
void reload() {
String lines[] = loadStrings("entries.txt");
history = new float[lines.length+1][3];
lastEntry = currEntry = lines.length;
for (int i=0; i < lines.length; i++) {
String[] vals = split(lines[i], ",");
history[i][TASTE] = float(vals[TASTE]);
history[i][HEALTH] = float(vals[HEALTH]);
history[i][COST] = float(vals[COST]);
}
saveEntry();
}
void saveAllAndReload() {
String[] data = new String[history.length];
for (int i=0; i < data.length; i++) {
data[i] = history[i][TASTE] + "," + history[i][HEALTH] + "," + history[i][COST];
}
saveStrings("data/entries.txt", data);
reload();
}
void mousePressed() {
for (int i=0; i < params.length; i++) {
if (params[i].contains(mouseX, mouseY)) {
currEntry = lastEntry;
selected = params[i];
}
}
}
void mouseReleased() {
selected = null;
}
void keyPressed() {
if (key == CODED) {
if (keyCode == LEFT) {
if (currEntry > 0) {
currEntry--;
for (int i=0; i < params.length; i++) {
params[i].tweenTo(history[currEntry][i]);
}
}
} else if (keyCode == RIGHT) {
if (currEntry < lastEntry) {
currEntry++;
for (int i=0; i < params.length; i++) {
params[i].tweenTo(history[currEntry][i]);
}
}
}
} else if (key == 's') {
saveAllAndReload();
}
}
float calcX(float _off, float _ang) {
return (centerX + _off * cos(_ang));
}
float calcY(float _off, float _ang) {
return (centerY + _off * sin(_ang));
}