No description provided
The showcase player uses a modified version of Processing.js in combination with jsweet to let students program their apps in Java code while still allowing for browser support.
Content created by students is scaled to fit the showcase frame while maintaining aspect ratio and cursor position. This is why some projects may appear blurry in fullscreen, or why some small details may not be visible on a small screen
<iframe width='500px' height='400px' src='https://nest.ktbyte.com/nest#90691' allowfullscreen></iframe>
boolean showTriangles = true, showSpirals = true, showDots = true;
Draggables p;
Point[] points;
float radius = 10;
float phi = 1.618034;
float angle;
int n = 360, red = 229, green = 190, blue = 100;
float da = TWO_PI/n;
float timer = 0;
int maxPoints = 30;
void setup() {
size(800, 800);
points = new Point[2];
points[0] = new Point( width*0.1, height*0.5, color(red, green, blue), radius);
points[1] = new Point( width*0.4, height*0.5, color(red, green, blue), radius);
p = new Draggables(points, radius);
angle = PI/2;
}
void draw() {
background(0);
if (showDots) {
p.redraw();
}
p.update();
if (showTriangles) {
stroke(red, green, blue);
line(p.getPoint(0).x, p.getPoint(0).y, p.getPoint(1).x, p.getPoint(1).y);
}
PVector[] t = new PVector[maxPoints];
t[0] = new PVector(p.getPoint(0).x, p.getPoint(0).y);
t[1] = new PVector(p.getPoint(1).x, p.getPoint(1).y);
float[] di = new float[maxPoints];
di[0] = dist(t[0].x, t[0].y, t[1].x, t[1].y);
for (int i = 1; i < maxPoints; i++) {
di[i] = di[i-1]/phi;
}
float[] ang = new float[maxPoints-1];
float deltaAng = atan2(t[1].y-t[0].y, t[1].x-t[0].x);
ang[0] = angle;
for (int i = 1; i < ang.length; i++) {
ang[i] = ang[i-1] + ang[0]-deltaAng;
}
for (int i = 2; i < maxPoints; i++) {
t[i] = new PVector(t[i-1].x + di[i-1]*cos(ang[i-2]-(i-1)*108.0/360*TWO_PI),
t[i-1].y + di[i-1]*sin(ang[i-2]-(i-1)*108.0/360*TWO_PI));
}
strokeWeight(2);
for (int i = 0; i < maxPoints; i++) {
if (showTriangles) {
drawTriangles(i, t, di, ang);
}
if (showSpirals) {
drawSpirals(i, t, di, ang, deltaAng);
}
}
updateValues(deltaAng);
}
void mouseReleased() {
p.release();
}
void keyPressed() {
if (key == 't') {
showTriangles = !showTriangles;
}
if (key == 's') {
showSpirals = !showSpirals;
}
if (key == 'd') {
showDots = !showDots;
}
}
void drawSpirals(int i, PVector[] q, float[] di, float[] ang, float deltaAng) {
if (0 < i && i < maxPoints-3) {
float tempAng = atan2(q[i-1].y - q[i+2].y, q[i-1].x - q[i+2].x);
float ang108 = 108.0/360*TWO_PI, a;
drawArc(q[i+2], di[i+1]*phi, tempAng, ang108);
if (deltaAng < 0) {
drawArc(q[i+2], di[i+1]*phi, tempAng - ang108, ang108);
} else {
drawArc(q[i+2], di[i+1]*phi, tempAng - ang108, ang108);
}
}
}
void drawTriangles(int i, PVector[] q, float[] di, float[] ang) {
if (i > 0) {
stroke(red, green, blue);
line(q[i-1].x, q[i-1].y, q[i].x, q[i].y);
}
if (i < maxPoints-2) {
fill(red, green, blue, 80);
noStroke();
beginShape();
vertex(q[i].x, q[i].y);
vertex(q[i+1].x, q[i+1].y);
vertex(q[i+2].x, q[i+2].y);
endShape(CLOSE);
}
}
void drawArc(PVector mid, float r, float start, float v) {
int vMax = 10;
float dv = v/(vMax-1);
stroke(183, 31, 31);
noFill();
beginShape();
curveVertex(mid.x + r*cos(start), mid.y+ r*sin(start));
for (int i = 0; i < vMax; i++) {
curveVertex(mid.x + r*cos(start + dv*i), mid.y+ r*sin(start + dv*i));
}
curveVertex(mid.x + r*cos(start + v), mid.y+ r*sin(start + v));
endShape();
fill(183, 31, 31, 80);
noStroke();
beginShape();
curveVertex(mid.x + r*cos(start), mid.y+ r*sin(start));
for (int i = 0; i < vMax; i++) {
curveVertex(mid.x + r*cos(start + dv*i), mid.y+ r*sin(start + dv*i));
}
curveVertex(mid.x + r*cos(start + v), mid.y+ r*sin(start + v));
curveVertex(mid.x + r*cos(start + v), mid.y+ r*sin(start + v));
endShape();
}
void updateValues(float deltaAng) {
int degree = round(((deltaAng+angle)%TWO_PI)*180/PI);
if ((degree+36)%72 != 0 ) {
angle += da;
} else {
if (timer == 0) {
timer = 1;
} else if (timer < 100) {
timer ++;
} else {
timer = 0;
angle = (angle + da)% TWO_PI;
}
}
}
/**************************************************************************/
/* Class to draw a set of draggable points. When dragging a point, no */
/* other point should be dragged. When point 1 is dragged onto point 2, */
/* point 2 should be partly hidden. Next time the mouse hits the area of */
/* collision, point 1 should be dragged. */
/**************************************************************************/
class Draggables {
Point[] draggables;
//A stack of indeces. The index of a dragged point is moved to the last position in stack.
//Draw points in stack-order, update move in reverse stack-order
int[] stack;
int draggedPoint = -1;
float radius;
Draggables(Point[] p, float radius){
draggables = new Point[p.length];
stack = new int[p.length];
for (int i=0; i<p.length; i++) {
draggables[i] = new Point(p[i].x, p[i].y, p[i].fColor, p[i].r);
stack[i] = i;
}
this.radius = radius;
}
float getX(int i) {
return draggables[i].x;
}
float getY(int i) {
return draggables[i].y;
}
Point getPoint(int i) {
return draggables[i];
}
void setX(float x, int i) {
draggables[i].x =x;
}
void setY(float y, int i) {
draggables[i].y =y;
}
int size() {
return draggables.length;
}
void update() {
float mx = mouseX;
float my = mouseY;
if (mousePressed) {
for (int k=(stack.length-1); k>-1; k--) {
int i = stack[k];
if (draggedPoint == -1) {
if (dist(draggables[i].x, draggables[i].y, mx, my)<=radius) {
draggedPoint = i;
moveToLast(k);
}
} else if (mx >0 && my>0 && mx<width && my<(height-38-radius)) {
draggables[draggedPoint].x = mx;
draggables[draggedPoint].y = my;
}
}
}
}
void redraw() {
for (int i=0; i<draggables.length; i++) {
draggables[stack[i]].redraw();
}
}
void release() {
draggedPoint = -1;
}
//place the dragged index at the last position in the stack of indeces
void moveToLast(int i) {
int temp = stack[i];
for (int k=i; k<(stack.length-1); k++) {
stack[k] = stack[k+1];
}
stack[stack.length-1] = temp;
}
}
class Point {
float x, y, r;
color fColor;
Point(float x, float y, color fColor, float r) {
this.x = x;
this.y = y;
this.r = r;
this.fColor = fColor;
}
void redraw() {
noStroke();
ellipseMode(RADIUS);
fill(this.fColor);
ellipse(x, y, r, r);
}
}