xxxxxxxxxx
/***********************************************************************************************************
arcPlay, by jWilliam Dunn
inpired by my prior work in Swift3D and Flash
and ocodo's ArcMachine and ArcConstrukt.
keyboard controls:
1,6,7,8: pre-programmed views
9 0 : add or subtract Arcs from rendering
? : snap the present camera params to the debug window
v : wireframe view
x : exit
_ - : add or subtract segment unit width
space : freeze the scene
changeLog:
20130324: minimal 2D version for JavaScript
20130323: added comments, preprogrammed camera views, renderCount, freeze mode
20130322: added HUD, color palette, wireframe view
20130321: added PeasyCam, change to 3D, construct using translated/rotated boxes (segments)
20130320: initial port from my early JavaScript 2D model
/***********************************************************************************************************/
color baseColor = #8c8c85;
int MAXARCS = 50; // optimized for 50 or less Arcs
int renderCount = 40; // start up by rendering 50 Arcs
boolean showFill = false; // initialize with wireframe view on first frame to eliminate pause between modes
boolean animateArcs = true; // toggle to freeze the scene
//color[] pallette = {#021a32,#08233e,#011c37,#011631,#021830}; // bluegrays
//color[] pallette = {#40382e,#94846a,#636363,#282c30}; // handsome baseColor = #bfab93;
color[] pallette = {#2e2e2b,#333330,#40403c,#4c4c48}; // metallic baseColor = #8c8c85;
Arc[] arcs; // the variable of class Arc
float startX, startY; // variables to hold the centerpoint of all Arcs
float segmentWidth=10; // the segment is the unit that makes up the 2D Arc
int MAXSEGMENTWIDTH = 12;
/***********************************************************************************************************/
void setup() {
size(960, 540);
startX = width/2; startY = height/2; // assign the centerpoint (a holdover from the 2D version)
// create an array of Arc objects
arcs = new Arc[MAXARCS];
for (int i=0; i<MAXARCS; i++) {
arcs[i] = new Arc(i);
}
frameRate(20);
}
/***********************************************************************************************************/
void keyPressed() {
if (key == 'x') {
exit();
}
if (key == 'v') {
showFill = !showFill;
}
if (key == ' ') {
animateArcs = !animateArcs;
}
if (key == '1') {
segmentWidth = 20;
renderCount = 50;
}
if (key == '6') {
segmentWidth = 20;
}
if (key == '7') {
segmentWidth = 3;
renderCount = 1;
}
if (key == '8') {
segmentWidth = 3;
renderCount = 10;
}
if (key == '9' && renderCount < MAXARCS) {
renderCount += 1;
}
if (key == '0' && renderCount > 1) {
renderCount -= 1;
}
if (key == '_' && segmentWidth < MAXSEGMENTWIDTH) {
segmentWidth += 1;
}
if (key == '-' && segmentWidth > 1) {
segmentWidth -= 1;
}
}
/***********************************************************************************************************/
void draw() {
if (showFill == true) {
background(baseColor);
} else {
background(#000022);
}
// render outermost Arc first
pushMatrix();
translate(mouseX/2+startX/2, mouseY/2+startY/2);
for (int i=renderCount-1; i>=0; i--) {
arcs[i].display();
}
popMatrix();
if (showFill == false) {
fill(#cccccc);
text("segmentWidth="+segmentWidth+" renderCount="+renderCount, 10, height-10);
}
if (frameCount == 1) {showFill=true;} // first pass is wireframe, then fill
}
/***********************************************************************************************************/
class Arc {
int id; // properties of an Arc
float innerRadius;
float outerRadius;
float lengthAngle;
float startAngle;
float startDelta;
color insideColor;
float lengthDelta;
int colorAlpha;
int ttl;
float level;
Arc(int id) {
initializeArc(id); // call a function to randomize an Arc
}
void initializeArc(int i) {
id = i;
innerRadius = 50 + random(id*5,id*10+50); // pick an inner radius based on the Arc id
outerRadius = innerRadius + 10 + random(id+10); // vary the outer radius also
startAngle = radians(random(360)); // choose a random starting angle
lengthAngle = radians(40 + random(120));// and a length of angular Arc
lengthDelta = radians(random(-5,5)); // how fast the length will grow/shrink
startDelta = radians(random(-5*(MAXARCS-id)/MAXARCS,5*(MAXARCS-id)/MAXARCS)); // how fast the starting angle varies
int gray = 50 + round(random(205)); // choose a gray color
// insideColor = color(gray);
insideColor = pallette[round(random(pallette.length-1))]; // or select from a pallette
colorAlpha = 85+round(random(15)); // select a random colorAlpha
ttl = 100+round(random(100)); // choose a time-to-live
level = random(-20,20); // vary the position of the Arc in Z space
}
void display() {
if (showFill == true) {
fill (insideColor);
noStroke ();
} else {
strokeWeight (0.75);
noFill ();
stroke(41,51,61,128);
}
// render the Arc by creating a series of 3D boxes in one degree increments around a circle
for (int n = round(degrees(startAngle)); n < round(degrees(startAngle+lengthAngle)); n++) {
pushMatrix();
translate(innerRadius*cos(radians(n)), innerRadius*sin(radians(n))); // polar to cartesian
rotate(radians(n)); // orient the box toward the center point
rect(0,0,outerRadius-innerRadius,segmentWidth);
popMatrix();
}
if (animateArcs) {
startAngle += startDelta; // advance the Arc along the ring by the startDelta
lengthAngle += lengthDelta; // adjust the length of the Arc
if (lengthAngle>radians(200)) {
lengthDelta = -lengthDelta;
}
if (lengthAngle<radians(20)) {
lengthDelta = -lengthDelta;
}
if (--ttl <= 0) { // if the Arc has expired
initializeArc(id); // call the init function to randomize its properties
}
}
}
}