Spin3d spin = new Spin3d(); void setup() { size(200,200); framerate(20); } void mouseDragged() { spin.mouseMoved(); } void loop() { spin.update(); background(240); translate(width/2, height/2); spin.apply(); scale(50); stroke(0); drawShape(); } final float a = 1.0f; final float b = a * 0.8f; final float c = a * 0.5f; void drawShape() { drawPair(); rotateY(HALF_PI); rotateZ(HALF_PI); drawPair(); rotateY(HALF_PI); rotateZ(HALF_PI); drawPair(); } void drawPair() { push(); translate(0,0,(a-c)/2+c); drawPiece(); pop(); push(); translate(0,0,-(a-c)/2-c); rotateX(PI); drawPiece(); pop(); } void drawPiece() { // front beginShape(POLYGON); // right top vertex(a/2, b+a/2, 0); vertex(a/2, a/2, 0); vertex((a-c)/2, a/2, 0); // right bottom vertex((a-c)/2, -a/2, 0); vertex(a/2, -a/2, 0); vertex(a/2, -b-a/2, 0); // left bottom vertex(-a/2, -b-a/2, 0); vertex(-a/2, -a/2, 0); vertex(-(a-c)/2, -a/2, 0); // left top vertex(-(a-c)/2, a/2, 0); vertex(-a/2, a/2, 0); vertex(-a/2, b+a/2, 0); endShape(); float y = 1; for (int i=0; i<2; i++) { // top cap beginShape(POLYGON); vertex(a/2, y*(b+a/2), 0); vertex(-a/2, y*(b+a/2), 0); vertex(-a/2, y*(b+a/2), -c); vertex(a/2, y*(b+a/2), -c); endShape(); // back cap beginShape(POLYGON); vertex(a/2, y*(b+a/2), -c); vertex(-a/2, y*(b+a/2), -c); vertex(-a/2, y*(a/2+c/2), -c); vertex(a/2, y*(a/2+c/2), -c); endShape(); // side panels float x = 1; for (int j=0; j<2; j++) { beginShape(POLYGON); vertex(x*-a/2, y*(b+a/2), 0); vertex(x*-a/2, y*(b+a/2), -c); vertex(x*-a/2, y*(c/2+a/2),-c); vertex(x*-a/2, y*(c/2+a/2),-c/2); vertex(x*-a/2, y*(a/2), -c/2); vertex(x*-a/2, y*(a/2), 0); endShape(); x = -1; } y = -1; } } /******************************************************************************* * Spin3d - Handles nice trackball style camera movement in Processing * - based on Matrix3D code from cello3d by Marcello ********************************************************************************/ public class Spin3d { float x= 0, y = 0; float tdx = 0, tdy = 0; float dx = tdx, dy = tdy; public void mouseMoved() { // GOTCHA: x and y are switched! tdx=0.01*(mouseY-pmouseY); tdy=0.01*(mouseX-pmouseX); } public void apply() { g.transform(m_0_0, m_0_1, m_0_2, m_0_3, m_1_0, m_1_1, m_1_2, m_1_3, m_2_0, m_2_1, m_2_2, m_2_3, m_3_0, m_3_1, m_3_2, m_3_3); } void update() { x += dx; y += dy; dx += (tdx-dx)/20; dy += (tdy-dy)/20; tdx += (0-tdx)/20; tdy += (0-tdy)/20; rotateX(dx); rotateY(dy); } public Spin3d() { } public float m_0_0 = 1, m_0_1 = 0, m_0_2 = 0, m_0_3 = 0, m_1_0 = 0, m_1_1 = 1, m_1_2 = 0, m_1_3 = 0, m_2_0 = 0, m_2_1 = 0, m_2_2 = 1, m_2_3 = 0, m_3_0 = 0, m_3_1 = 0, m_3_2 = 0, m_3_3 = 1; public void rotateX(float t) { if (t==0) return; float sin = sin(t); float cos = cos(t); transform( 1, 0, 0, 0, 0, cos, sin, 0, 0, -sin,cos, 0, 0, 0, 0, 1 ); } public void rotateY(float t) { if (t==0) return; float sin = sin(t); float cos = cos(t); transform( cos, 0, sin, 0, 0, 1, 0, 0, -sin,0, cos, 0, 0, 0, 0, 1 ); } public void transform(float nm_0_0, float nm_0_1, float nm_0_2, float nm_0_3, float nm_1_0, float nm_1_1, float nm_1_2, float nm_1_3, float nm_2_0, float nm_2_1, float nm_2_2, float nm_2_3, float nm_3_0, float nm_3_1, float nm_3_2, float nm_3_3) { Spin3d m = new Spin3d(); m.m_0_0 = m_0_0; m.m_0_1 = m_0_1; m.m_0_2 = m_0_2; m.m_0_3 = m_0_3; m.m_1_0 = m_1_0; m.m_1_1 = m_1_1; m.m_1_2 = m_1_2; m.m_1_3 = m_1_3; m.m_2_0 = m_2_0; m.m_2_1 = m_2_1; m.m_2_2 = m_2_2; m.m_2_3 = m_2_3; m.m_3_0 = m_3_0; m.m_3_1 = m_3_1; m.m_3_2 = m_3_2; m.m_3_3 = m_3_3; m_0_0 = nm_0_0*m.m_0_0 + nm_0_1*m.m_1_0 + nm_0_2*m.m_2_0; m_0_1 = nm_0_0*m.m_0_1 + nm_0_1*m.m_1_1 + nm_0_2*m.m_2_1; m_0_2 = nm_0_0*m.m_0_2 + nm_0_1*m.m_1_2 + nm_0_2*m.m_2_2; m_0_3 = nm_0_0*m.m_0_3 + nm_0_1*m.m_1_3 + nm_0_2*m.m_2_3 + nm_0_3; m_1_0 = nm_1_0*m.m_0_0 + nm_1_1*m.m_1_0 + nm_1_2*m.m_2_0; m_1_1 = nm_1_0*m.m_0_1 + nm_1_1*m.m_1_1 + nm_1_2*m.m_2_1; m_1_2 = nm_1_0*m.m_0_2 + nm_1_1*m.m_1_2 + nm_1_2*m.m_2_2; m_1_3 = nm_1_0*m.m_0_3 + nm_1_1*m.m_1_3 + nm_1_2*m.m_2_3 + nm_1_3; m_2_0 = nm_2_0*m.m_0_0 + nm_2_1*m.m_1_0 + nm_2_2*m.m_2_0; m_2_1 = nm_2_0*m.m_0_1 + nm_2_1*m.m_1_1 + nm_2_2*m.m_2_1; m_2_2 = nm_2_0*m.m_0_2 + nm_2_1*m.m_1_2 + nm_2_2*m.m_2_2; m_2_3 = nm_2_0*m.m_0_3 + nm_2_1*m.m_1_3 + nm_2_2*m.m_2_3 + nm_2_3; } }