/** * Interactive Toroid * by Ira Greenberg. * * Illustrates the geometric relationship * between Toroid, Sphere, and Helix * 3D primitives, as well as lathing * principal. * * Instructions: * UP arrow key pts++; * DOWN arrow key pts--; * LEFT arrow key segments--; * RIGHT arrow key segments++; * 'r' key toroid radius--; * 'f' key toroid radius++; * 'z' key initial polygon radius--; * 'x' key initial polygon radius++; * 'v' key toggle wireframe/solid shading * 'h' key toggle sphere/helix */ import kaleidoscope.*; //import kaleidoscope.WebCamera; import toxi.geom.Vec3D; import toxi.geom.Ray3D; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.AWTException; import java.awt.Point; // Point3D class required int pts = 40; float angle = 0; float radius = 40.0; // lathe segments int segments = 60; float latheAngle = 0; float latheRadius = 100.0; //vertices Point3D vertices[], vertices2[]; // for shaded or wireframe rendering boolean isWireFrame = true; // for optional helix boolean isHelix = false; float helixOffset = 5.0; Camera cam; void setup(){ size(400, 400, P3D); cam = new WebCamera( this ); cam.setPosition( new Vec3D( 208.76926, 145.1998 , 201.3854 ) ); cam.setTarget( new Vec3D(208.81529, 145.00772, 202.36398 ) ) ; cam.setRotation( new Vec3D( 11.093339, -2.6933303, 0.0) ); cam.setMoveSpeed( 0.5f ); } void draw(){ background(50, 64, 42); // basic lighting setup lights(); // println( "Position: " + cam.getPosition().x + " : " + cam.getPosition().y + " : " + cam.getPosition().z ); //println( "Target: " + cam.getTarget().x + " : " + cam.getTarget().y + " : " + cam.getTarget().z ); // println( "Rotation: " + cam.getRotation().x + " : " + cam.getRotation().y + " : " + cam.getRotation().z ); // 2 rendering styles // wireframe or solid if (isWireFrame){ stroke(255, 255, 150); noFill(); } else { noStroke(); fill(150, 195, 125); } //center and spin toroid translate(width/2, height/2, -100); rotateX(frameCount*PI/150); rotateY(frameCount*PI/170); rotateZ(frameCount*PI/90); // initialize point arrays vertices = new Point3D[pts+1]; vertices2 = new Point3D[pts+1]; // fill arrays for(int i=0; i<=pts; i++){ vertices[i] = new Point3D(); vertices2[i] = new Point3D(); vertices[i].x = latheRadius + sin(radians(angle))*radius; if (isHelix){ vertices[i].z = cos(radians(angle))*radius-(helixOffset* segments)/2; } else{ vertices[i].z = cos(radians(angle))*radius; } angle+=360.0/pts; } // draw toroid latheAngle = 0; for(int i=0; i<=segments; i++){ beginShape(QUAD_STRIP); for(int j=0; j<=pts; j++){ if (i>0){ vertex(vertices2[j].x, vertices2[j].y, vertices2[j].z); } vertices2[j].x = cos(radians(latheAngle))*vertices[j].x; vertices2[j].y = sin(radians(latheAngle))*vertices[j].x; vertices2[j].z = vertices[j].z; // optional helix offset if (isHelix){ vertices[j].z+=helixOffset; } vertex(vertices2[j].x, vertices2[j].y, vertices2[j].z); } // create extra rotation for helix if (isHelix){ latheAngle+=720.0/segments; } else { latheAngle+=360.0/segments; } endShape(); } } /* left/right arrow keys control ellipse detail up/down arrow keys control segment detail. 'a','s' keys control lathe radius 'z','x' keys control ellipse radius 'w' key toggles between wireframe and solid 'h' key toggles between toroid and helix */ void keyPressed(){ if(key == CODED) { // pts if (keyCode == UP) { if (pts<40){ pts++; } } else if (keyCode == DOWN) { if (pts>3){ pts--; } } // extrusion length if (keyCode == LEFT) { if (segments>3){ segments--; } } else if (keyCode == RIGHT) { if (segments<80){ segments++; } } } // lathe radius if (key =='r'){ if (latheRadius>0){ latheRadius--; } } else if (key == 'f'){ latheRadius++; } // ellipse radius if (key =='z'){ if (radius>10){ radius--; } } else if (key == 'x'){ radius++; } // wireframe if (key =='v'){ if (isWireFrame){ isWireFrame=false; } else { isWireFrame=true; } } // helix if (key =='h'){ if (isHelix){ isHelix=false; } else { isHelix=true; } } } class Point3D{ float x, y, z; // constructors Point3D(){ } Point3D(float x, float y, float z){ this.x = x; this.y = y; this.z = z; } }