// Polygon editor, Jarek Rossignac, June 2005 int count =4; // number of control vertices int cap=128; // size of control arrays int gr=4; // number of recursions int pts=count*round(pow(2,gr)); float Px = 0.0; float Py = 0.0; // current mouse position int bi=-1; // index of selected vertex, -1 if none selected float[] x = new float [cap]; float[] y = new float [cap]; int [] locked = new int [cap]; int [] vlocked = new int [cap*64]; float[] vx = new float [cap*64]; float[] vy = new float [cap*64]; float[] area = new float [cap*64]; // area changes float s=0.3, t=0.5; // parameter for smoothing and subdivision int menuWidth=200; // width of menu column int preserve=1; // restore nothing, area, perimeter int paste=0; // tracking translation, rotation, scaling color black = color(0, 0, 0); color red = color(200, 0, 0); color green = color(0, 100, 0); color grey = color(180, 180, 180); color blue = color(0, 0, 200); color yellow = color(250, 250, 130); color brown = color(150, 100, 50); color orange = color(250, 200, 150); int nov = 4; // number of original vertices int method=10; int showDots=1; float[] ox = new float [cap*round(pow(2,7))]; float[] oy = new float [cap*round(pow(2,7))]; float[] ax = new float [cap*round(pow(2,7))]; float[] ay = new float [cap*round(pow(2,7))]; float[] atx = new float [cap*round(pow(2,7))]; float[] aty = new float [cap*round(pow(2,7))]; float[] artx = new float [cap*round(pow(2,7))]; float[] arty = new float [cap*round(pow(2,7))]; float[] asrtx = new float [cap*round(pow(2,7))]; float[] asrty = new float [cap*round(pow(2,7))]; void setup() { size(600+menuWidth, 600); // window size PFont font = loadFont("Courier-14.vlw"); textFont(font, 12); strokeJoin(ROUND); strokeCap(ROUND); for (int i=0; i-1) {x[bi]=mouseX; y[bi]=mouseY;}; // snap selected vertex to mouse position during dragging switch(method) { case 7: QuadricBspline(); break; case 8: CubicBspline(); break; case 9: FourPoints(); break; case 10: Jarek(); break; case 11: VariableJarek(); break; case 12: LaplaceSmoothing(); break; case 13: biLaplaceSmoothing(); break; case 14: TaubinSmoothing(); break; case 15: LaplacePasting(); break; case 16: biLaplacePasting(); break; case 17: TaubinPasting(); break; }; drawCurve(); drawControl(); } void drawControl() { stroke(brown); strokeWeight(1.0); beginShape(LINE_STRIP); for (int i=0; ibx) {bx=x[i];}; if (x[i]by) {by=y[i];}; if (y[i]abs(y[n(i)]-y[i])) {float dy=(y[n(i)]-y[i])/2; y[n(i)]-=dy; y[i]+=dy;} else {float dx=(x[n(i)]-x[i])/2; x[n(i)]-=dx; x[i]+=dx;} }; }; if (key=='v') {println("Control polyloop has "+count+" points"); for (int i=0; i100) { // if closest vertex is too far bd=600*600; // reinitilize distance squared for (int i=0; ibi; i--) {x[i+1]=x[i]; y[i+1]=y[i]; }; // shift down the rest bi++; x[bi]=Px; y[bi]=Py; count++; // insert new vertex at mouse position }else {bi=-1;}; // nothing selected }; } void mouseReleased() { // do this when mouse released if ((bi!=-1) && ((x[bi]<0)||(x[bi]>600)||(y[bi]<0)||(y[bi]>600))) { // if outside of port for (int i=bi; i600)&&(mouseX<600+menuWidth)) { if ((mouseY>0)&&(mouseY<75)){ println("variable "); if ((mouseY>0)&&(mouseY<25)) {switch ((mouseX-600)*6/menuWidth) {case 0: s/=2; break; case 1: s-=0.1; break; case 4: s+=0.1; break; case 5: s*=2; break;};s=round(10*s)/10.0;}; if ((mouseY>25)&&(mouseY<50)) {switch ((mouseX-600)*6/menuWidth) {case 0: t/=2; break; case 1: t-=0.1; break; case 4: t+=0.1; break; case 5: t*=2; break;};t=round(10*t)/10.0;}; if ((mouseY>50)&&(mouseY<75)) {switch ((mouseX-600)*6/menuWidth) {case 0: gr/=2; break; case 1: gr--; break; case 4: gr++; break; case 5: gr*=2; break;};}; } else { print("choice "+(mouseY-75)/25+" : "); switch ((mouseY-75)/25) { case 0: loadControl(); println("Loaded "+count+" vertices"); break; case 1: replicate(); println("Replicate "+pts+" control points"); method=0; break; case 2: splitEdges(); println("Split producing "+pts+" vertices"); break; case 3: dual(); println("Dual "); break; case 4: kill(); println("Kill "); break; case 5: measure(); println("Measure "); break; case 6: println("Apply("+s+","+t+")"); break; case 7: method=7; println("Quadric Bspline "); break; case 8: method=8; println("Cubic Bspline "); break; case 9: method=9; println("Four Points "); break; case 10: method=10; println("Jarek("+s+")"); break; case 11: method=11; println("Variable Jarek "); break; case 12: method=12; println("Laplace smoothing"); break; case 13: method=13; println("bi-Laplace smoothing "); break; case 14: method=14; println("Taubin Smoothing ("+s+","+t+")"); break; case 15: method=15; println("Laplace Tracking"); break; case 16: method=16; println("BiLaplace Tracking "); break; case 17: method=17; println("Taubin Tracking ("+s+","+t+")"); break; case 18: print("Save "); switch ((mouseX-600)*5/menuWidth) {case 0: case 1: break; case 2: println("control"); saveControl(); break; case 3: println("derived"); saveDerived(); break; case 4: break;}; break; case 19: print("Preserve "); switch ((mouseX-600)*5/menuWidth) {case 0: case 1: break; case 2: print("nothing: "); preserve=0; break; case 3: print("area: "); preserve=1; break; case 4: print("perimeter: "); preserve=2; break;}; println(preserve); break; case 20: print("Paste "); switch ((mouseX-600)*5/menuWidth) {case 0: case 1: break; case 2: print("tranlsation: "); paste=0; break; case 3: print("rotation: "); paste=1; break; case 4: print("scaling: "); paste=2; break;}; println(paste); break; }; }; }; } void measure() { L(); L2(); saveL(); } void L() {for (int i=0; i0) {fill(green);} else {fill(red);}; rect(vx[i],vy[i],sqrt(abs(area[i])),sqrt(abs(area[i]))); }; }; void MA () { for (int i=0; i100.0) {ss=-2*aa/b2;} else {fill(red); ellipse(vx[i],vy[i],10.0,10.0);}; vx[i]+=-ss*by; vy[i]+=ss*bx; }; }; void loadControl() { String [] ss = loadStrings("loop.txt"); String subpts; int s=0; int comma; count = int(ss[s]); for(int i=0;i0){J(1.0);}; if (gr>1){J(0.0);}; if (gr>2){J(-1.0);} for (int i=3; i