//***************************************************************************** // CURVE TWEENING, Jarek Rossignac, March, 2008 //***************************************************************************** void showHelp() { fill(yellow,40); rect(0,0,height,height); pushMatrix(); translate(20,20); fill(dgreen); text("Jarek Rossignac's Geometry Sand Box: Tweener (2008)",0,0); translate(0,20); text("Experimental environment for exploring tweening strategies between key curves",0,0); translate(0,20); text("Beware: Not debugged, not optimized, not engineered for commercial use!",0,0); translate(0,20); fill(dblue); translate(0,20); text("Click in window to activate it, press SPACE to show/hide this text and '~' to show/hide the menu (on the right)",0,0); translate(0,20); text("Use scrolls (top of menu) to adjust numeric values: .:resets, -/+:increment, large step",0,0); translate(0,20); text("Press buttons (bottom of menu) to toggle states (green means ON) or to perform actions",0,0); translate(0,20); text("In the explanations below, * means 'click', *~ means 'click-and-drag'. k*~ means keep 'k' pressed and drag",0,0); translate(0,20); text("",0,0); translate(0,20); text("EDITING CURVE C (which may be used to copy, edit, and replace keys)",0,0); translate(0,20); text(" press n=0...9 to load key n into C, edit C, u:update key, SHIFT+m to upload C as key m",0,0); translate(0,20); text(" g:guess C using from original input keys, G:guess C from resampled keys",0,0); translate(0,20); text(" c:recenter, t:turn, z:zoom, x:both, F:filter, B:bulge, C:coarsen, S:sample",0,0); translate(0,20); text(" =:makeSquare, ]:frame C in window, +:alignEdgesWithAxes, .:showIDs",0,0); translate(0,20); text(" to edit points on C: *~:pick&drag vertetx, i*~:insert, d*:delete",0,0); translate(0,20); text("To create sharp corners: enable 'trimming' and draw self-crossing curves",0,0); translate(0,20);// text("To create silhouettes (T-junctions): enable 'trimming' and increase 'silhouette fraction'",0,0); translate(0,20); text("",0,0); translate(0,20); text("",0,0); translate(0,20); text("When running Processing locally",0,0); translate(0,20); text(" A:archive curve",0,0); translate(0,20); text(" X:to snap a picture (it will be saved ias data/Pnm/frameXXX.tif, where XXX is incremented from 000).",0,0); translate(0,20); popMatrix(); noFill(); } // STATE VARIABLES boolean // states toggled in menu throughEnds=true, // add ends before ringing showEnds=false, // show dummy ends for refinement showVertexIds=true, // show vertex IDs 0, 1, ... showVertices=true, // show vertices of current curve showCurve=true, // show current curve showPoints=false, // show captured points of current curve showKeys=false, // shows captured keys with IDs: orange and R,G,B around current showRings=false, // shows captured keys with IDs: orange and R,G,B around current cubic=false, // use 4 key frames and catmul-rom to intrepolate dollies and vertices threeSegments=false, // use curl morphs (with 3 segments) curlMorph=false, // use curl morphs (instead of linear morph) spiralDolly=false, // use a spiral interpolation of dolly (instead of linear) dolly=false, // use a dolly and local coordinates for the morphs (linear, unless spiral selected) rings=true, // show result of ringing global=false, // show result of global refinements spans=false, // show result of per-span refinements triColor=false, // shows inbetween frames using 3 colors to try and create an illusion of motion showFrames=false, // shows inbetween frames playAnimation=false, // plays animation filming=false, // filming editingDollies=false, // show and edit dollies nudgingKey=false, // click and edit keys editingKeys=false, // click and edit keys enteringSelectedKey=false, // press digit and click&drag to enter selected key enteringConsecutiveKeys=false; // click&draw mode to enter consecutive keys boolean // states toggled by keys capturing=false; // in process of capturing a key int cc=0; // current key int // counts edited in menu _pixels = 3, // number of pixels separating captured points _filters = 5, // number of filtering steps performed on captured points _samples = 200, // number of samples generated along captured curve _subdivisions = 0, // number of subdivision steps performed to refine the captured resampled curve _segments = 5, // number of segments per Bezier curve used when rendering the curves in Camull-Rom form _frames = 1, // number of frames shown between keys _steps = 6; // number of steps in animations between keys float _fraction = 0, // initial fraction of each hidden loop shown (in 1/16) _weight = 100, // ratio between drawing speed and radius of disk shown _roi = 50; // distance to points affected by local filetering when pulling float vroi = _roi; // current _roi. Grows with time. buttons Buttons= new buttons(); // CREATE DIALS FOR EDITING VALUES void loadButtons() { // Buttons.add(new button("name",min,init,max,increment,fastIncrement)); Buttons.add(new button("a",-2,_ga,2,.125,.5)); Buttons.add(new button("b",-2,_gb,2,.125,.5)); Buttons.add(new button("s",-2,_gs,2,.125,.5)); Buttons.add(new button("levels",0,_rec,10,1,5)); } // CREATE BUTTONS FOR ACTIONS AND TOGGELS void loadToggles() { // ACTIONS Toggles.add(new toggle(" Make movie",false)); Toggles.add(new toggle(" Previous file number",false)); Toggles.add(new toggle(" Read next file",false)); Toggles.add(new toggle(" remove ends",false)); Toggles.add(new toggle(" add ends",false)); // STATE CHANGES Toggles.add(new toggle(" recursive",recursive)); Toggles.add(new toggle(" rings",rings)); Toggles.add(new toggle(" global",global)); Toggles.add(new toggle(" spans",spans)); Toggles.add(new toggle(" ",true)); Toggles.add(new toggle(" interpolate ends",throughEnds)); Toggles.add(new toggle(" show ends",showEnds)); Toggles.add(new toggle(" Show vertices",showVertices)); Toggles.add(new toggle(" Show curve",showCurve)); Toggles.add(new toggle(" Show points",showPoints)); Toggles.add(new toggle(" Show keys",showKeys)); } void mousePressed() { // process dials int k= Buttons.click(); int m=-1; if(k==++m) _ga=Buttons.v(m); if(k==++m) _gb=Buttons.v(m); if(k==++m) _gs=Buttons.v(m); if(k==++m) _rec=int(Buttons.v(m)); // PROCESS BUTTONS FOR ACTIONS AND STATE CHANGES (bottom-up order) k= Toggles.click(); m=-1; // process actions if(k==++m) {Toggles.B[m].V=false; filming=true; }; // start animation and make movie if(k==++m) {Toggles.B[m].V=false; loadP(); fn=(fn+maxfn)%(maxfn+1); }; if(k==++m) {Toggles.B[m].V=false; loadP(); fn=(fn+1)%(maxfn+1); if(fn| "+Format(V,4,4)+" = "+name,x,y+14); noFill(); }; boolean click() { if ( (x+i