// RINGS, Jarek Rossignac, April 03, 2008 boolean recursive=false; int ops=0; // operation counter boolean drawing=false; // pen up used to disable drawing during initialization (5 first moves) int _rec=7; // number of recursions and B-spline degree float _gs=1.5, _ga=-.63, _gb=-.63; // mixed J-spline subdivision parameters //float _gs=0, _ga=0, _gb=0; // mixed J-spline subdivision parameters int m=11; // max number of rings; pt[][] R = new pt[m][4]; // m rings of 4 points each int[] e = new int[m]; // index of rotating slot for inserting the next point in ring boolean[] f = new boolean[m]; // next point to be produced when pushing on ring is an F-point pt lP=new pt(); // last B-point to be drawn to finish curve void makeRings() {for (int r=0; r=_rec) {if(f[r]) f[r]=false; else if(drawing) {R[r][e[r]].v(); lP=R[r][n(e[r])]; }} // draw B-point on last ring and save the next F-point else {pt Q; float a=_gs; float b=_gs; if(r==0) {a=_ga; b=_gb;}; // set mixed J-spline parameters if(f[r]) Q=Pf(R[r][e[r]],R[r][n(e[r])],R[r][n(n(e[r]))],R[r][n(n(n(e[r])))],b); // compute four-point subdivision point else Q=Pb( R[r][n(e[r])],R[r][n(n(e[r]))],R[r][n(n(n(e[r])))],a); // compute B-spline subdivision point f[r]=!f[r]; // toggle which point to produce next loadRing(r+1,Q); pushRing(r+1); pushRing(r+1); } // load next ring and advance it twice } int n(int v){return (v+1)%4;} // next slot around the ring void showEdges(int r) {stroke(col.is(r)); int v=e[r]; beginShape(); for (int i=0; i<4; i++) {R[r][v].v(); v=n(v);}; endShape(); } void showPoints(int r) {stroke(col.is(r)); for (int v=0; v<4; v++) R[r][v].show(2);} void showRing(int r) {showEdges(r); showPoints(r); } void showRings() {for (int r=0; r<=_rec; r++) showRing(r); } void showRing() {showRing(_rec); } pt Ps(pt A, float s, pt B) {return(new pt(A.x+s*(B.x-A.x),A.y+s*(B.y-A.y))); }; pt Pb(pt A, pt B, pt C, float s) {ops++; return( s(s(B,s/4.,A),0.5,s(B,s/4.,C))); }; // returns a tucked B towards its neighbors pt Pf(pt A, pt B, pt C, pt D, float s) {ops++; return( s(s(A,1.+(1.-s)/8.,B) ,0.5, s(D,1.+(1.-s)/8.,C))); }; // returns a bulged mid-edge point Colors col = new Colors(5); void sub(pt[] P, int r, int s) { // Subdivides a polyloop and renders it int n=P.length; if (r<=0) {beginShape(); for (int i=2; i=_rec) {if(f[r]) f[r]=false; else if(drawing) {R[r][e[r]].v(); lP=R[r][n(e[r])]; }} // draw B-point on last ring and save the next F-point else {pt Q; float a=_gs; float b=_gs; if(r==0) {a=_ga; b=_gb;}; // set mixed J-spline parameters if(f[r]) Q=Pf(R[r][e[r]],R[r][n(e[r])],R[r][n(n(e[r]))],R[r][n(n(n(e[r])))],b); // compute four-point subdivision point else Q=Pb( R[r][n(e[r])],R[r][n(n(e[r]))],R[r][n(n(n(e[r])))],a); // compute B-spline subdivision point f[r]=!f[r]; // toggle which point to produce next loadRing(r+1,Q); } // load next ring and advance it twice }