//***************************************************************************** // Road editor, Jarek Rossignac, Nov 2006 //***************************************************************************** float back=0; // laplace back move int recp = 3; // recursion level int rec = 5; // recursion level int vn =4; // number of control vertices int svn =vn; // number of new vertices int cap=64; // size of control arrays int scap=cap*4096; // size of derived array pt[] P = new pt [cap]; // control points pt[] SP = new pt [scap]; // derived points pt[] LP = new pt [scap]; // derived LEFT points pt[] RP = new pt [scap]; // derived RIGHT points float[] r = new float [cap]; // radius of control points float[] sr = new float [scap]; // radius of subdivided points int bi=-1; // index of selected mouse-vertex, -1 if none selected boolean radius=false; // true when radius is being edited boolean fillDisks=true; // togle to fill disks or not boolean showControlCurve=true; boolean showCircles=false; boolean showMedian=true; boolean fillRoad=true; boolean showHats=false; boolean showLines=false; boolean showArcs=true; boolean showDistance=false; pt Mouse = new pt(0,0); // current mouse position vec Vlabel=new vec(10,10); // vector for labels // COLORS color soft = color(200, 200, 210); color red = color(200, 10, 10); color blue = color(10, 10, 200); color green = color(0, 150, 0); color black = color(10, 10, 10); color magenta = color(250, 150, 200); color brown = color(100, 50, 20); color yellow = color(250, 245, 130); color metal = color(50, 150, 200); color orange = color(200, 150, 50); boolean numbers = false; // toggles display of vertex numberss void setup() { size(800, 800); // strokeJoin(ROUND); strokeCap(ROUND); PFont font = loadFont("Courier-14.vlw"); textFont(font, 12); for (int i=0; irmax) rmax=sr[i]; for(float d=rmax; d>=0; d-=rmax/levels) { fill(250-100*((rmax-d)/rmax),245-100*((rmax-d)/rmax),130-100*((rmax-d)/rmax)); drawSmallCircles(d,rmax/levels); }; noFill(); }; void showLabels() { for (int i=0; ir+e) SP[i].show(r*2); else SP[i].show(sr[i]*2); }; void drawControlCircles() {for (int i=0; i10) { // if closest vertex is too far bd=600; // reinitilize distance squared for (int i=0; ibi; i--) {P[i+1].setFromPt(P[i]); r[i+1]=r[i];}; // shift down the rest bi++; P[bi].setFromMouse(); vn++; r[bi]=(r[ip(bi)]+r[in(bi)])/2; // insert new vertex at mouse position r[bi]+=(r[bi]-(r[ip(ip(bi))]+r[in(in(bi))])/2)/3; println("inserted disk "+bi); } else {bi=-1;}; // nothing selected }; }; } float d2(int j) {return (Mouse.disTo(P[j]));}; // squared distance from mouse to vertex P[j] float dm(int j) {return (Mouse.disTo(average(P[j],P[in(j)])));}; // squared distance from mouse to mid-edge point void mouseReleased() { // do this when mouse released if ( (bi!=-1) && P[bi].isOut() ) { // if outside of port for (int i=bi; irec) {recp=rec;}; println("recp = "+recp); }; if (key==',') {recp--; if (recp<0) {recp=0;}; println("recp = "+recp); }; if (key=='>') {rec++; if (rec>11) {rec=11;}; println("rec = "+rec); }; if (key=='<') {rec--; if (rec<0) {rec=0;}; println("rec = "+rec); }; if (key=='N') {numbers=!numbers;}; if (key=='F') {fillDisks=!fillDisks;}; if (key==' ') {showControlCurve=!showControlCurve;}; if (key=='c') {showCircles=!showCircles ;}; if (key=='m') {showMedian=!showMedian ;}; if (key=='f') {fillRoad=!fillRoad ;}; if (key=='h') {showHats =!showHats;}; if (key=='l') {showLines=!showLines ;}; if (key=='d') {showDistance=!showDistance;}; if (key=='a') {showArcs =!showArcs;}; if (key=='W') {savePts();}; if (key=='R') {loadPts();}; if (key=='I') { saveFrame("pix-####.tif");}; if (key=='A') { // axis aligns the edges for (int i=0; iabs(P[in(i)].y-P[i].y)) {float dy=(P[in(i)].y-P[i].y)/2; P[in(i)].y-=dy; P[i].y+=dy;} else {float dx=(P[in(i)].x-P[i].x)/2; P[in(i)].x-=dx; P[i].x+=dx;} }; }; if (key=='C') { float sx=width; float sy=height; float bx=0.0; float by=0.0; for (int i=0; ibx) {bx=P[i].x;}; if (P[i].xby) {by=P[i].y;}; if (P[i].y