/*═══════════════════════════════════════════════════════════════════════╕ │ Liège Openscad Library | │ Module de déformation et modification pour OpenSCAD │ ╞══════════════════╤════════════════════════════════════╤════════════════╡ │ marc@vanlindt.be │ LGPL 2.1 marc@vanlindt.be 2022 │ v0.98 ---- wip | ╞══════════════════╧═══════════════════════╤════════════╧════════════════╛ │ Variables générales / ╘═══════════════════════════════════════*/ LogoFB= [[4.46567, 4.99666], [3.06433, 4.99666], [3.06433, 0], [0.987666, 0], [0.987666, 4.99666], [0, 4.99666], [0, 6.76134], [0.987666, 6.76134], [0.987666, 7.90467], [1.00769, 8.22956], [1.07504, 8.57716], [1.20063, 8.92712], [1.39537, 9.25909], [1.6702, 9.55271], [2.03602, 9.78764], [2.50376, 9.94352], [3.08433, 10], [4.62167, 9.99402], [4.62167, 8.28068], [3.505, 8.28068], [3.35933, 8.26038], [3.21662, 8.18648], [3.10811, 8.0397], [3.065, 7.80073], [3.065, 6.76073], [4.64833, 6.76073]]; LetterL=[[0,0],[0,70],[22,73],[19,21],[50,25],[48,-1],[0,0]]; //LetterO=[[0,35],[6.25,61.25],[25,70],[25,70],[43.75,61.25],[50,35],[43.75,8.75],[25,0],[6.25,8.75],[0,35]]; LetterO=[[0,0],[0,70],[50,70],[50,0],[0,0]]; blue = [0,0,1,1]; red = [1,0,0,1]; green = [0,1,0,1]; violet = [0.5,0,0.5,1]; yellow = [1,1,0,1]; cyan = [0,1,1,1]; black = [0,0,0,1]; white = [1,1,1,1]; oak = RVB(200,50,90,255); orange = [1,0.5,0,1]; olive = [0.5,0.5,0,1]; sarcelle = [0,0.5,0.5,1]; marine = [0,0,0.5,1]; fuschia = [1,0,1,1]; glass = [1,0,1,0.2]; bleu = [0,0,1,1]; rouge = [1,0,0,1]; vert = [0,1,0,1]; jaune = [1,1,0,1]; noir = [0,0,0,1]; blanc = [1,1,1,1]; gris = [0.5,0.5,0.5,1]; gray = [0.5,0.5,0.5,1]; pink = RVB(255,107,219,255); phi = 1.61803399; aphi = phi-1; biphi = phi+1; angledor = 360/biphi; py = sqrt(0.5); bipy = sqrt(2); pi = 3.141592654; tau = pi*2; /*═══════════╕ │ Exemples \ ╘════════════*/ /* MOEBIUS / ELLIPSE moebius(n=32,d=40,t=0.5) ellipse([5,20],$fn=128); moebius(n=32,d=40,t=0.5) ellipse([20,5],$fn=128); */ /* CHULL chull(m=true){ sphere(d=1,$fn=64); translate([10,10,00]) sphere(d=1,$fn=16); translate([20,0,00]) sphere(d=1,$fn=16); translate([30,0,00]) sphere(d=1,$fn=16); translate([30,-10,00]) sphere(d=1,$fn=16); translate([0,-10,00]) sphere(d=1,$fn=16); } */ /* PYTHATREE / BONE*/ //pythatree(d="z",h=50,maxit=6,r1=30,r2=30) //bone(h=50,d1=20,d2=14.14214,c=40,$fn=64); /*pythatree(d="z",h=10*biphi,maxit=8,a=90,r1=90,r2=90) hull(){sphere(d=10,$fn=16); translate([0,0,10*biphi])sphere(d=10*aphi,$fn=16);} */ //pythatree(d="y",h=10,sp=5,maxit=8) //polygon(square([10,10],center=true)); /*pythatree(d="y",h=50,maxit=9,a=90,s=sqrt(0.5)) hull(){ circle(d=10,$fn=64); translate([0,50]) circle(d=sqrt(0.5)*10,$fn=64);} */ /**/ /* ROTATE2 rotate2() cube(center=true); translate([0,2,0]) cube(center=true); */ /* RING ring(d=10,n=11){ cylinder(d=1,h=5); translate([0,0,5.6]) scale([1,1,2]) sphere(d=0.6,$fn=64); } */ /* SKEW skew(YX=1) cube([2,2,2]); */ /* ROUNDSQUARE roundsquare(s=[40,20],d=[5,10,5,15],$fn=64,center=true); */ /* NGON ngon(d=20,fn=3,inside=true); translate([0,0,-1]) #cylinder(d=20,$fn=64); translate([25,0,0]) ngon(d=20,fn=3,inside=false); translate([25,0,-1]) #cylinder(d=20,$fn=64); translate([50,0,0])ngon(d=20,f=4,inside=true); translate([50,0,-1])#cylinder(d=20,$fn=64); translate([75,0,0])ngon(d=20,fn=4,inside=false); translate([75,0,-1])#cylinder(d=20,$fn=64); translate([100,0,0])ngon(d=20,fn=5,inside=true); translate([100,0,-1])#cylinder(d=20,$fn=64); translate([125,0,0])ngon(d=20,fn=5,inside=false); translate([125,0,-1])#cylinder(d=20,$fn=64); */ /* OUTLINE*/ /*outline(w=1,t="in"){ ellipse([10,20],fn=64);ellipse([20,10],fn=64);} translate([0,0,1]){#ellipse([10,20],fn=64);#ellipse([20,10],fn=64);} */ /* outline(w=1,t="out"){ ellipse([10,20],fn=64);ellipse([20,10],fn=64);} translate([0,0,1]){#ellipse([10,20],fn=64);#ellipse([20,10],fn=64);} */ /*outline(w=1,t="on"){ ellipse([10,20],fn=64);ellipse([20,10],fn=64);} translate([0,0,1]){#ellipse([10,20],fn=64);#ellipse([20,10],fn=64);} */ /**/ /* RANDOM for(i=[1:10]){ echo(random(10,s=i)); } */ /* FIBONACCI for(i=[1:15]){ echo(fibonacci(i)); } */ /* TEARDROP / RANDOM for(i=[1:500]){ translate([random(500,i*10),random(500,i*50),random(500,i*60)]) color([0.6,0.6,0.9,0.5])teardrop(a=30+random(30,i)); } */ /* STAR star(d1=10,d2=20,fn=9); */ /* TUBE - COUDE tube(d1=10,d2=8,h=15,$fn=64); translate([0,0,15]) coude(d1=10,d2=8,a=45,$fn=64); translate([0,0,20]) rotate([0,045,0]) translate([0,0,5]) tube(d1=10,d2=8,h=5,$fn=64); */ /* ROUNDCUBE roundcube(s=[50,100,150],b=[5,15,15,20],t=[25,35,40,5],$fn=64,center=true); */ /* PAIR for(i=[0:20]){ echo(str(i,pair(i)==true?" est pair!":" est impair!")); } */ /* GRID - CNC grid(s=[100,100],x=5,y=10,w=2) { cnc(0.5,$fn=32){ ellipse([2,1],$fn=32); ellipse([1,2],$fn=32); }} */ /* PIEPART piepart(d=10,p=20/100); rotate([0,0,360*21/100]) piepart(d=10,p=78/100); */ /* PIE pie(d=10,p=[1,2,1,2,1,2,3,2,1,3,2,1]); */ /* SUM echo(sum([5,10,15,20])); */ /* MYANGLE/length*/ /* CORRECT / CHULL rotate_extrude() rotate_extrude_correct() chull(){ circle(d=3); translate([60,0]) circle(d=3); translate([70,120]) circle(d=3); } */ /* FRACTSHAPE fractshape(d=40,fn=4,maxit=3); translate([40,0,0]) fractshape(d=40,fn=5,it=3); translate([80,0,0]) fractshape(d=40,fn=6,it=3); */ /* clean test=[[0,0],[0,0],[10,10],[10,10],[20,20],[20,20],[30,30],[30,30],[40,40],[40,40],[50,50],[50,50]]; echo(clean(test)); */ /* Kochflake for(i=[0:3]){ translate([i*10,0,0])kochflake(d=10,maxit=i);} */ /* Chaincurve / TRACE //points=[[0,0],[sin(30)*10,cos(30)*10],[10,0],[0,0]]; points=[[0,0],[0,10],[10,10],[20,0],[30,10],[40,20],[60,-20],[10,-10],[10,-5],[15,-5],[15,0],[0,0]]; color([0.4,1.0,0.4,1]) linear_extrude(1) polygon(chaincurve(points,8)); color("red") linear_extrude(3) trace(points,0.2); color([0.5,0.5,1,1]) linear_extrude(3) trace(chaincurve(points,8),0.1); */ /* difference(){ rotate2() cube([10,10,10],center=true); translate([0,0,10]) cube([20,20,20],center=true);} /* rotate2() cube([10,10,10],center=true); */ /*═══════════════════════════════╕ │ Modificateurs / déformations \ ╘════════════════════════════════*/ module outline (w,t){ w=w==undef?1:w; t=t==undef?"on":t; difference() { offset(t=="out"?w:t=="in"?0:w/2) children(); offset(t=="out"?0:t=="in"?-w:-w/2) children(); } } module pythatree (a,h,sp,maxit,b,r1,r2,s,d){ a = a == undef ? 45 : a; h = h == undef ? 1 : h; sp = sp == undef ? 0 : sp; maxit = maxit == undef ? 3 : maxit; b = b == undef ? 1 : b; r1 = r1 == undef ? 0 : r1; r2 = r2 == undef ? 0 : r2; s = s == undef ? py : s; d = d == undef ? "y" : d; children(); if(b<=maxit) { translate([d=="x"?h:d=="y"?sp:-sp, d=="x"?-sp:d=="y"?h:0, d=="x"?0:d=="y"?0:h]) rotate([d=="x"?0:d=="y"?r2:0, d=="x"?r2:d=="y"?0:-a, d=="x"?-a:d=="y"?-a:r2]) scale([s,s,s]) pythatree(a=a,h=h,sp=sp,maxit=maxit,b=b+1,r1=r1,r2=r2,s=s,d=d) { children(); }; translate([d=="x"?h:d=="y"?-sp:sp, d=="x"?sp:d=="y"?h:0, d=="x"?0:d=="y"?0:h]) rotate([d=="x"?0:d=="y"?r1:0, d=="x"?r1:d=="y"?0:a, d=="x"?a:d=="y"?a:r1]) scale([s,s,s]) pythatree(a=a,h=h,sp=sp,maxit=maxit,b=b+1,r1=r1,r2=r2,s=s,d=d) { children(); }; } } module chull (m){ union() for(i=[0:$children-2]){ hull(){ children(m==true?0:i); children(i+1); } } } module rotate2 (){ rotate([45,90-atan(sqrt(2)),0]) children(); } module ring (d,n){ d=d==undef?10:d; n=n==undef?5:n; for(i=[0:n-1]){ rotate([0,0,360/n*i]){ translate([d/2,0,0]) children(); } } } module fibo (s,n,r){ r=r==undef?true:r; s=s==undef?1:s; n=n==undef?128:n; for(i=[1:n]){ rotate([0,0,angledor*i]) translate([s*i,0,0]) scale(r==true?s+pow(1.003,i):1) children(); } } module skew (XY,XZ,YX,YZ,ZX,ZY){ matrice=[ [1,XY,XZ,0], //[redimX, skewXY, skewXZ,translateX] [YX,1,YZ,0], //[SkewYX,RedimY,SkewYZ,translateY] [ZX,ZY,1,0] //[SkewZX, SkewZY,redimZ,TranslateZ] ]; multmatrix(matrice){ children(); } } module cnc(d,show,fn){ show=show==undef?false:show; d = d == undef ? 3:d; fn = fn == undef ? 32:fn; if(show==false){ offset(-d/2,$fn=fn) offset(d/2,$fn=fn) children(); } else { color("green") linear_extrude(1) children(); color("red") linear_extrude(0.5) difference() { offset(-d/2,$fn=fn) offset(d/2,$fn=fn) children(); children(); } } } module moebius(d,t,fn){ // version 2.0 fn = fn == undef ? 128 :fn; d = d == undef ? 30 :d; t = t == undef ? 0.5 :t; union(){ for(j=[0:$children-1]) { for(i=[1:fn]){ hull(){ rotate([0,360/fn*i,0]) translate([d/2,0,0]) rotate([0,0,i*(360*t)/fn]) linear_extrude(0.1) children(j); rotate([0,360/fn*(i+1),0]) translate([d/2,0,0]) rotate([0,0,(i+1)*(360*t)/fn]) linear_extrude(0.1) children(j); } } } } } module grid (dim,x,y){ dim=dim==undef?[100,100]:dim; x=x==undef?10:x; y=y==undef?10:y; for(i=[1:x-1]) translate([i*dim[0]/x,0,0]) rotate([-90,0,0]) linear_extrude(dim[1]) children(); for(i=[1:y-1]) translate([0,i*dim[1]/y,0]) rotate([-90,0,-90]) linear_extrude(dim[0]) children(); } module rotate_extrude_correct (){ difference(){ children(); translate([-100000,-50000]) square([100000,100000]); } } /*═══════════════════╕ │ Nouvelles formes \ ╞══════╤═══════════════╛ │ 2D │ ╘═════*/ module teardrop (d,a,fn){ polygon(teardrop(d=d==undef?10:d,a=a==undef?30:a,fn=fn==undef?16:fn)); } module star (d1,d2,fn){ polygon(star(d1=d1==undef?10:d1,d2=d2==undef?20:d2,fn=fn==undef?7:fn)); } module ellipse (dim,fn){ polygon(ellipse(dim,fn)); } module losange (dim){ polygon(losange(dim)); } module roundsquare (table,d,fn){ polygon(roundsquare(s=table,d=d,fn=fn)); } module kochflake (d,maxit){ polygon ( koch ( ngon(d=d,fn=3), maxit=maxit ) ); } module ngon (d,fn,inside){ polygon(ngon(d,fn,inside)); } module piepart (d,a,p){ polygon(piepart(d=d,a=a,p=p)); } module triangle (w,h){ polygon(triangle(w=w,h=h)); } module fractshape (d,fn,inside,maxit){ polygon(fractshape(fn=fn,d=d,maxit=maxit,inside=inside)); } module lghs (){ for(i=[-1:2:1]) { rotate([0,0,i*45]){ translate([0,-50,0]) difference(){ cnc(10) union(){ hull(){ circle(d=20); translate([0,100,0]) circle(d=15); } translate([0,100,0]) circle(d=50); } hull(){ translate([0,150,0]) rotate([0,0,30]) circle(d=25,$fn=6); translate([0,110,0]) rotate([0,0,30]) circle(d=25,$fn=6); } circle(d=10); } } } } module trace(table,d,fn,dot,dotfn,tr,d2){ tr=tr==undef?true:tr; fn=fn==undef?8:dot==true?4:fn; dotfn=dotfn==undef?16:dotfn; dot=dot==undef?true:dot; d=d==undef?1:d; d2=d2==undef?d*2:d2; for(i=[0:len(table)-2]){ if(tr==true) { hull(){ translate(table[i]) circle(d=d,$fn=fn); translate(table[i+1]) circle(d=d,$fn=fn); } } if(dot==true){ translate(table[i]) circle(d=d2,$fn=dotfn);} if(dot==true){ translate(table[i+1]) circle(d=d2,$fn=dotfn);} } } module voronoi(dim, w, t, c, n,seed){ n=n==undef?100:n; dim=dim==undef?[1000,500]:dim; table=pointgrid([dim[0],dim[1]],n=n,seed=seed); c=c==undef?0:c; t=table[0][0]+table[0][1]; w=w==undef?1:w; seed=seed==undef?1/fn*n*c/w:seed; outline(w=w*2,t="in") square(dim); difference(){ square(dim); cnc(-c/2) for (p=table){ intersection_for(p2=table){ if (p!=p2){ translate((p+p2)/2 -normal(p2-p)*w){ rotate([0,0,-myangle(p,p2)]) translate([-t,-t]) square([2*t, t]); }}}}}} /*════════╕ │ 2D/3D │ ╘════════*/ /*═════╕ │ 3D │ ╘═════*/ module tube (d1,d2,h,center){ d1=d1==undef?10:d1; d2=d2==undef?8:d2; h=h==undef?30:h; center=center==undef?false:center; translate([0,0,center==true?-h/2:0]) difference(){ cylinder(d=d1,h=h); translate([0,0,-1]) cylinder(d=d2,h=h+2); } } module coude (d1,d2,a){ d1=d1==undef?10:d1; d2=d2==undef?8:d2; a=a==undef?90:a<=-90?-90:a>=90?90:a; difference(){ union(){ cylinder(d=d1,h=d1/2); translate([0,0,d1/2]) sphere(d=d1); translate([0,0,d1/2]) rotate([0,a,0]) cylinder(d=d1,h=d1/2); } union(){ translate([0,0,-1]) cylinder(d=d2,h=d1/2+1); translate([0,0,d1/2]) sphere(d=d2); translate([0,0,d1/2]) rotate([0,a,0]) cylinder(d=d2,h=d1/2+1); } } } module roundcube (s,b,t,center,q){ s=s==undef?[50,40,30]:s; b=b==undef?[5,5,5,5]:b; t=t==undef?[20,20,20,20]:t; q=q==undef?16:q; center=center==undef?false:center; translate([center==true?-s[0]/2:0,center==true?-s[1]/2:0,center==true?-s[2]/2:0]) hull(){ translate([b[0]/2,b[0]/2,b[0]/2]) sphere(d=b[0],$fn=q); translate([s[0]-b[1]/2,b[1]/2,b[1]/2]) sphere(d=b[1],$fn=q); translate([s[0]-b[2]/2,s[1]-b[2]/2,b[2]/2]) sphere(d=b[2],$fn=q); translate([b[3]/2,s[1]-b[3]/2,b[3]/2]) sphere(d=b[3],$fn=q); translate([t[0]/2,t[0]/2,s[2]-t[0]/2]) sphere(d=t[0],$fn=q); translate([s[0]-t[1]/2,t[1]/2,s[2]-t[1]/2]) sphere(d=t[1],$fn=q); translate([s[0]-t[2]/2,s[1]-t[2]/2,s[2]-t[2]/2]) sphere(d=t[2],$fn=q); translate([t[3]/2,s[1]-t[3]/2,s[2]-t[3]/2]) sphere(d=t[3],$fn=q); } } module bone (h,d1,d2,c,q){ h = h == undef ? 50 : h; d1 = d1 == undef ? 20 : d1; d2 = d2 == undef ? 14.14214 : d2; c = c == undef ? 40 : c; q = q == undef ? 128 : q; rotate_extrude(){ rotate_extrude_correct(){ cnc((c)*1,fn=q) { translate([0,h,0]) circle(d=d2,$fn=q); translate([0,0]) circle(d=d1,$fn=q); } } } } module rock(d,c,seed){ c=c==undef?3:c; seed=seed==undef?1:seed; intersection_for(i=[0:c]){ a=[random(360,s=i*seed),random(360,s=i*seed*2),random(360,s=i*seed*3)]; rotate(a) cube([d,d,d*10],center=true); } } module pie (d,p,pct,i=1,a=0){ pct=topct(p); echo(pct); rotate([0,0,a*360]) linear_extrude(i) piepart(d=d,p=p[i-1]/sum(p)+0.01); if(i<len(p)){ pie(d=d,p=p,i=i+1,a=a+pct[i-1]); } } /*══════════════════════╕ │ Nouvelles fonctions \ ╞═══════════════════╤════╛ │ Sur nombres (a) │ ╘══════════════════*/ function random (n,s,pos) = rands(pos==undef?0:pos==true?0:-n,n,1,s==undef?n:s)[0]; function fibonacci (n,a=0,b=1,c=1) = c<n+1?fibonacci(a=b,b=a+b,c=c+1,n=n):a; function hypo (a,b) = sqrt((a*a)+(b*b)); function real (a,b,c) = ((a*a)+(b*b))+c; function imaginary (a,b,c) = (2*a*b)+c; function pair (a) = a%2==0?true:false; function normal (a) = a/(sqrt(a[0]*a[0]+a[1]*a[1])); /*═════════════════════════╕ │ Sur tables [a,b,c, ...] │ ╘═════════════════════════*/ function sum (a,b=0,c=0,n) = b<(n==undef?len(a):n)?sum(a=a,b=b+1,c=c+a[b],n=n):c; function topct (a) = a/sum(a); function moyenne (a,b=0,c=0) = b<len(a)?sum(a=a,b=b+1,c=c+a[b])/len(a):c; function invert (a) = let(b=[for(i=[0:len(a)-1]) a[(len(a)-1)-i]])b; function sort (a,invert=false) = len(a) == 0 ? [] : let ( b=floor(len(a)/2), c=[for(i=a) if (i<a[b]) i], d=[for(i=a) if (i>a[b]) i], e=[for(i=a) if (i==a[b]) i] ) invert==false?concat(sort(c),e,sort(d)):invert(concat(sort(c),e,sort(d))); /*════════════════════════════╕ │ Sur vecteurs [[a,b],[c,d]] │ ╘════════════════════════════*/ function length (a,b) = sqrt(((b[0]-a[0])*(b[0]-a[0]))+((b[1]-a[1])*(b[1]-a[1]))); function divide (a,b,c) = [a[0]+(b[0]-a[0])*c, a[1]+(b[1]-a[1])*c]; function myangle (a,b) = atan2(b[0]-a[0],b[1]-a[1]); function join (a,c=0,t=[]) = let (u=concat(t,a[c]))c==len(a)?t:join(a=a,c=c+1,t=u); // NIGHTLY BUILDS ONLY function join2(aa) = [for(i=[0:len(aa)-1] ) each aa[i]]; function clean(a) = [for(i=[0:len(a)-1]) each (a[i]==a[i+1]?"":a[i][0]==undef?"":[a[i]])]; function koch (a,angle,maxit,it) = let( a=a[0]==a[len(a)-1]?a:concat(a,[a[0]]), b = [ for ( i = [ 0 : len(a)-2 ] ) [ a[i], divide(a[i],a[i+1],1/3), divide(a[i],a[i+1],1/3) + [ sin(myangle(a[i],a[i+1])-(angle==undef?60:angle<=60?60:angle>=180?180:angle))*length(a[i], a[i+1])/3, cos(myangle(a[i],a[i+1])-(angle==undef?60:angle<=60?60:angle>=180?180:angle))*length(a[i],a[i+1])/3], divide(a[i],a[i+1],2/3)+[sin(-90+myangle(a[i],a[i+1])-((90+(90-(angle<=60?60:angle>=180?180:angle)))))*length(a[i],a[i+1])/3,cos(-90+myangle(a[i],a[i+1])-(90+(90-(angle<=60?60:angle>=180?180:angle))))*length(a[i],a[i+1])/3], divide(a[i],a[i+1],2/3), a[i+1] ]], maxit=maxit==undef?0:maxit, it=it==undef?0:it ) it==maxit?clean(join2(b)):koch(a=clean(join2(b)),angle=angle,maxit=maxit,it=it+1); function fract(a,angle,in,maxit,it,close)= let( close=close==undef?true:close, a=close==true?a[0]==a[len(a)-1]?a:concat(a,[a[0]]):a, maxit=maxit==undef?3:maxit==0?1:maxit, it=it==undef?0:it, inside=in==undef?1:in==true?1:-1, angle=angle==undef?60:angle, b = [ for ( i = [ 0 : len(a)-2 ] ) [ a[i], divide(a[i],a[i+1],angle/180), divide(a[i],a[i+1],angle/180) + [ sin(myangle(a[i],a[i+1]) + angle*inside) * (length(a[i],a[i+1])/3) , cos(myangle(a[i],a[i+1]) + angle*inside) * (length(a[i],a[i+1])/3) ], divide(a[i],a[i+1],1-(angle/180)), a[i+1]] ] ) it+1==maxit?clean(join2(b)):fract(a=clean(join2(b)),angle=angle,in=in,maxit=maxit,it=it+1,close=close); /* function fract (a,angle,in,maxit,it) = let( a=a[0]==a[len(a)-1]?a:concat(a,[a[0]]), maxit=maxit==undef?3:maxit==0?1:maxit, it=it==undef?0:it, angle=angle==undef?60:angle, b = [ for ( i = [ 0 : len(a)-2 ] ) [ a[i], divide(a[i],a[i+1],angle/180), divide(a[i],a[i+1],1/2) + [ sin(myangle(a[i],a[i+1]) + (in==false?-90:90)) * (length(a[i],a[i+1])/3) , cos(myangle(a[i],a[i+1]) + (in==false?-90:90)) * (length(a[i],a[i+1])/3) ], divide(a[i],a[i+1],1-(angle/180)), a[i+1]] ] ) it+1==maxit?clean(join2(b)):fract(a=clean(join2(b)),angle=angle,in=in,maxit=maxit,it=it+1); */ function curve(table,fn) = let( fn = fn == undef ? 8 : fn, c = [ for ( i = [0:(fn)] ) each [divide(table[0],table[1],1/(fn)*i)]], d = [ for ( i = [0:(fn)] ) each [divide(table[1],table[2],1/(fn)*i)]], e = [ for ( i = [0:(fn)] ) each [divide(c[i],d[i],1/(fn)*i)]]) e; function doublevector(table,f,it=0) = let( f=f==undef?0:f, aa = [for (i=[0:len(table)-1]) each [table[i],divide(table[i],table[i+1],0.5)]] ) it==f?clean(aa):doublevector(clean(aa),f=f,it=it+1); function ngon(d,fn,inside) = let ( d=d==undef?10:inside==undef?d:inside==true?d:d*((d/2)/(cos(360/fn/2)*d/2)), fn=fn==undef?4:fn, aa=[for(i=[0:fn])[sin(360/fn*i)*d/2,cos(360/fn*i)*d/2]] ) aa; function square(d,center)=let( center=center==undef?false:center, d=d==undef?[10,10]:d, c1 = center == true ? [-d[0]/2,-d[1]/2] : [ 0, 0], c2 = center == true ? [-d[0]/2, d[1]/2] : [ 0, d[1]], c3 = center == true ? [ d[0]/2, d[1]/2] : [ d[0], d[1]], c4 = center == true ? [ d[0]/2,-d[1]/2] : [ d[0], 0], aa=[c1,c2,c3,c4,c1] ) aa; function ellipse(s,fn) = let ( fn=fn==undef?16:fn, s=s==undef?[10,10*aphi]:s, aa=[for(i =[0:fn] ) [sin(360/fn*i)*s[0]/2,cos(360/fn*i)*s[1]/2]] ) aa; function losange(s) = let ( s=s==undef?[10,10*aphi]:s, aa=[for(i =[0:4] ) [sin(360/fn*i)*s[0]/2,cos(360/fn*i)*s[1]/2]] ) aa; function circle(d,r,fn) = let ( fn=fn==undef?16:fn, r=r==undef?d==undef?5:d/2:r, aa=ngon(d=r*2,fn=fn) ) aa; function star(d1,d2,fn) = let ( d1=d1==undef?10:d1/2, d2=d2==undef?5:d2/2, fn=fn==undef?7:fn, aa=[for(i=[0:2*(fn)])[sin(360/(2*fn)*i)*(pair(i)==true?d1:d2),cos(360/(2*fn)*i)*(pair(i)==true?d1:d2)]] ) aa; function roundsquare(s,d,fn) = let ( fn = fn == undef ? 8:fn, s = s == undef ? [15,20] : s, d = d == undef ? [3,6,3,6] : len(d) == 1 ? [d[0]/2,d[0]/2,d[0]/2,d[0]/2]:len(d)==2?[d[0]/2,d[1]/2,d[1]/2,d[1]/2]:len(d)==3?[d[0]/2,d[1]/2,d[2]/2,d[2]/2]:d[0]==undef?[d/2,d/2,d/2,d/2]:d/2, p1 = [0,0], p2 = [0,d[0]], p3 = [0,s[1]-d[1]], p4 = [0,s[1]], p5 = [d[1],s[1]], p6 = [s[0]-d[2],s[1]], p7 = [s[0],s[1]], p8 = [s[0],s[1]-d[2]], p9= [s[0],d[3]], p10= [s[0],0], p11= [s[0]-d[3],0], p12= [d[0],0], c1=curve([p3,p4,p5],fn=fn), c2=curve([p6,p7,p8],fn=fn), c3=curve([p9,p10,p11],fn=fn), c4=curve([p12,p1,p2],fn=fn), aa=clean(join2([c1,c2,c3,c4,[p3]])) ) aa; function piepart(d,a,p) = let ( d=d==undef?10:d/2, a=a==undef?p==undef?90:p>=1?360*1/p:360*p:a, aa=concat([[0,0]],[for(i=[0:a])[-sin(-90+i)*d,cos(-90+i)*d]]) ) aa; function triangle(w,h)= let ( h=h==undef?cos(30)*w:h, aa=[[-w/2,0],[0,h],[w/2,0],[-w/2,0]] ) aa; function fractshape(d,fn,inside,maxit)= let( d=d==undef?10:d/2, fn=fn==undef?5:fn, maxit=maxit==undef?3:maxit, inside=inside==undef?true:inside, angle=fn==3?60:fn==4?89:360/fn, points=fract(ngon(d=d*2,fn=fn),maxit=maxit,angle=angle,in=inside) ) points; function teardrop(d,a,fn)=let ( d=d==undef?10:d, a=a==undef?30:a, h=d*tan(90-a), fn=fn==undef?16:fn, courbe= [for(i=[0:fn]) [sin(90-a+(360-(90-a)*2)/fn*i)*d/2,cos(90-a+(360-(90-a)*2)/fn*i)*d/2]], aa=concat(courbe,[[0,(cos(90-a)*d/2)+h*sin(90-a)/2]],[[sin(90-a)*d/2,cos(90-a)*d/2]]) ) aa; function fractalize(table,force,maxit,seed)= let ( force=force==undef?1:force, maxit=maxit==undef?3:maxit, seed=seed==undef?1:seed, aa= [ for(i=[0:len(table)-2], ab = doublevector([[table[i][0],table[i][1]],[table[i+1][0],table[i+1][1]]],maxit=maxit)) for(j=ab[0]) each clean([[ab][0],[ab][1]]+[[(random(pos=false,n=force,s=sin(seed)*sin(ab[0])+sin(ab[1]))),(random(pos=false,n=force,s=cos(seed)*cos(ab[0])-sin(ab[1])))],[(random(n=force,s=tan(seed)+sin(ab[0])+2*cos(ab[1]))),(random(n=force,s=cos(seed)+cos(ab[0])-3*cos(ab[1])))]]) ] ) clean(aa); function pointgrid(dim,n,seed) =[for(i=[0:n-1])[random(n=dim[0],s=sin(i/n/(seed==undef?1:seed))),random(n=dim[1],s=cos(i*2/n/(seed==undef?1:seed)))]]; function rescale(a,s) = [for (i=a) i*s]; function retranslate(a,t) = [for (i=a) i+t]; function 2Drot(object,angle) = [for(i=[0:len(object)-1]) [sin(myangle([0,0],object[i])+angle)*length([0,0],object[i]),cos(myangle([0,0],object[i])+angle)*length([0,0],object[i])]]; function to3D(a,b,h,bottom,top) = let ( bottom=bottom==undef?true:bottom, top=top==undef?true:top, aa=[ for(i=[0:len(a)]) each[[a[i][0],a[i][1],0],[b[i][0],b[i][1],h]] ], bb=[ for(i=[0:1:len(aa)]) each [[i,i+1,i+2],[i+1,i+3,i+2]] ], cc=bottom==true?[ for(i=[0:2:len(aa)]) each [i] ]:[], // dd=top==true?[ for(i=[0:2:len(aa)]) each [len(aa)-1-i] ]:[], dd=top==true?[ for(i=[0:2:len(aa)]) each [len(aa)-1-i] ]:[], ee=concat(bb,[cc],[dd]) ) [clean(aa),clean(ee)]; function simple3D(a,b,h,bottom,top,angle,correct) = let ( angle=angle==undef?0:angle, correct=correct==undef?0:correct, bottom=true, top=true, c=2Drot(interpolate(a,b,maxstep=1,step=0,correct=correct,q=1),angle), d=2Drot(interpolate(a,b,maxstep=1,step=1,correct=correct,q=1),angle), aa=[ for(i=[0:len(c)]) each[[c[i][0],c[i][1],0],[d[i][0],d[i][1],h]] ], bb=[ for(i=[0:1:len(aa)]) each [[i,i+1,i+2],[i+1,i+3,i+2]] ], cc=bottom==true?[ for(i=[0:2:len(aa)]) each [i] ]:[], dd=top==true?[ for(i=[0:2:len(aa)]) each [len(aa)-1-i] ]:[], ee=concat(bb,[cc],[dd]) ) [clean(aa),clean(ee)]; function vectranslate(a,n,it)=let( n=n==undef?0:n, it=it==undef?0:it, aa=n==0?a:[for(i=[0:len(a)-1]) i==0?a[len(a)-2]:a[i-1]] ) it==n+len(a)-2?aa:vectranslate(a=aa,n=n,it=it+1); module 2Dto3D(a,b,h,segment,correct,quality,rotation){ angle=rotation==undef?0:rotation/segment; quality=quality==undef?1:quality; he=h==undef?64:h; mm=segment==undef?16:segment; aabc=a==undef?ngon(d=50,fn=3):a; adef=b==undef?chaincurve(koch(ngon(d=50,fn=3),maxit=1),fn=4):b; correct=correct==undef?0:correct; union(){ for(i=[0:mm-1]){ my3Dobject=to3D( 2Drot(interpolate(aabc,adef,maxstep=mm,step=i,correct=correct,q=quality),i*angle), 2Drot(interpolate(aabc,adef,maxstep=mm,step=i+1,correct=correct,q=quality),(i+1)*angle), h=he/mm, top=i==mm-1?true:true, bottom=i==0?true:true); translate([0,0,i*he/mm]) color([1/mm*i,1-(1/mm*i),1,1]) union() { polyhedron(my3Dobject[0],my3Dobject[1]); polyhedron(my3Dobject[0],my3Dobject[1]); } } } } function interpolate(a,b,step,maxstep,correct,q)= let( pp=ppcm(len(a)-1,len(b)-1,q)-[1,1], correct=correct==undef?0:correct, abc=vectranslate(multiplyfaces(a,pp[0]),n=correct==undef?0:correct), def=multiplyfaces(b,pp[1]), aa=[for(i=[0:len(def)]) each [divide(abc[i],def[i],step/(maxstep))]]) clean(aa); function ppcm(a,b,q)=let( aa=[for(i=[0:max(a,b)]) each [i*a*(q==undef?1:q)]], bb=[for(i=[0:max(a,b)]) each [i*b*(q==undef?1:q)]], cc=[for(i=[0:max(a,b)]) each [for(j=[1:100]) each aa[i]==bb[j]?bb[j]:""]]) [cc[0]/a,cc[0]/b]; function multiplyfaces(object,n)=let( n=n==undef?1:n==0?0:n, aa=n==0?object:[for(i=[0:len(object)-2]) each addpoints(object[i],object[i+1],n) ]) concat(clean(aa),[object[0]]); function addpoints(c1,c2,n)=[for(i=[0:n]) each [divide(c1,c2,i/(n+1))]]; function chaincurve(table,fn,closed,detail) = let ( detail=detail==undef?1:detail==0?1:detail*sign(detail)*2+1, closed=closed==undef?true:closed, // table=table[0]==table[len(table)-1]?table:concat([for(i=[0:len(table)]) table[i]],table[len(table)-1]), //totaltab=table, totaltab=concat(table,[table[0]],closed==true?[table[1]]:"",closed==true?[table[2]]:""), tab = multiplyfaces(totaltab,detail), d = [for (i=[(closed==true?4:2):2:len(tab)-(closed==false?4:2)]) each curve([tab[(i)-1],tab[i],tab[i+1]],fn)], b =table[0], c = table[len(table)-1], a = d ) clean(a); function RVB(a,b,c,d)= let( a=a==undef?0.5:1/255*a, b=b==undef?0.5:1/255*b, c=c==undef?0.5:1/255*c, d=d==undef?1:1/255*d, aa=[a,b,c,d] )aa; function mirror(a,x,y)=let( xx=x==undef?1:x==true?-1:1, yy=y==undef?1:y==true?-1:1, aa=[ for(i=[0:len(a)-1]) each [ [a[i][0]*xx,a[i][1]*yy] ] ] )aa; function center(a,center)=let( LMax=sort([for(i=[0:len(a)-1])a[i][0]])[0], LMin=sort([for(i=[0:len(a)-1])a[i][0]],invert=true)[0], HMax=sort([for(i=[0:len(a)-1])a[i][1]])[0], HMin=sort([for(i=[0:len(a)-1])a[i][1]],invert=true)[0], LargMax=LMax*sign(LMax), LargMin=LMin*sign(LMin), HautMax=HMax*sign(HMax), HautMin=HMin*sign(HMin), Largeur=LargMax<=LargMin?LargMin-LargMax:LargMax-LargMin, Hauteur=HautMax<=HautMin?HautMin-HautMax:HautMax-HautMin, aa=retranslate(a,[-LMax-(center==false?0:Largeur/2),-HMax-(center==false?0:Hauteur/2)]) )aa; function offset(a,d,i)= let ( invert=i==undef?false:true, aa=mesangles(a), mesangles=orientangles(aa), bb=[ for(i=[0:len(a)-2]) each [[a[i][0]+sin(90-mesangles[i])*d,a[i][1]+cos(90-mesangles[i])*d]] ] ) concat(bb,[bb[0]]); function mesangles(a,invert)=let ( invert=invert==undef?false:true, aa=[ for(i=[0:len(a)-2]) let( a1=(invert==false?90:-90)-myangle(a[i],a[i==len(a)-2?0:i+1]), a2=(invert==false?90:-90)-myangle(a[i],a[i==0?len(a)-2:i-1]), aa1=(invert==false?90:-90)-myangle(a[i],a[i==len(a)-2?0:i+1]), aa2=(invert==false?90:-90)-myangle(a[i],a[i==0?len(a)-2:i-1]), a3=(a1+a2)/2+180, aaa=aa[i-1] ) a3 ] ) aa; function orientangles(a,i)= let ( i=i==undef?0:i, aa=[ for(j=[0:len(a)-1]) each (a[j]-a[j-1])>=90?a[j]-180:(a[j]-a[j-1])<=-90?a[j]+180:a[j]] ) i==len(a)-1?aa:orientangles(a=aa,i=i+1); function coeffdirect(a)=let //coefficient directeur ( aa=(a[1][1]-a[0][1])/(a[1][0]-a[0][0]) ) aa; /* Dans un plan cartésien, on peut trouver les coordonnées du point d’intersection de deux courbes (comme par exemple deux droites) en résolvant le système d’équations. Soit les droites dont les équations sont y = x – 4 et y = –2x + 5, alors : x – 4 = –2x + 5. On représente ces droites dans un plan cartésien. Donc : 3x = 9 et x = 3 Puis : y = –1 Les coordonnées du point d’intersection de ces droites sont (3, –1). */ module 2D(a){ polygon(a); } module 3D(a){ if(a[1]!=undef) { polyhedron(a[0],a[1]); } } function cube(d,center)=let ( d=d==undef?[10,10,10]:d, center=center==undef?false:center, mys=square([d[0],d[1]],center=center), aa=to3D(mys,mys,h=d[2]) ) center==false?aa:translate3D(aa,[0,0,-d[2]/2]); function cylinder(d,d1,d2,h,fn,center)=let ( d1=d==undef?d1==undef?10:d1:d, d2=d==undef?d2==undef?10:d2:d, h=h==undef?40:h, fn=fn==undef?16:fn, center=center==undef?false:center, myg1=ngon(d=d1,fn=fn), myg2=ngon(d=d2,fn=fn), aa=to3D(myg1,myg2,h=h) ) center==false?aa:translate3D(aa,[0,0,-h/2]); function translate3D(a,b)=[[for(i=[0:len(a[0])-1]) a[0][i]+b],a[1]]; function rescale3D(a,s)= [[for(i=[0:len(a[0])-1]) a[0][i]*s],a[1]]; function gradient(a,b,c) = let ( c=c==undef?1:c, aR=a[0], aV=a[1], aB=a[2], aA=a[3], bR=b[0], bV=b[1], bB=b[2], bA=b[3], mR=(aR-bR)/c, mV=(aV-bV)/c, mB=(aB-bB)/c, mA=(aA-bA)/c, aa=[for(i=[0:c-1]) [a[0]-mR*i,a[1]-mV*i,a[2]-mB*i,a[3]-mA*i]] ) aa; module menger(d,maxit,it){ let(it=it==undef?0:it) if(it==maxit){ square([d,d]); } else{ union(){ menger(d=d/3+0.001,maxit=maxit,it=it+1); translate([d/3,0]) menger(d=d/3+0.001,maxit=maxit,it=it+1); translate([d/3*2,0]) menger(d=d/3+0.001,maxit=maxit,it=it+1); translate([0,d/3]) menger(d=d/3+0.001,maxit=maxit,it=it+1); translate([d/3*2,d/3]) menger(d=d/3+0.001,maxit=maxit,it=it+1); translate([0,d/3*2]) menger(d=d/3+0.001,maxit=maxit,it=it+1); translate([d/3,d/3*2]) menger(d=d/3+0.001,maxit=maxit,it=it+1); translate([d/3*2,d/3*2]) menger(d=d/3+0.001,maxit=maxit,it=it+1); }}} module menger3d(it,d,maxit){ it=it==undef?1:it; if (it==maxit){ cube([d,d,d],center=true); } if (it<=maxit){ union(){ for (i=[-1:1]){ translate([d/3,d/3,d/3*i]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); translate([-d/3,d/3,d/3*i]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); } translate([0,d/3,d/3]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); translate([0,d/3,-d/3]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); for (i=[-1:1]){ translate([d/3,-d/3,d/3*i]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); translate([-d/3,-d/3,d/3*i]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); } translate([0,-d/3,d/3]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); translate([0,-d/3,-d/3]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); translate([d/3,0,d/3]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); translate([d/3,0,-d/3]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); translate([-d/3,0,d/3]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); translate([-d/3,0,-d/3]) rotate([0,90,0]) menger3d(it=it+1,d=d*1/3,maxit=maxit); }}} module jcube(it,d,maxit){ it=it==undef?1:it; union() { if(it==maxit) { cube([d,d,d],center=true); } if(it<=maxit) { translate([d/2,d/2,d/2]) translate([-d/2*(sqrt(2)-1),-d/2*(sqrt(2)-1),-d/2*(sqrt(2)-1)]) jcube(it=it+1,maxit=maxit,d=d*(sqrt(2)-1)); translate([-d/2,d/2,d/2]) translate([d/2*(sqrt(2)-1),-d/2*(sqrt(2)-1),-d/2*(sqrt(2)-1)]) jcube(it=it+1,maxit=maxit,d=d*(sqrt(2)-1)); translate([d/2,-d/2,d/2]) translate([-d/2*(sqrt(2)-1),d/2*(sqrt(2)-1),-d/2*(sqrt(2)-1)]) jcube(it=it+1,maxit=maxit,d=d*(sqrt(2)-1)); translate([-d/2,-d/2,d/2]) translate([d/2*(sqrt(2)-1),d/2*(sqrt(2)-1),-d/2*(sqrt(2)-1)]) jcube(it=it+1,maxit=maxit,d=d*(sqrt(2)-1)); translate([d/2,d/2,-d/2]) translate([-d/2*(sqrt(2)-1),-d/2*(sqrt(2)-1),d/2*(sqrt(2)-1)]) jcube(it=it+1,maxit=maxit,d=d*(sqrt(2)-1)); translate([-d/2,d/2,-d/2]) translate([d/2*(sqrt(2)-1),-d/2*(sqrt(2)-1),d/2*(sqrt(2)-1)]) jcube(it=it+1,maxit=maxit,d=d*(sqrt(2)-1)); translate([d/2,-d/2,-d/2]) translate([-d/2*(sqrt(2)-1),d/2*(sqrt(2)-1),d/2*(sqrt(2)-1)]) jcube(it=it+1,maxit=maxit,d=d*(sqrt(2)-1)); translate([-d/2,-d/2,-d/2]) translate([d/2*(sqrt(2)-1),d/2*(sqrt(2)-1),d/2*(sqrt(2)-1)]) jcube(it=it+1,maxit=maxit,d=d*(sqrt(2)-1)); translate([-d/2,-d/2,0]) translate([d/2*(1-(2*(sqrt(2)-1))),d/2*(1-(2*(sqrt(2)-1))),0]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([-d/2,d/2,0]) translate([d/2*(1-(2*(sqrt(2)-1))),-d/2*(1-(2*(sqrt(2)-1))),0]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([d/2,-d/2,0]) translate([-d/2*(1-(2*(sqrt(2)-1))),d/2*(1-(2*(sqrt(2)-1))),0]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([d/2,d/2,0]) translate([-d/2*(1-(2*(sqrt(2)-1))),-d/2*(1-(2*(sqrt(2)-1))),0]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([-d/2,0,-d/2]) translate([d/2*(1-(2*(sqrt(2)-1))),0,d/2*(1-(2*(sqrt(2)-1)))]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([-d/2,0,d/2]) translate([d/2*(1-(2*(sqrt(2)-1))),0,-d/2*(1-(2*(sqrt(2)-1)))]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([d/2,0,-d/2]) translate([-d/2*(1-(2*(sqrt(2)-1))),0,d/2*(1-(2*(sqrt(2)-1)))]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([d/2,0,d/2]) translate([-d/2*(1-(2*(sqrt(2)-1))),0,-d/2*(1-(2*(sqrt(2)-1)))]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([0,-d/2,-d/2]) translate([0,d/2*(1-(2*(sqrt(2)-1))),d/2*(1-(2*(sqrt(2)-1)))]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([0,-d/2,d/2]) translate([0,d/2*(1-(2*(sqrt(2)-1))),-d/2*(1-(2*(sqrt(2)-1)))]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([0,d/2,-d/2]) translate([0,-d/2*(1-(2*(sqrt(2)-1))),d/2*(1-(2*(sqrt(2)-1)))]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); translate([0,d/2,d/2]) translate([0,-d/2*(1-(2*(sqrt(2)-1))),-d/2*(1-(2*(sqrt(2)-1)))]) jcube(it=it+1,maxit=maxit,d=d*(1-(2*(sqrt(2)-1)))); }}}