//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.