//Aaron Koblin //Design for Interactive Media 157A //11/29/04 //Weavograph is a generative piece designed for //printmaking using the Adobe Illustrator format. int stagex = 400; //stage width int stagey = 400; //steage height AIExport ai; int angle,speed, radius1, radius2; //radius is a distance per vert seed int centery, centerx, counter; float[] centersx = new float[10]; float[] centersy = new float[10]; float[] spritesx = new float[10]; float[] spritesy = new float[10]; float[] speeds = new float[10]; boolean flag1, drawing; BImage brush1,brush2,sc1,sc2,sc3,sc4,sc5; void setup(){ ai = new AIExport( this, 10 ); ai.turnTransparencyOn(); ai.setFileName("test4.ai"); ai.setLineWeight( 0.25); framerate(20); counter = 0; background(255); size(stagex, stagey); centerx = stagex/2; centery = stagey/2; centerverts(); //plots the centers for each sprite in a circle; drawing = true; } void loop(){ ai.run(); if (drawing){ if (counter > 100){ counter = 0; } if (counter > 50){ flag1 = true; counter ++; }else{ if(counter < 100){ flag1 = false; counter ++; } } if(flag1){ plotsprites(); } else plotsprites2(); drawpattern(); angle++; if(angle > 360){ //prevents overflow after long run-time angle = 1; setspeeds(); } radius1 = mouseX/1; radius2 = mouseX/2; } } void setspeeds(){ for(int x = 0;x<10;x++){ speeds[x] = mouseX/6+(9*x); // setup a speed for the rotation of each vert } } void centerverts(){ for(int x=0;x< centersx.length ;x++){ angle = 0; angle = 36 * x; centersx[x] = centerx + (cos(angle*3.14/180)*radius1); centersy[x] = centery + (sin(angle*3.14/180)*radius1); } } void plotsprites(){ for(int x=0;x< spritesx.length ;x++){ spritesx[x] = centersx[x] + (tan((angle*speeds[x])*3.14/180)*radius2); spritesy[x] = centersy[x] + (sin((angle*speeds[x])*3.14/180)*radius2); } } void plotsprites2(){ for(int x=0;x< spritesx.length ;x++){ spritesx[x] = centersx[x] + (tan((angle*speeds[x])*3.14/180)*radius2); spritesy[x] = centersy[x] + (cos((angle*speeds[x])*3.14/180)*radius2); } } void drawpattern(){ for(int x=0;x< spritesx.length;x++){ rotate((PI/180)*speeds[x]); ai.ai_fill(int(speeds[x])*2+50, int(speeds[x])*2+50,100,160); if(x<5){ ai.ai_rect(spritesx[x], spritesy[x], 30, int(speeds[x]/12)+2); } if(x>5){ ai.ai_rect(spritesx[x], spritesy[x], 30, int(speeds[x]/12)+2); } } } void mousePressed() { setup(); } void keyPressed(){ if( key=='e' ) ai.exportOneFrame(); if( key=='s' ) ai.takeSnapShot(); if( key=='d' ) ai.dumpSnapShots(); if( key=='r' ) ai.toggleContinuousRecording(); } /* * Created on Jun 4, 2004 * * TODO To change the template for this generated file go to Window - * Preferences - Java - Code Generation - Code and Comments */ /** * @author William * * TODO To change the template for this generated type comment go to Window - * Preferences - Java - Code Generation - Code and Comments */ //******************************************************************************************** // // Export class for Adobe Illustrator (*.ai) files // version 0.1a // build 000005 // // Exports version 8.0/10.0 Adobe Illustrator files. // // Distributed under the GNU lesser public license without implied // or explicit warrantees of any kind, including, but not limited // to, the implied warrantee of MERCHANTABILITY or FITNESS FOR // A PARTICULAR PURPOSE. // // by Allan William Martin // // ******************************************************************************************** public class AIExport { // Constructor. Sets the bApplet, layers, and defaults for rectMode and ellipseMode. public AIExport(BApplet bApplet, int nLayers) { this.bApplet = bApplet; setNumberOfLayers(nLayers); ai_rectMode(BConstants.CORNER); ai_ellipseMode(BConstants.CORNER); } private BApplet bApplet; final int START_LINES = 100; int NUM_LAYERS = 5; // Five default layers. final int IDLE = 0; final int WRITING = 1; int stage = IDLE; boolean writeAIFile = false; boolean continuousRecording = false; boolean snapShot = false; boolean dump = false; int snapShotNum = 1; int group = 0; String[][] layers = null; int[] nLines; int currentLayer = 1; int currentRectMode; int currentEllipseMode; int currentShapeMode; int shapeStage = 0; int shapeCycle = 0; float[] shapeFirstVertex = new float[3]; float currentLineWeight = 1.0f; boolean transparency = false; String strokeFillTagClosed = "b"; String strokeFillTagOpen = "B"; String fileName = "AI_output.ai"; /** * Functions that actually write the Illustrator file begin here; */ private void setNumberOfLayers(int nLayers) { if (nLayers < 1) nLayers = 1; NUM_LAYERS = nLayers; nLines = new int[NUM_LAYERS]; for (int i = 0; i < NUM_LAYERS; i++) nLines[i] = 0; } void setFileName(String fileName) { this.fileName = fileName; } private void setDefaults() { setLayer(1); currentLineWeight = 1.0f; } public void run() { if ((stage == WRITING && (!continuousRecording && !snapShot)) || dump) { dump = false; // Load the blank Illustrator prototype. String[][] aiHeader = new String[2][]; aiHeader[0] = bApplet.loadStrings("AIHeader1.txt"); aiHeader[1] = bApplet.loadStrings("AIHeader2.txt"); String[][] aiLayer = new String[2][]; aiLayer[0] = bApplet.loadStrings("AILayer1.txt"); aiLayer[1] = bApplet.loadStrings("AILayer2.txt"); String[] aiEOF; aiEOF = bApplet.loadStrings("AIEOF.txt"); // Calculate the anticipated file length. int fileLength = 0; fileLength += aiHeader[0].length + 1; fileLength += aiHeader[1].length; fileLength += (NUM_LAYERS - 1) * (aiLayer[0].length + 1); fileLength += (NUM_LAYERS - 1) * aiLayer[1].length; fileLength += aiEOF.length; for (int i = 0; i < NUM_LAYERS; i++) fileLength += nLines[i]; String[] aiLines = new String[fileLength]; int currentLine = 0; // Keeps track of where we're writing in the // file. // Write the header and specify the number of layers. System.arraycopy(aiHeader[0], 0, aiLines, currentLine, aiHeader[0].length); currentLine += aiHeader[0].length; aiLines[currentLine] = "%AI5_NumLayers: " + NUM_LAYERS; currentLine++; System.arraycopy(aiHeader[1], 0, aiLines, currentLine, aiHeader[1].length); currentLine += aiHeader[1].length; // Write the layers. for (int i = 1; i <= NUM_LAYERS; i++) { // Write the graphical contents of the layer. if (layers[i - 1][0] != null) { System.arraycopy(layers[i - 1], 0, aiLines, currentLine, nLines[i - 1]); currentLine += nLines[i - 1]; } // Write the terminator for the current layer, the beginning of // the next layer, and the name and setup stuff for the next layer. // But the last end-of-layer command is in AIEOF.txt, so don't // write this stuff on the last layer. if (i < NUM_LAYERS) { System.arraycopy(aiLayer[0], 0, aiLines, currentLine, aiLayer[0].length); currentLine += aiLayer[0].length; aiLines[currentLine] = "(Layer " + (i + 1) + ") Ln"; currentLine++; System.arraycopy(aiLayer[1], 0, aiLines, currentLine, aiLayer[1].length); currentLine += aiLayer[1].length; } } // Write the end-of-file stuff. System.arraycopy(aiEOF, 0, aiLines, currentLine, aiEOF.length); // Write the file! bApplet.saveStrings(fileName, aiLines); setStage(IDLE); writeAIFile = false; bApplet.println("AIExport: Adobe Illustrator file " + fileName + " written with " + aiLines.length + " lines."); layers = null; for (int i = 0; i < NUM_LAYERS; i++) nLines[i] = 0; return; } // If done recording the snapshot, don't write the file, but set // the stage back to idle. if (stage == WRITING && snapShot) { setStage(IDLE); } // If writing is triggered and you're writing a snapshot or // recording one frame, set the stage to writing to record // the upcoming frame. if (writeAIFile && (!continuousRecording || snapShot)) { setStage(WRITING); writeAIFile = false; } // If writing is triggered and you're recording continuously, // set the stage to writing to record the upcoming frame and // trigger writing again so the next frame is recorded, too. if (writeAIFile && continuousRecording) { setStage(WRITING); writeAIFile = true; } // Set the default Illustrator-specific variables, and write the // stroke and fill at the beginning before recording the frame. setDefaults(); if (stage == WRITING) { writeCurrentStroke(); writeCurrentFill(); } } private void addLine(String lineContents) { if (continuousRecording && (bApplet.frame % frameRate) != 0) return; if (layers == null) { layers = new String[NUM_LAYERS][START_LINES]; } // Expand the array if it's suddenly larger than what's been allocated // so far (a multiple of START_LAYERS). if (nLines[currentLayer - 1] >= layers[currentLayer - 1].length) { String[][] newLayers = new String[NUM_LAYERS][nLines[currentLayer - 1] + START_LINES]; for (int i = 0; i < NUM_LAYERS; i++) { System.arraycopy(layers[i], 0, newLayers[i], 0, nLines[currentLayer - 1]); } layers = newLayers; } layers[currentLayer - 1][nLines[currentLayer - 1]] = lineContents; nLines[currentLayer - 1]++; } // ***************************************************************************************** // Functions for interface handling; int frameRate = 1; public void exportOneFrame(){ beginWriting(); } void beginWriting() { writeAIFile = true; bApplet.println("AIExport: Starting default export. Exporting the next frame."); } public void setContinuousRecordingFrameRate(int frameRate) { this.frameRate = frameRate; } public void toggleContinuousRecording() { continuousRecording = !continuousRecording; if (continuousRecording) { writeAIFile = true; bApplet.println("AIExport: Continuous recording started."); } if (!continuousRecording) { writeAIFile = false; bApplet.println("AIExport: Continuous recording terminated."); } } public void takeSnapShot() { snapShot = true; writeAIFile = true; bApplet.println("AIExport: Taking Illustrator snapshot #" + snapShotNum + "."); snapShotNum++; } public void dumpSnapShots() { dump = true; bApplet.println("AIExport: Dumping " + (snapShotNum - 1) + " Illustrator snapshots."); snapShotNum = 1; } private void setStage(int stage) { this.stage = stage; } // ***************************************************************************************** // Functions that handle Illustrator-specific parameters; void setLayer(int layer) { if (layer >= 1 && layer <= NUM_LAYERS) currentLayer = layer; writeCurrentStroke(); writeCurrentFill(); writeCurrentLineWeight(); } void setLineWeight(float lw) { currentLineWeight = lw; writeCurrentLineWeight(); } private void writeCurrentLineWeight(){ if (stage == WRITING) { /* int rememberCurrentLayer = currentLayer; for (int i = 1; i <= NUM_LAYERS; i++) { currentLayer = i;*/ addLine(currentLineWeight + " w"); /* } currentLayer = rememberCurrentLayer;*/ } } void beginGroup() { if (stage == WRITING) { if (group == 0) addLine("u"); group++; } } void endGroup() { if (stage == WRITING) { if (group > 0) group--; if (group == 0) addLine("U"); } } // ***************************************************************************************** // Processing variants to allow for .AI exporting start here; // The ones here handle stroke and fill; void turnTransparencyOn() { transparency = true; } void turnTransparencyOff() { transparency = false; } void ai_noFill() { bApplet.noFill(); if (stage == WRITING) { if (transparency) addLine("0 1 0 0 0 Xy"); if (bApplet.g._stroke) { strokeFillTagClosed = "s"; strokeFillTagOpen = "S"; } else { strokeFillTagClosed = "n"; strokeFillTagOpen = "N"; } } } void ai_fill(int arg0) { bApplet.fill(arg0); setFill(); } void ai_fill(float arg0) { bApplet.fill(arg0); setFill(); } void ai_fill(float arg0, float arg1) { bApplet.fill(arg0, arg1); setFill(); } void ai_fill(float arg0, float arg1, float arg2) { bApplet.fill(arg0, arg1, arg2); setFill(); } void ai_fill(float arg0, float arg1, float arg2, float arg3) { bApplet.fill(arg0, arg1, arg2, arg3); setFill(); } private void setFill() { if (stage == WRITING) { if (bApplet.g._stroke) { strokeFillTagClosed = "b"; strokeFillTagOpen = "B"; } else { strokeFillTagClosed = "f"; strokeFillTagOpen = "F"; } writeCurrentFill(); } } private void writeCurrentFill() { if (stage == WRITING && bApplet.g._fill) addLine(bApplet.g.fillR + " " + bApplet.g.fillG + " " + bApplet.g.fillB + " Xa"); } private void writeFillTransparency() { if (stage == WRITING && (transparency && bApplet.g._fill) ) addLine("0 " + bApplet.g.fillA + " 0 0 0 Xy"); } void ai_noStroke() { bApplet.noStroke(); if (stage == WRITING) { if (transparency) addLine("0 1 0 0 0 Xy"); if (bApplet.g._fill) { strokeFillTagClosed = "f"; strokeFillTagOpen = "F"; } else { strokeFillTagClosed = "n"; strokeFillTagOpen = "N"; } } } void ai_stroke(int arg0) { bApplet.stroke(arg0); setStroke(); } void ai_stroke(float arg0) { bApplet.stroke(arg0); setStroke(); } void ai_stroke(float arg0, float arg1) { bApplet.stroke(arg0, arg1); setStroke(); } void ai_stroke(float arg0, float arg1, float arg2) { bApplet.stroke(arg0, arg1, arg2); setStroke(); } void ai_stroke(float arg0, float arg1, float arg2, float arg3) { bApplet.stroke(arg0, arg1, arg2, arg3); setStroke(); } private void setStroke() { if (stage == WRITING) { if (bApplet.g._fill) { strokeFillTagClosed = "b"; strokeFillTagOpen = "B"; } else { strokeFillTagClosed = "s"; strokeFillTagOpen = "S"; } writeCurrentStroke(); } } private void writeCurrentStroke() { if (stage == WRITING && bApplet.g._stroke) addLine(bApplet.g.strokeR + " " + bApplet.g.strokeG + " " + bApplet.g.strokeB + " XA"); } private void writeStrokeTransparency() { if (stage == WRITING && (transparency && bApplet.g._stroke) ) addLine("0 " + bApplet.g.strokeA + " 0 0 0 Xy"); } private boolean solid() { if (bApplet.g.strokeA > 254 && bApplet.g.fillA > 254) return true; return false; } // ***************************************************************************************** // Below are the drawing functions; private float reflectedScreenY(float x, float y, float z) { // Illustrator's origin is the lower-left; this function // compensates. return bApplet.height - bApplet.screenY(x, y, z); } int currentFontSize; int currentFontMode = BConstants.ALIGN_LEFT; void ai_textMode(int mode) { bApplet.textMode(mode); if (stage == WRITING) currentFontMode = mode; } void ai_textSize(int fontSize) { bApplet.textSize(fontSize); currentFontSize = fontSize; } void ai_textFont(BFont font, int fontSize) { bApplet.textFont(font, fontSize); currentFontSize = fontSize; } void ai_text(String context, float x, float y) { bApplet.text(context, x, y); if (stage == WRITING) { y += currentFontSize; if (currentFontMode == BConstants.ALIGN_CENTER) x -= bApplet.width / 2; if (currentFontMode == BConstants.ALIGN_RIGHT) x -= bApplet.width; writeFillTransparency(); addLine("1 To"); addLine("1 0 0 1 1 1 0 Tp"); addLine(bApplet.screenX(x, y, 0) + " " + reflectedScreenY(x, y, 0) + " m"); addLine((bApplet.screenX(x, y, 0) + bApplet.width) + " " + reflectedScreenY(x, y, 0) + " L"); addLine((bApplet.screenX(x, y, 0) + bApplet.width) + " " + (reflectedScreenY(x, y, 0) + currentFontSize + 10) + " L"); addLine(bApplet.screenX(x, y, 0) + " " + (reflectedScreenY(x, y, 0) + currentFontSize + 10) + " L"); addLine(bApplet.screenX(x, y, 0) + " " + reflectedScreenY(x, y, 0) + " L"); addLine("n"); addLine("TP"); addLine("0 Tr"); if (currentFontMode == BConstants.ALIGN_LEFT) addLine("0 Ta"); if (currentFontMode == BConstants.ALIGN_CENTER) addLine("1 Ta"); if (currentFontMode == BConstants.ALIGN_RIGHT) addLine("2 Ta"); addLine("/_Myriad-Roman " + currentFontSize + " 10.0439 -3 Tf"); addLine("(" + context + ") Tx"); addLine("TO"); } } void ai_point(float x, float y) { ai_point(x, y, 0); } void ai_point(float x, float y, float z) { if( z==0 ) bApplet.point( x, y ); else bApplet.point(x, y, z); if (stage == WRITING) { writeStrokeTransparency(); addLine((bApplet.screenX(x, y, z) - .1f) + " " + (reflectedScreenY(x, y, z) - .1f) + " m"); addLine((bApplet.screenX(x, y, z) + .1f) + " " + (reflectedScreenY(x, y, z) - .1f) + " L"); addLine((bApplet.screenX(x, y, z) + .1f) + " " + (reflectedScreenY(x, y, z) + .1f) + " L"); addLine((bApplet.screenX(x, y, z) - .1f) + " " + (reflectedScreenY(x, y, z) + .1f) + " L"); addLine((bApplet.screenX(x, y, z) - .1f) + " " + (reflectedScreenY(x, y, z) - .1f) + " L"); if (bApplet.g._stroke) { addLine("b"); } else { addLine("n"); } } } void ai_line(float x1, float y1, float x2, float y2) { bApplet.line(x1, y1, x2, y2); writeLine( x1, y1, 0, x2, y2, 0 ); } void ai_line(float x1, float y1, float z1, float x2, float y2, float z2) { bApplet.line(x1, y1, z1, x2, y2, z2); writeLine( x1, y1, z1, x2, y2, z2 ); } void ai_triangle(float x1, float y1, float x2, float y2, float x3, float y3) { bApplet.triangle(x1, y1, x2, y2, x3, y3); writeTri( x1, y1, 0, x2, y2, 0, x3, y3, 0 ); } void ai_quad(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4 ) { bApplet.quad(x1, y1, x2, y2, x3, y3, x4, y4); writeQuad( x1, y1, 0, x2, y2, 0, x3, y3, 0, x4, y4, 0 ); } void ai_ellipseMode(int mode) { currentEllipseMode = mode; bApplet.ellipseMode(mode); } void ai_ellipse(float a, float b, float c, float d) { bApplet.ellipse(a, b, c, d); if (stage == WRITING) { if (currentEllipseMode == BConstants.CENTER_DIAMETER) { a -= c / 2; b -= d / 2; } if (currentEllipseMode == BConstants.CENTER_RADIUS) { c *= 2; d *= 2; a -= c / 2; b -= d / 2; } if (currentEllipseMode == BConstants.CORNERS) { c -= a; d -= b; } if (transparency && bApplet.g._stroke && bApplet.g._fill && !solid()) beginGroup(); for (int k = 0; k <= 1; k++) { if (!bApplet.g._fill && bApplet.g._stroke) k++; if (k == 0) writeFillTransparency(); if (k == 1) writeStrokeTransparency(); addLine(bApplet.screenX(a + c, b + d / 2, 0) + " " + reflectedScreenY(a + c, b + d / 2, 0) + " m"); addLine(bApplet.screenX(a + c, b + d / 2 - .276143f * d, 0) + " " + reflectedScreenY(a + c, b + d / 2 - .276143f * d, 0) + " " + bApplet.screenX(a + c / 2 + .276143f * c, b, 0) + " " + reflectedScreenY(a + c / 2 + .276143f * c, b, 0) + " " + bApplet.screenX(a + c / 2, b, 0) + " " + reflectedScreenY(a + c / 2, b, 0) + " c"); addLine(bApplet.screenX(a + c / 2 - .276143f * c, b, 0) + " " + reflectedScreenY(a + c / 2 - .276143f * c, b, 0) + " " + bApplet.screenX(a, b + d / 2 - .276143f * d, 0) + " " + reflectedScreenY(a, b + d / 2 - .276143f * d, 0) + " " + bApplet.screenX(a, b + d / 2, 0) + " " + reflectedScreenY(a, b + d / 2, 0) + " c "); addLine(bApplet.screenX(a, b + d / 2 + .276143f * d, 0) + " " + reflectedScreenY(a, b + d / 2 + .276143f * d, 0) + " " + bApplet.screenX(a + c / 2 - .276143f * c, b + d, 0) + " " + reflectedScreenY(a + c / 2 - .276143f * c, b + d, 0) + " " + bApplet.screenX(a + c / 2, b + d, 0) + " " + reflectedScreenY(a + c / 2, b + d, 0) + " c"); addLine(bApplet.screenX(a + c / 2 + .276143f * c, b + d, 0) + " " + reflectedScreenY(a + c / 2 + .276143f * c, b + d, 0) + " " + bApplet.screenX(a + c, b + d / 2 + .276143f * d, 0) + " " + reflectedScreenY(a + c, b + d / 2 + .276143f * d, 0) + " " + bApplet.screenX(a + c, b + d / 2, 0) + " " + reflectedScreenY(a + c, b + d / 2, 0) + " c"); if (transparency) { if (solid()) { addLine(strokeFillTagClosed); break; } if (k == 0 && bApplet.g._fill) addLine("f"); if (k == 1 && bApplet.g._stroke) addLine("s"); if (!bApplet.g._stroke || !bApplet.g._fill) break; if (!bApplet.g._stroke && !bApplet.g._fill) { addLine("n"); break; } } if (!transparency) { addLine(strokeFillTagClosed); break; } } if (transparency && bApplet.g._stroke && bApplet.g._fill && !solid()) endGroup(); } } void ai_rectMode(int mode) { currentRectMode = mode; bApplet.rectMode(mode); } void ai_rect(float a, float b, float c, float d) { bApplet.rect(a, b, c, d); if (stage == WRITING) { if (currentRectMode == BConstants.CENTER_DIAMETER) { a -= c / 2; b -= d / 2; } if (currentRectMode == BConstants.CORNERS) { c -= a; d -= b; } writeQuad( a, b, 0, a+c, b, 0, a+c, b+d, 0, a, b+d, 0 ); } } void ai_bezier(float ax1, float ay1, float cx1, float cy1, float cx2, float cy2, float ax2, float ay2) { bApplet.bezier(ax1, ay1, cx1, cy1, cx2, cy2, ax2, ay2); if (stage == WRITING) { writeStrokeTransparency(); addLine(bApplet.screenX(ax1, ay1, 0) + " " + reflectedScreenY(ax1, ay1, 0) + " m"); addLine(bApplet.screenX(cx1, cy1, 0) + " " + reflectedScreenY(cx1, cy1, 0) + " " + bApplet.screenX(cx2, cy2, 0) + " " + reflectedScreenY(cx2, cy2, 0) + " " + bApplet.screenX(ax2, ay2, 0) + " " + reflectedScreenY(ax2, ay2, 0) + " c"); if (bApplet.g._stroke) { addLine("S"); } else { addLine("N"); } } } void ai_box(float s) { ai_box(s, s, s); } void ai_box(float x, float y, float z) { bApplet.box(x, y, z); if (stage == WRITING) { float[][] corners = new float[8][3]; int[][] faces = { { 0, 1, 3, 2}, { 2, 3, 7, 6}, { 6, 7, 5, 4}, { 0, 1, 5, 4}, { 1, 5, 7, 3}, { 0, 4, 6, 2}}; int p = 0; for (float a = -1; a <= 1; a += 2) { for (float b = -1; b <= 1; b += 2) { for (float c = -1; c <= 1; c += 2) { corners[p][0] = a * (x / 2.0f); corners[p][1] = b * (y / 2.0f); corners[p][2] = c * (z / 2.0f); p++; } } } beginGroup(); for (int i = 0; i < 6; i++) { writeQuad( corners[faces[i][0]][0], corners[faces[i][0]][1], corners[faces[i][0]][2], corners[faces[i][1]][0], corners[faces[i][1]][1], corners[faces[i][1]][2], corners[faces[i][2]][0], corners[faces[i][2]][1], corners[faces[i][2]][2], corners[faces[i][3]][0], corners[faces[i][3]][1], corners[faces[i][3]][2] ); } endGroup(); } } private void writeVertex( float x, float y, float z, String tag ){ if( stage == WRITING ) addLine(bApplet.screenX(x, y, z) + " " + reflectedScreenY(x, y, z) + " " + tag ); } int vertexCount = 0; void ai_beginShape(int mode) { bApplet.beginShape(mode); if( vertices == null ) for( int i=0;i<4;i++ ) for( int j=0;j<3;j++ ) vertices[i][j] = 0; vertexCount = 0; if (stage == WRITING) { currentShapeMode = mode; shapeStage = 0; firstBezierCurve = true; bezierCurves = false; if ((currentShapeMode == BConstants.LINE_STRIP || currentShapeMode == BConstants.LINE_LOOP) || (currentShapeMode == BConstants.TRIANGLE_STRIP || currentShapeMode == BConstants.QUAD_STRIP)) beginGroup(); if (transparency && currentShapeMode == BConstants.POLYGON ){ if (bApplet.g._fill) writeFillTransparency(); else writeStrokeTransparency(); } } } void ai_endShape() { bApplet.endShape(); if( vertexCount == 0 ){ shapeStage = 0; firstBezierCurve = true; bezierCurves = false; return; } vertexCount = 0; if (stage == WRITING) { firstBezierCurve = true; if (!bezierCurves) { if( currentShapeMode == BConstants.LINE_STRIP ) endGroup(); if( currentShapeMode == BConstants.LINE_LOOP ){ writeLine( vertices[0][0], vertices[0][1], vertices[0][2], shapeFirstVertex[0], shapeFirstVertex[1], shapeFirstVertex[2] ); endGroup(); } if (currentShapeMode == BConstants.TRIANGLE_STRIP || currentShapeMode == BConstants.QUAD_STRIP) endGroup(); if( currentShapeMode == BConstants.POLYGON ){ writeVertex(shapeFirstVertex[0], shapeFirstVertex[1], shapeFirstVertex[2], "L"); addLine(strokeFillTagClosed); } } if (bezierCurves) { if (currentShapeMode == BConstants.LINE_STRIP) { if (bApplet.g._stroke) addLine("S"); } if (currentShapeMode == BConstants.LINE_LOOP) { addLine(bezierStart[0] + " " + bezierStart[1] + " L"); if (bApplet.g._stroke) addLine("s"); } if (currentShapeMode == BConstants.POLYGON) { addLine(bezierStart[0] + " " + bezierStart[1] + " L"); addLine(strokeFillTagClosed); } bezierCurves = false; } } } float[][] vertices = new float[4][3]; private void writeLine( float x1, float y1, float z1, float x2, float y2, float z2 ){ if (stage == WRITING) { writeStrokeTransparency(); writeVertex( x1, y1, z1, "m" ); writeVertex( x2, y2, z2, "L" ); if (bApplet.g._stroke) { addLine("S"); } else { addLine("N"); } } } private void writeTri( float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3 ){ if (stage == WRITING) { if (transparency && bApplet.g._stroke && bApplet.g._fill && !solid()) beginGroup(); for (int k = 0; k <= 1; k++) { if (!bApplet.g._fill && bApplet.g._stroke) k++; if (k == 0) writeFillTransparency(); if (k == 1) writeStrokeTransparency(); writeVertex( x1, y1, z1, "m" ); writeVertex( x2, y2, z2, "L" ); writeVertex( x3, y3, z3, "L" ); writeVertex( x1, y1, z1, "L" ); if (transparency) { if (solid()) { addLine(strokeFillTagClosed); break; } if (k == 0 && bApplet.g._fill) addLine("f"); if (k == 1 && bApplet.g._stroke) addLine("s"); if (!bApplet.g._stroke || !bApplet.g._fill) break; if (!bApplet.g._stroke && !bApplet.g._fill) { addLine("n"); break; } } if (!transparency) { addLine(strokeFillTagClosed); break; } } if (transparency && bApplet.g._stroke && bApplet.g._fill && !solid()) endGroup(); } } private void writeQuad( float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4 ){ if (stage == WRITING) { if (transparency && bApplet.g._stroke && bApplet.g._fill && !solid()) beginGroup(); for (int k = 0; k <= 1; k++) { if (!bApplet.g._fill && bApplet.g._stroke) k++; if (k == 0) writeFillTransparency(); if (k == 1) writeStrokeTransparency(); writeVertex( x1, y1, z1, "m" ); writeVertex( x2, y2, z2, "L" ); writeVertex( x3, y3, z3, "L" ); writeVertex( x4, y4, z4, "L" ); writeVertex( x1, y1, z1, "L" ); if (transparency) { if (solid()) { addLine(strokeFillTagClosed); break; } if (k == 0 && bApplet.g._fill) addLine("f"); if (k == 1 && bApplet.g._stroke) addLine("s"); if (!bApplet.g._stroke || !bApplet.g._fill) break; if (!bApplet.g._stroke && !bApplet.g._fill) { addLine("n"); break; } } if (!transparency) { addLine(strokeFillTagClosed); break; } } if (transparency && bApplet.g._stroke && bApplet.g._fill && !solid()) endGroup(); } } private void shiftVertices(){ for( int i=0;i<3;i++ ) { vertices[0][i] = vertices[1][i]; vertices[1][i] = vertices[2][i]; vertices[2][i] = vertices[3][i]; } } void ai_vertex(float x, float y) { ai_vertex(x, y, 0); } void ai_vertex(float x, float y, float z) { if( z==0 ) bApplet.vertex(x, y); else bApplet.vertex(x, y, z); vertexCount++; if (stage == WRITING) { if (currentShapeMode == BConstants.POINTS) { ai_point(x, y, z); return; } vertices[ shapeStage ][0] = x; vertices[ shapeStage ][1] = y; vertices[ shapeStage ][2] = z; if (shapeStage == 0) { shapeFirstVertex[0] = x; shapeFirstVertex[1] = y; shapeFirstVertex[2] = z; } shapeStage++; if( shapeStage == 1 && currentShapeMode == BConstants.POLYGON ) writeVertex(x, y, z, "m"); if( shapeStage > 1 && currentShapeMode == BConstants.POLYGON ){ writeVertex(x, y, z, "L"); shapeStage = 2; } if( shapeStage == 2 && (currentShapeMode == BConstants.LINE_STRIP || currentShapeMode == BConstants.LINE_LOOP )){ writeLine( vertices[0][0], vertices[0][1], vertices[0][2], vertices[1][0], vertices[1][1], vertices[1][2] ); shiftVertices(); shapeStage = 1; } if( shapeStage == 2 && currentShapeMode == BConstants.LINES ){ writeLine( vertices[0][0], vertices[0][1], vertices[0][2], vertices[1][0], vertices[1][1], vertices[1][2] ); shapeStage = 0; } if( shapeStage == 3 && currentShapeMode == BConstants.TRIANGLES ){ writeTri( vertices[0][0], vertices[0][1], vertices[0][2], vertices[1][0], vertices[1][1], vertices[1][2], vertices[2][0], vertices[2][1], vertices[2][2] ); shapeStage = 0; } if( shapeStage == 4 && currentShapeMode == BConstants.QUADS ){ writeQuad( vertices[0][0], vertices[0][1], vertices[0][2], vertices[1][0], vertices[1][1], vertices[1][2], vertices[2][0], vertices[2][1], vertices[2][2], vertices[3][0], vertices[3][1], vertices[3][2] ); shapeStage = 0; } if( shapeStage == 3 && currentShapeMode == BConstants.TRIANGLE_STRIP ){ writeTri( vertices[0][0], vertices[0][1], vertices[0][2], vertices[1][0], vertices[1][1], vertices[1][2], vertices[2][0], vertices[2][1], vertices[2][2] ); shiftVertices(); shapeStage = 2; } if( shapeStage == 4 && currentShapeMode == BConstants.QUAD_STRIP ){ writeQuad( vertices[0][0], vertices[0][1], vertices[0][2], vertices[1][0], vertices[1][1], vertices[1][2], vertices[2][0], vertices[2][1], vertices[2][2], vertices[3][0], vertices[3][1], vertices[3][2] ); shiftVertices(); shiftVertices(); shapeStage = 2; } } } float bezierCoordinates[][] = new float[4][2]; float bezierStart[] = new float[2]; boolean firstBezierCurve = true; boolean bezierCurves = false; void ai_bezierVertex(float x1, float y1) { ai_bezierVertex(x1, y1, 0); } void ai_bezierVertex(float x1, float y1, float z1) { bApplet.bezierVertex(x1, y1, z1); vertexCount++; if (stage == WRITING) { bezierCoordinates[shapeStage][0] = bApplet.screenX(x1, y1, z1); bezierCoordinates[shapeStage][1] = reflectedScreenY(x1, y1, z1); if (!bezierCurves) { bezierStart[0] = bezierCoordinates[0][0]; bezierStart[1] = bezierCoordinates[0][1]; bezierCurves = true; } if (shapeStage == 3) { if (firstBezierCurve) { addLine(bezierCoordinates[0][0] + " " + bezierCoordinates[0][1] + " m"); firstBezierCurve = false; } else { addLine(bezierCoordinates[0][0] + " " + bezierCoordinates[0][1] + " L"); } addLine(bezierCoordinates[1][0] + " " + bezierCoordinates[1][1] + " " + bezierCoordinates[2][0] + " " + bezierCoordinates[2][1] + " " + bezierCoordinates[3][0] + " " + bezierCoordinates[3][1] + " c"); shapeStage = -1; } shapeStage++; } } }
Assignment: Convergence: Create two drawings, derived from the same algorithm, using your experience from Exercise D and G, Drawing/Gesture and Multiples.