Ceci est une ancienne révision du document !
Le code est ici : L.O.L. - Code
Créée par Marc Vanlindt - CC-BY-SA Belgique 2.0
Le but de cette librairie est de faire en sorte que toutes les primitives 2D puissent être appelées en tant que variables.
Plusieurs fonctions et modules ont donc été réalisés pour les créer mais également pour en créer de nouvelles et les modifier plus en profondeur.
Une fois les primitives utilisées en tant que variables, il est possible d'y appliquer des modifications en principe accessibles qu'aux polygones ou aux vecteurs, ces formes étant les seules dont il est possible de retirer les coordonnées de chaque point le composant.
Attention :
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],[50,35],[43.75,8.75],[25,0],[25,0],[6.25,8.75],[0,35]]; 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); rose = 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;
Donne un nombre aléatoire entre 0 et n si pos est sur *true* (par défaut) et entre -n et n si pos est sur *false*. s correspond à la valeur utilisée pour générer le nombre aléatoire.
for(i=[1:100]){ translate([random(n=300,s=i,pos=false),random(n=300,s=i*2,pos=false)]) teardrop(); }
function random (n,s,pos) = rands(pos==undef?0:pos==true?0:-n,n,1,s==undef?n:s)[0];
Donne l'hypothénuse en fonction de deux longueurs.
echo(hypo(3,4)); -> ECHO: 5
function hypo (a,b) = sqrt((a*a)+(b*b));
for(i=[0:10]){echo(i," : ",pair(i));} -> ECHO: 0, " : ", true ECHO: 1, " : ", false ECHO: 2, " : ", true ECHO: 3, " : ", false ECHO: 4, " : ", true ECHO: 5, " : ", false ECHO: 6, " : ", true ECHO: 7, " : ", false ECHO: 8, " : ", true ECHO: 9, " : ", false ECHO: 10, " : ", true
function pair (a) = a%2==0?true:false;
abc=[[0,0],[100,100]]; echo(normal(abc)); -> ECHO: [[0, 0], [0.707107, 0.707107]]
function normal (a) = a/(sqrt(a[0]*a[0]+a[1]*a[1]));
abc=ppcm(10,25); def=ppcm(11,17); ghi=ppcm(32,24); echo(abc); echo(def); echo(ghi); ->ECHO: [5,2] -> 5*10 = 2*25 ECHO: [17,11] -> 17*11 = 11*17 ECHO: [3,4] -> 3*32 = 4*24
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];
abc=[10,2,9,7,5,6,4,8,3,1]; echo("sum :", sum(abc)); echo("topct :", topct(abc)); echo("moyenne :", moyenne(abc)); echo("invert :", invert(abc)); echo("sort :", sort(abc)); -> ECHO: "sum :", 55 ECHO: "topct :", [0.181818, 0.0363636, 0.163636, 0.127273, 0.0909091, 0.109091, 0.0727273, 0.145455, 0.0545455, 0.0181818] ECHO: "moyenne :", 5.5 ECHO: "invert :", [1, 3, 8, 4, 6, 5, 7, 9, 2, 10] ECHO: "sort :", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
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)));
Retourne la longueur entre deux points.
abc=[100,100]; def=[200,200]; echo(length(abc,def)); -> ECHO: 141.421
function length (a,b) = sqrt(((b[0]-a[0])*(b[0]-a[0]))+((b[1]-a[1])*(b[1]-a[1])));
abc=[50,50]; def=[100,100]; ghi=[for(i=[0:10])divide(abc,def,i/10)]; echo(ghi); -> ECHO: [[50, 50], [55, 55], [60, 60], [65, 65], [70, 70], [75, 75], [80, 80], [85, 85], [90, 90], [95, 95], [100, 100]]
function divide(a,b,c) = [a[0]+(b[0]-a[0])*c, a[1]+(b[1]-a[1])*c];
Attention : pour les besoins que j'en ai eu, cette fonction ne “ferme” pas la forme et seul le premier point est inclus, non le dernier!
abc=[50,50]; def=[100,100]; jkl=addpoints(abc,def,5); echo(jkl); -> ECHO: [[50, 50], [58.3333, 58.3333], [66.6667, 66.6667], [75, 75], [83.3333, 83.3333], [91.6667, 91.6667]]
function addpoints(c1,c2,n)=[for(i=[0:n]) each [divide(c1,c2,i/(n+1))]];
abc=[0,0]; def=[100,100]; echo(myangle(abc,def)); ->ECHO: 45
function myangle(a,b) = atan2(b[0]-a[0],b[1]-a[1]);
Join2 n'est pas compatible avec toutes les versions de OpenSCAD.
abc=[0,0]; def=[100,100]; ghi=[200,200]; jkl=[300,300]; echo(join([abc,def,ghi,jkl])); echo(join2([abc,def,ghi,jkl])); ->ECHO: [0, 0, 100, 100, 200, 200, 300, 300] ECHO: [0, 0, 100, 100, 200, 200, 300, 300]
function join(a,c=0,t=[]) = let (u=concat(t,a[c]))c==len(a)?t:join(a=a,c=c+1,t=u); function join2(aa) = [for(i=[0:len(aa)-1] ) each aa[i]];
abc=[[0,0],[1,1],undef,[2,2],[2,2],[3,3],undef,[4,4],[5,5],[5,5]]; echo(clean(abc)); -> ECHO: [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5]]
function clean(a) = [for(i=[0:len(a)-1]) each (a[i]==a[i+1]?"":a[i][0]==undef?"":[a[i]])];
abc=[[0,0],[100,0]]; def=fract(abc,in=false,angle=60,maxit=3,close=false); echo(def); color(vert) trace(abc); color(rouge) trace(def); ->ECHO: [[0, 0], [3.7037, 0], [5.55556, 3.2075], [7.40741, 0], [11.1111, 0], [12.963, 3.2075], [11.1111, 6.415], [14.8148, 6.415], [16.6667, 9.6225], [18.5185, 6.415], [22.2222, 6.415], [20.3704, 3.2075], [22.2222, 0], [25.9259, 0], [27.7778, 3.2075], [29.6296, 0], [33.3333, 0], [35.1852, 3.2075], [33.3333, 6.415], [37.037, 6.415], [38.8889, 9.6225], [37.037, 12.83], [33.3333, 12.83], [35.1852, 16.0375], [33.3333, 19.245], [37.037, 19.245], [38.8889, 22.4525], [40.7407, 19.245], [44.4444, 19.245], [46.2963, 22.4525], [44.4444, 25.66], [48.1481, 25.66], [50, 28.8675], [51.8519, 25.66], [55.5556, 25.66], [53.7037, 22.4525], [55.5556, 19.245], [59.2593, 19.245], [61.1111, 22.4525], [62.963, 19.245], [66.6667, 19.245], [64.8148, 16.0375], [66.6667, 12.83], [62.963, 12.83], [61.1111, 9.6225], [62.963, 6.415], [66.6667, 6.415], [64.8148, 3.2075], [66.6667, 0], [70.3704, 0], [72.2222, 3.2075], [74.0741, 0], [77.7778, 0], [79.6296, 3.2075], [77.7778, 6.415], [81.4815, 6.415], [83.3333, 9.6225], [85.1852, 6.415], [88.8889, 6.415], [87.037, 3.2075], [88.8889, 0], [92.5926, 0], [94.4444, 3.2075], [96.2963, 0], [100, 0]]
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);
abc=[[0,0],[0,100],[100,100]]; def=curve(abc,fn=6); echo(def); color(vert) trace(abc); color(rouge) trace(def); ->ECHO: [[0, 0], [2.77778, 30.5556], [11.1111, 55.5556], [25, 75], [44.4444, 88.8889], [69.4444, 97.2222], [100, 100]]
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;
abc=fractshape(d=50,fn=3,maxit=2,inside=false); def=chaincurve(abc,closed=true,fn=4); echo(def); color(vert) trace(abc); color(rouge) trace(def,dot=true,d=0.5);
function chaincurve(table,fn,closed,detail) = let ( detail=detail==undef?1:detail==0?1:detail*sign(detail)*2+1, closed=closed==undef?true:closed, 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);
abc=[[0,0],[100,0]]; for(i=[0:3])echo(doublevector(abc,f=i)); ->ECHO: [[0, 0], [50, 0], [100, 0]] ECHO: [[0, 0], [25, 0], [50, 0], [75, 0], [100, 0]] ECHO: [[0, 0], [12.5, 0], [25, 0], [37.5, 0], [50, 0], [62.5, 0], [75, 0], [87.5, 0], [100, 0]] ECHO: [[0, 0], [6.25, 0], [12.5, 0], [18.75, 0], [25, 0], [31.25, 0], [37.5, 0], [43.75, 0], [50, 0], [56.25, 0], [62.5, 0], [68.75, 0], [75, 0], [81.25, 0], [87.5, 0], [93.75, 0], [100, 0]]
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],1/2)]] ) it==f?clean(aa):doublevector(clean(aa),f=f,it=it+1); 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]]],f=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);
abc=square([50,100]); def=fractalize(abc,force=1,maxit=4); ghi=chaincurve(def); polygon(def); translate([55,0,0]) polygon(ghi);
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]]],f=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);
Les primitives 2D peuvent-être appellées de la même manière que celles présentes de base dans openscad.
Mais il est également possibles de faire appel à toutes sous forme de variable :
abc = square([10,20],center=true); square([10,20],center=true); translate ([12,0,0]) polygon(abc);
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;
abc = circle(d=10,fn=16); def = circle(r=5,fn=8); circle(d=10,$fn=24); translate ([12,0,0]) polygon(abc); translate ([24,0,0]) polygon(def);
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;
abc = ellipse([40,20],fn=12); ellipse([20,40],fn=24);; translate ([40,0,0]) polygon(abc);
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],cos(360/fn*i)*s[1]]] ) aa;
abc = star(d1=40,d2=10,fn=12); star(d1=40,d2=30,fn=9); translate ([40,0,0]) polygon(abc);
function star(d1,d2,fn) = let ( d1=d1==undef?10:d1, d2=d2==undef?5:d2, 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;
abc = roundsquare([15,25],[10,2.5,2.5,10]); roundsquare([20,10],[1,8,8,1]); translate ([22,0,0]) polygon(abc);
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;
abc = triangle(10,20); triangle(20,10); translate ([17.55,0,0]) polygon(abc);
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;
Où d est le diamètre, a un angle et p une fraction.
Si a et p ont tous les deux une valeurs, seul l'angle sera pris en compte.
abc=piepart(d=50,p=16/100); piepart(d=50,a=60); translate([30,0,0]) polygon(abc);
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;
abc=teardrop(25,60,12); def=teardrop(25,15,4); teardrop(25,30,24); translate([30,0,0]) polygon(abc); translate([60,0,0]) polygon(def);
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;
abc=ngon(20,4,inside=true); def=ngon(20,4,inside=false); ngon(20,16); translate([25,0,0]) polygon(abc); translate([50,0,0]) polygon(def); translate([25,0,-1]) #circle(d=20); translate([50,0,1]) #circle(d=20);
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;
abc=losange([10,20]); losange([20,10]); translate([20,0,0]) polygon(abc);
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;
abc=fractshape(d=40,fn=5,it=3,inside=true); def=fractshape(d=40,fn=6,it=3,inside=true); fractshape(d=40,fn=5,it=3,inside=false); translate([50,0,0]) fractshape(d=40,fn=3,it=3,inside=false); translate([0,50,0]) polygon(abc); translate([50,50,0]) polygon(def);
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;
abc=pointgrid([50,50],n=100); echo(abc); for(i=abc)translate(i) circle(d=1);
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)))]];
abc=[0,0,1,1]; def=[1,0,0,1]; ghi=gradient(abc,def,20); for(i=[0:19]) translate([i,0,0]) color(ghi[i]) cube([1,20,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;
Ces objets ne peuvent être appelés sous forme de variables.
Où w est la largeur du trait, c une courbure ouvant être appliqué aux angles à l'intérieur du motif, n le nombre de cellules voules et seed la graine à utiliser pour l'aléatoire.
voronoi([1000,500],w=4,c=0,n=100,seed=1123); translate([1050,0,0]) voronoi([1000,500],w=5,c=120,n=12,seed=614); translate([0,-650,0]) voronoi([1000,500],w=3,c=1,n=200,seed=614); translate([1050,-650,0]) voronoi([1000,500],w=3,c=1,n=200,seed=615);
module voronoi(dim, w, c, n, seed){ fn=fn==undef?32:fn; 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]); }}}}}}
abc=[[0,0],[sin(30)*10,cos(30)*10],[10,0]]; trace(abc); translate([15,0,0]) trace(abc,dot=false,fn=16); translate([30,0,0]) trace(abc,dot=true,dotfn=6); translate([0,15,0]) trace(abc, dot=true,dotfn=6,tr=false); translate([15,15,0]) trace(abc,d=0.5,dot=true,dotfn=6,tr=true,d2=3);
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);} } }
menger(d=50,maxit=5);
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); }}}
tube(d1=10,d2=8,h=10,$fn=8); translate([15,0,0]) tube(d1=15,d2=10,h=5,$fn=64);
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); } }
coude(d1=10,d2=6,$fn=64); translate([0,15,0]) coude(d1=10,d2=9,a=45,$fn=64); translate([0,30,0]) coude(d1=10,d2=5,a=67.5,$fn=64);
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); } } }
bone(h=50,d1=20,d2=14.14214,c=80,q=128); translate([30,0,0]) bone(h=50,d1=20,d2=14.14214,c=25,q=128); translate([60,0,0]) bone(h=50,d1=20,d2=5,c=60,q=128);
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)*2,$fn=q) { circle(d=d1,$fn=q); translate([0,h]) circle(d=d2,$fn=q); } } } }
roundcube(); translate([65,0,0]) roundcube(s=[20,30,50], b=[2,4,6,8],t=[10,12,14,16],q=64); translate([95,0,0]) roundcube(s=[70,30,40], b=[5,5,5,5],t=[35,35,35,35],q=64);
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; 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]); translate([s[0]-b[1]/2,b[1]/2,b[1]/2]) sphere(d=b[1]); translate([s[0]-b[2]/2,s[1]-b[2]/2,b[2]/2]) sphere(d=b[2]); translate([b[3]/2,s[1]-b[3]/2,b[3]/2]) sphere(d=b[3]); translate([t[0]/2,t[0]/2,s[2]-t[0]/2]) sphere(d=t[0]); translate([s[0]-t[1]/2,t[1]/2,s[2]-t[1]/2]) sphere(d=t[1]); translate([s[0]-t[2]/2,s[1]-t[2]/2,s[2]-t[2]/2]) sphere(d=t[2]); translate([t[3]/2,s[1]-t[3]/2,s[2]-t[3]/2]) sphere(d=t[3]); } }
Fonctionne pour les objets 2D et 3D :
ring(d=20,n=7) circle(); translate([25,0,0]) ring(d=20,n=9) sphere();
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(); } } }
fibo(s=1,n=512,r=true) circle(d=5); translate([1200,0,0]) fibo(s=1,n=512,r=false) circle(d=20); translate([600,600,0]) fibo(s=0.5,n=512,r=false) circle(d=20);
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(); } }
Simule l'utilisation d'une CNC où d est le diamètre de la mèche.
show=true/false permet de voir “ce que donne” la différence entre la forme originelle et celle qui serait coupée à la CNC.
difference(){ square([10,20],center=true); square([8,18],center=true); } translate([12,0,0])cnc(d=4,show=true){ difference(){ square([10,20],center=true); square([8,18],center=true); }} translate([24,0,0])cnc(d=4,show=false){ difference(){ square([10,20],center=true); square([8,18],center=true); }}
module cnc(d,show){ show=show==undef?false:show; d = d == undef ? 3:d; if(show==false){ offset(-d/2,$fn=32) offset(d/2,$fn=32) children(); } else { color("green") linear_extrude(1) children(); color("red") linear_extrude(0.5) difference() { offset(-d/2,$fn=32) offset(d/2,$fn=32) children(); children(); } } }
chull(m=true){ sphere(d=1,$fn=16); 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); } translate([0,-25,0]) chull(m=false){ sphere(d=1,$fn=16); 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); }
module chull(m){ union() for(i=[0:$children-2]){ hull(){ children(m==true?0:i); children(i+1); } } }
grid([500,500],x=3,y=5){ ellipse([10,30]); ellipse([30,10]); }
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(); }
moebius(fn=64){ square([1,10],center=true);} translate([50,0,0]) moebius(fn=64,t=2){ square([1,10],center=true);} translate([0,0,50]) moebius(fn=64,t=1.5){ square([1,10],center=true);} translate([50,0,50]) moebius(fn=64,t=1.5){ ellipse([1,10]); ellipse([10,1]);}
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); } } } } }
pythatree(d="z",h=50,maxit=5,r1=0,r2=0) bone(h=50,d1=20,d2=14.14214,c=160,$fn=32); translate([200,0,0])pythatree(d="z",h=50,maxit=7,r1=0,r2=90) bone(h=50,d1=20,d2=14.14214,c=160,$fn=32);
pythatree(d="y",h=5,maxit=9) square([1,5]);
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(); }; } }
abc=square([10,10],center=true); def=circle(d=10,fn=7); ghi=interpolate(abc,def,step=0,maxstep=1,correct=0,q=1); jkl=interpolate(abc,def,step=1,maxstep=1,correct=0,q=1); echo(len(abc)); echo(len(def)); echo(len(ghi)); echo(len(jkl)); trace(abc,dot=true,d=0.3); translate([15,0,0]) trace(def,dot=true,d=0.3); translate([0,-15,0]) trace(ghi,dot=true,d=0.3); translate([15,-15,0]) trace(jkl,dot=true,d=0.3); ->ECHO: 5 ECHO: 8 ECHO: 29 ECHO: 29
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))]]) (aa);
abc=square([10,10],center=true); echo(len(abc)); for(i=[1:4]){ def=multiplyfaces(abc,i); echo(len(def)); translate([12*(i-1),0,0]) trace(def,d=0.3); } ->ECHO: 5 ECHO: 9 ECHO: 13 ECHO: 17 ECHO: 21
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]]);
abc=ngon(d=50,fn=3); def=chaincurve(koch(abc,maxit=2)); my3Dobject=simple3D(abc,def,h=70); polyhedron(my3Dobject[0],my3Dobject[1]);
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(L1,L2,maxstep=1,step=0,correct=correct,q=1),angle), d=2Drot(interpolate(L1,L2,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)];
Attention : Ce module générera énormément d'erreurs mais le résultat final devrait être bon. a est la première forme. b est la seconde forme. h la hauteur de la forme. correct permet de corriger de quel point à quel point se fait le raccords afin d'éviter les rotations.
Ce module est sujet à beaucoup de bugs!!! Merci de préférer tant que maintenant le passage par la fonction simple3D()
Les autres variables seron documentées plus tard.
abc=ngon(d=40,fn=5); def=fractshape(d=40,fn=5,it=3,inside=true); ghi=chaincurve(def); 2Dto3D(abc,def,segment=4,h=20); translate([50,0,0]) 2Dto3D(abc,ghi,segment=8,h=20); translate([0,50,0]) 2Dto3D(circle(d=40,fn=16),square([20,20],center=true),h=20,segment=16,correct=0); translate([50,50,0]) 2Dto3D(circle(d=40,fn=16),square([20,20],center=true),h=20,segment=4,correct=6);
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]);} } } }