/** *

spxlSpikyBall

*

by subpixel

* *

Version 1.0, 2009-02-24

* *

A sphere and some points... demonstration of the * SuperPoint * Processing Library.

* *

Controls

* */ import processing.opengl.*; import com.hardcorepawn.*; // Magic fast points object :o) SuperPoint p; float SPHERE_RADIUS = 200; float WIDTH_2; // Window width / 2 .. set in setup() float HEIGHT_2; // Window height / 2 .. set in setup() // User parameters boolean paused = false; boolean autoCentre = false; boolean wander = true; // State float spinSpeed = 1.0; float tSpinSpeed = 1.0; // target spinSpeed float spinIncrement = 0.1; // Origin float ox = 0.0; float oy = 0.0; float oz = 0.0; // Target origin float tox = 0.0; float toy = 0.0; float toz = 0.0; // Orientation float theta = 0.0; float phi = 0.0; // These values determine the spin on separate axes float thetaRatio = 0.003; float phiRatio = 0.009; // Easing float easeValue = 0.1; void setup() { if (online) { size(640, 480, OPENGL); // Applet-friendly size cursor(CROSS); } else { size(screen.width, screen.height, OPENGL); // Fullscreen? :o) noCursor(); } background(0); WIDTH_2 = width >> 1; HEIGHT_2 = height >> 1; p=new SuperPoint(this); for(int i=0; i < 2000; i++) { addRandomPoint(); } // Initial Location ox = tox = 0; oy = toy = 0; oz = -10000; // Far away... Result is a nice zoom in effect. :o) } void draw() { hint(DISABLE_OPENGL_ERROR_REPORT); // Speed up rendering? background(0); // Move back to centre? if (autoCentre && !mousePressed) { tox *= (1-easeValue); toy *= (1-easeValue); } else if (wander) // Wander around { float n = 8*TWO_PI * noise(frameCount * 0.001); float dx = cos(n); float dy = sin(n); tox = constrain(tox + dx, -WIDTH_2, WIDTH_2); toy = constrain(toy + dy, -HEIGHT_2, HEIGHT_2); } // Move back and forth toz = -100 + 100 * sin(frameCount * 0.01); // Ease to target ox = lerp(ox, tox, easeValue); oy = lerp(oy, toy, easeValue); oz = lerp(oz, toz, easeValue); // Ease to target spin speed spinSpeed = lerp(spinSpeed, tSpinSpeed, easeValue); // Adjust orientation using spin speed theta += spinSpeed * thetaRatio; phi += spinSpeed * phiRatio; // Translate origin translate(WIDTH_2 + ox, HEIGHT_2 + oy, oz); // Orient rotateZ(theta); rotateY(phi); // Inner sphere noStroke(); fill(0); sphereDetail(30); sphere(SPHERE_RADIUS); // Draw the points (base of tips) p.draw(12); // Additional sets of points to make pointy tips for (int i = 0; i < 8; i++) { scale(1.006 + 0.002 / (abs(spinSpeed)+1)); rotateZ(-thetaRatio * spinSpeed * 0.7); rotateY(-phiRatio * spinSpeed * 0.7); p.draw(11-i); } } // Create a new random (evenly distributed) point on a random-radius sphere void addRandomPoint() { float R = SPHERE_RADIUS * random(1, 1.5); // Random radius at least size of sphere redius float z = random(-R, R); // Pick any z within bounds of sphere float r = sqrt((R * R) - (z * z)); // Find radius of circle formed by intersection of sphere with plane Z = z float t = random(TWO_PI); // Pick random angle around circumferemce of circle float x = r * cos(t); // Locate point for the selected angle: x coordinate float y = r * sin(t); // " " " " " " : y coordinate p.addPoint(x, y, z, random(abs(z)/R),random(abs(x)/R),random(abs(y)/R),random(0.85)); } void keyPressed() { // These key codes are for my keyboard... maybe different on yours final int PAGE_UP = 33; final int PAGE_DOWN = 34; if (key == CODED) switch (keyCode) { // Move to edge of window case LEFT: tox = -HEIGHT_2; break; case RIGHT: tox = WIDTH_2; break; case UP: toy = -HEIGHT_2; break; case DOWN: toy = HEIGHT_2; break; // Spin speed adjustment case PAGE_DOWN: tSpinSpeed -= spinIncrement; break; case PAGE_UP: tSpinSpeed += spinIncrement; break; default: // In case you need to work out what key you're pressing! println(keyCode); break; } else switch (key) { case ' ': // Pause/unpause paused = !paused; if (paused) noLoop(); else loop(); break; case 'c': case 'C': // Centre on/off autoCentre = !autoCentre; break; case 'j': case 'J': // Jump to random position ox = tox = random( -WIDTH_2, WIDTH_2); oy = toy = random(-HEIGHT_2, HEIGHT_2); break; case 'm': case 'M': // Move to random position tox = random( -WIDTH_2, WIDTH_2); toy = random(-HEIGHT_2, HEIGHT_2); break; case 's': case 'S': { // Random spin speed // Random integer -2, -1, 0, 1 (2 isn't included as we account for equal value next) float rnd = int(random(-3, 2)); // If less than exising value, use it, otherwise use one number higher // so we don't get the same value as last time tSpinSpeed = (rnd < tSpinSpeed) ? rnd : rnd + 1; break; } case 'x': case 'X': // Stop spinning tSpinSpeed = 0; break; case 'w': case 'W': // Wander on/off wander = !wander; break; default: // In case you need to work out what key you're pressing! println(key); break; } } void mousePressed() { targetMouse(); } void mouseDragged() { targetMouse(); } // Set target location based on mouse position void targetMouse() { tox = mouseX - WIDTH_2; toy = mouseY - HEIGHT_2; }