/* * SONIC v.01 * * Diplomwahlfacharbeit für CAAD, ETH Zürich * Philipp Eversmann, Florian Poppele * * xx.07.2007 * * desc: TODO t, load/save -> rayList/reflected List nach RAYGENERATOR verschieben, mutate mit re. klick abbrechen * */ // VARS PROGRAMM Polygon ourNewPolygon = new Polygon(); // aktuelle Geometrie RayGenerator allRays; // Strahlenbild FitnessCalculator currFitnessCalc; // aktuelle Fitnessberechnung float currFitness; // aktuell angezeigter Fitnesswert GeometrySaver savedGeometries = new GeometrySaver(); // Speicherobjekt für Geometrie, Strahlenbild, Fitnesswert ArrayList rayList; // Endpunkte der Strahlen bzw. Startpunkte der reflektierten Strahlen ArrayList reflectedList; // Endpunkte der reflektierten Strahlen //ArrayList fitnessList = new ArrayList(); // berechnete Fitnesswerte float emitterX, emitterY; Vec emitterCenter = new Vec(0,0); int emitterRad = 5; // VARS PROGRAMMMODUS boolean drawPolyMode = true; boolean drawReflectionsMode = false; boolean drawMutationMode = false; // VARS MAUS boolean eOver = false; // Emitter MouseOver boolean eClicked = false; // Emitter angeklickt boolean eLocked = false; // Emitter kann nicht verschoben werden boolean ePlaced = false; // Emitter gesetzt boolean lOver = false; // boolean sOver = false; // Slider MouseOver boolean ptOver = false; // Punkt MouseOver boolean ptClicked = false; // Punkt angeklickt boolean ptLocked = false; // Punkt kann nicht verschoben werden boolean stopMutation = false; // boolean drag; // nach Drag(mouseRelease) float clickOffX = 0; float clickOffY = 0; int ptIndex; int snapRadius = 10; // VARS OUTPUT PFont font01; // für Anzeige Sliderwerte PFont font20; // für Beschreibung Anzeige PFont font30; // für Tooltips PFont font50; // für "sonic" Slider resolutionSlider = new Slider(225, 591, 85, 1, 20, 6); // Slider um Anzahl der Rays einstellen zu können // VARS FARBEN /*color cNormal1 = color(128, 255, 0); color cNormal2 = color(84, 168, 0);*/ color cHighlight1 = color(128, 255, 0); color cHighlight2 = color(84, 168, 0); color cTransp1 = color(255, 255, 255, 10); color cNormal1 = color(180); color cNormal2 = color(160); color cDark1 = color(130); color cDark2 = color(90); //color cNormal1 = color(220); //color cNormal2 = color(200); //color cDark1 = color(90); //color cDark2 = color(150); //color white = color(0); /*///////////////////////////////////////////////////////////// // SETUP // /////////////////////////////////////////////////////////////*/ void setup() { size(600, 600); // Fenstergröße font01 = loadFont("MarkeEigenbauNormal-8.vlw"); // Fonts laden font20 = loadFont("BrowalliaNew-Bold-20.vlw"); font30 = loadFont("BrowalliaNew-Bold-30.vlw"); font50 = loadFont("Bauhaus93-50.vlw"); ellipseMode(CENTER); background(0); } /*///////////////////////////////////////////////////////////// // DRAW // /////////////////////////////////////////////////////////////*/ void draw() // DRAW { //println("dRM "+ drawReflectionsMode+" dPM "+drawPolyMode); background(0); progName(); // Programmnamen ausgeben if (drawPolyMode == true) // Polygon zeichnen { progMsg("draw polygon"); showCoord(); ourNewPolygon.drawPoly(); // Polygonpunkte setzen } if (drawReflectionsMode == true) // Emitter setzen und Reflekionen zeichnen { if (ePlaced && eLocked) { allRays.raysDraw(); } // bei vorhandenem Emitter Strahlen zeichnen checkMouseOver(); // MouseOver kontrollieren showInfo(); // Fläche, Fitness anzeigen showCoord(); // Maus-Koordinaten anzeigen ourNewPolygon.drawPoly(); // fertiges Polygon zeichnen savedGeometries.showList(width-120, 10); // gespeicherte Geometrien anzeigen } if (drawMutationMode == true) // mutieren { Mutate m = new Mutate(); // DEBUG MAKE GLOBAL showInfo(); // Fläche, Fitness anzeigen m.mutatePoints (); allRays.raysDraw(); ourNewPolygon.drawPoly(); // fertiges Polygon zeichnen } } /* * Methode: drawEmitter() * Desc: * * Params: * * */ void drawEmitter(float xPos, float yPos) { stroke(cDark2); fill(cHighlight1); ellipse(xPos, yPos, emitterRad, emitterRad); } /* * Methode: * Desc: * * Params: * * */ void initDrawReflectionsMode() { drawReflectionsMode = true; // Schalter für Programmmodus emitterCenter = new Vec (emitterX, emitterY); allRays = new RayGenerator(emitterCenter, ourNewPolygon); // Strahlenbild berechnen currFitnessCalc = new FitnessCalculator(); // Fitness berechnen currFitness = currFitnessCalc.calculateFitness(); } /*///////////////////////////////////////////////////////////// // MOUSE EVENTS // /////////////////////////////////////////////////////////////*/ /* * Methode: * Desc: * * Params: * * */ void mouseClicked() { if (drawMutationMode == true) { if (stopMutation == false) { stopMutation = true; drawReflectionsMode = true; drawMutationMode = false; } } if (drawReflectionsMode == true) { if (mouseButton == LEFT) { if(!ePlaced) // Emitter wird gesetzt; wird nur einmal ausgeführt { ePlaced = true; // Emitter gesetzt eLocked = true; // Emitter wird gerade nicht verschoben //println("mouseClicked ePlaced"+ePlaced+" eLocked"+eLocked); emitterX = mouseX; emitterY = mouseY; drawEmitter(emitterX, emitterY); initDrawReflectionsMode(); } else if (ePlaced && eOver && eLocked) // bereits gesetzter Emitter wird verschoben { eClicked = true; eLocked = false; //println("clicked = true"); clickOffX = mouseX - emitterX; clickOffY = mouseY - emitterY; } else if (lOver) // Geometrie Speichern/Klick auf Schloss Icon { savedGeometries.saveToList(ourNewPolygon, allRays, currFitness); } if (ptOver) // Polygoneckpunkt wird verschoben { ptClicked = true; //println("mouseClicked "); } } if (mouseButton == RIGHT) { drawMutationMode = true; drawReflectionsMode = false; } } if (drawPolyMode == true) { if (mouseButton == LEFT) { //println("mouseClicked1() ePlaced"+ePlaced); ourNewPolygon.addPoint(mouseX, mouseY); } if (mouseButton == RIGHT) // RECHTER BUTTON { ourNewPolygon.closePoly(); // Polygon schliessen drawPolyMode = false; // Beendigung Zeichenmodus drawReflectionsMode = true; // Beginn Strahlenausgabemodus } } } /* * Methode: mouseDragged() * Desc: verschiebt Emitters bzw. Polygonpunkt bei Drag * * Params: - * */ void mouseDragged() // Verhalten bei MouseDrag { //println("DRAG"+ptClicked); int snapDist = 10; //println("DRAG C"+eClicked+" L"+eLocked+" O"+eOver); if ((drawReflectionsMode == true) && eLocked && eOver) // DRAG EMITTER { emitterX = mouseX - clickOffX; emitterY = mouseY - clickOffY; //println("HELLLOOOO"); //setEmitterMode = false; emitterCenter = new Vec (emitterX, emitterY); allRays.Origin = emitterCenter; allRays.calculateRays(emitterCenter, ourNewPolygon); // Strahlenbild neu berechnen //println("POINTS: "+allRays.intersectPoints.size()); drag = true; } if (ptOver) // DRAG POLYGONPUNKT { //println("mouseDragged ptClicked"+ptClicked); ourNewPolygon.movePoint(mouseX, mouseY, ptIndex); // Polygonpunkt verschieben allRays.calculateRays(emitterCenter, ourNewPolygon); // Strahlenbild neu berechnen drag = true; } if (sOver) // DRAG SLIDER { resolutionSlider.dragSlider(); } } /* * Methode: mouseReleased() * Desc: Variablen werden nach Click/Drag zurückgesetzt * * Params: - * */ void mouseReleased() { if (drawReflectionsMode == true) { //if (eClicked = true) { eClicked = false; } if (drag) { currFitnessCalc = new FitnessCalculator(); currFitness = currFitnessCalc.calculateFitness(); drag = false; } //ptClicked = false; //ptOver = false; } } /* * Methode: checkMouseOver() * Desc: MouseOver Status von Emitter und Polygon werden überwacht * Emitter wird gezeichnet * Programmmeldungen werden ausgegeben * * Params: - * */ void checkMouseOver() { if (ePlaced) // MOUSEOVER EMITTER { float distMouseCircle = sqrt( sq(emitterX-mouseX) + sq(emitterY-mouseY) ); // Distanz Cursor-Emitter if (distMouseCircle <= snapRadius) // liegt MouseOver vor? { eOver = true; progMsg("drag emitter"); cursor(HAND); strokeWeight(3); // Emitter hervorheben if(!eClicked) { stroke(cDark2); fill(cHighlight1); ellipse(emitterX, emitterY, 2*emitterRad, 2*emitterRad); } } else // kein MouseOver { eOver = false; //println("NOT Over emitter"); stroke(cNormal2); fill(cNormal2); ellipse(emitterX, emitterY, emitterRad, emitterRad); } strokeWeight(1); } else if (!ePlaced) // Emitter nicht gesetzt, "klebt" am Mauszeiger { drawEmitter(mouseX, mouseY); progMsg("set emitter"); } // MOUSEOVER POLYGON int i = 0; // Counter für Schleife boolean ptFound = false; // Abbruchbedingung für Schleife while ((i <= ourNewPolygon.polyPoints.size()-1) && (ptFound == false)) { float ptDist = sqrt( sq(ourNewPolygon.getPt(i).getX()-mouseX) + sq(ourNewPolygon.getPt(i).getY()-mouseY) ); if (ptDist <= snapRadius) { ptFound = true; ptOver = true; ptIndex = i; //println("over pt"+i+" "+ptOver); strokeWeight(3); // gefundenen Eckpunkt hervorheben stroke(cHighlight1); noFill(); ellipse(ourNewPolygon.getPt(i).getX(), ourNewPolygon.getPt(i).getY(), 10, 10); cursor(HAND); strokeWeight(1); // auf Standard zurücksetzen progMsg("drag polypoint"); } else { ptOver = false; } i++; } if (ePlaced && (mouseX >= 396) && (mouseX <=406) && (mouseY <= height-5) && (mouseY >= height-15))// MOUSEOVER SCHLOSS { lOver = true; drawLock(!lOver); progMsg("save geometry"); } else if (ePlaced) { lOver = false; drawLock(!lOver); } if (ePlaced) // MOUSEOVER SLIDER { if (resolutionSlider.drawSlider()) // MouseOver Check in der Klasse { sOver = true; cursor(HAND); progMsg("change ray resolution"); } else { sOver = false; } } if (!ptOver && !eOver && !lOver && !sOver){ cursor(ARROW); } // NO MOUSEOVER AT ALL } /*///////////////////////////////////////////////////////////// // PROGRAM MESSAGES // /////////////////////////////////////////////////////////////*/ /* * Methode: progName() * Desc: gibt Programmnamen links unten aus * * Params: * */ void progName() { textFont(font50, 50); fill(40); textAlign(LEFT); text("sonic", 10, height-5); } /* * Methode: progMsg(String msg) * Desc: gibt Programmhinweise rechts unten aus * * Params: * msg - auszugebender Text * */ void progMsg(String msg) { textFont(font30, 30); fill(100); textAlign(RIGHT); text(msg, width-10, height-20); } /* * Methode: showInfo() * Desc: * * Params: - * */ void showInfo() { textFont(font20, 20); textAlign(LEFT); fill(cDark2); if (ePlaced) // nur bei gesetztem Emitter resolution, Fläche, Fitness ausgeben { if (!drawMutationMode) { text("ray resolution", 135, height-5); } text("aPoly", 325, height-5); text("fitness_", 410, height-5); fill(cDark1); text(round(ourNewPolygon.areaPoly()/1000), 362, height-5); // Polygonfläche text(nf(currFitness, 2, 3), 455, height-5); // Fitnesswert } } /* * Methode: showCoord() * Desc: gibt aktuelle Cursor Koordinaten rechts unten aus * * Params: - * */ void showCoord() { textFont(font20, 20); textAlign(RIGHT); fill(cDark1); text(nf(mouseX, 3), width-50, height-5); text(nf(mouseY, 3), width-10, height-5); fill(cDark2); text(" x_", width-70, height-5); text(" y_", width-30, height-5); } /* * Methode: drawLock(boolean open) * Desc: zeichnet ein geöffnetes oder geschlossenes Schloss-Icon * * Params: * open - gibt an ob das Schloss offen oder geschlossen ist */ void drawLock(boolean open) { smooth(); int lockWidth = 5; int lowerLeftCornerX = 396; int lowerLeftCornerY = height-9; noStroke(); if (open) // geöffnetes Schloss zeichnen { fill(cNormal1); rectMode(CORNER); rect(lowerLeftCornerX+lockWidth, lowerLeftCornerY, lockWidth, lockWidth-1); ellipseMode(CENTER); ellipse(lowerLeftCornerX+4, lowerLeftCornerY-1.5, 4, 5); fill(0); ellipse(lowerLeftCornerX+4, lowerLeftCornerY-1.5, 1, 3); fill(0); rect(lowerLeftCornerX, lowerLeftCornerY, lockWidth, lockWidth-1); } else // geschlossenes Schloss zeichnen { fill(cHighlight1); rectMode(CORNER); rect(lowerLeftCornerX+lockWidth, lowerLeftCornerY, lockWidth, lockWidth-1); ellipseMode(CENTER); ellipse(lowerLeftCornerX+lockWidth*1.5, lowerLeftCornerY-1.5, 4, 5); fill(0); ellipse(lowerLeftCornerX+lockWidth*1.5, lowerLeftCornerY-1.5, 1, 3); } noSmooth(); stroke(1); }