Rev 18506 | Rev 18517 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 18506 | Rev 18513 | ||
|---|---|---|---|
| Line 6... | Line 6... | ||
| 6 | mob(g,z)=if(g[3],z=conj(z));(g[1]*z+g[2])/(conj(g[2])*z+conj(g[1]));\ |
6 | mob(g,z)=if(g[3],z=conj(z));(g[1]*z+g[2])/(conj(g[2])*z+conj(g[1]));\ |
| 7 | \\ Produit et inverse dans le groupe de Moebius etendu\ |
7 | \\ Produit et inverse dans le groupe de Moebius etendu\ |
| 8 | mobx(g)=[g[1],g[2];conj(g[2]),conj(g[1])];\ |
8 | mobx(g)=[g[1],g[2];conj(g[2]),conj(g[1])];\ |
| 9 | mob_mul(g1,g2)=my(m=mobx(g1)*mobx(if(g1[3],conj(g2),g2)));[m[1,1],m[1,2],g1[3]!=g2[3]];\ |
9 | mob_mul(g1,g2)=my(m=mobx(g1)*mobx(if(g1[3],conj(g2),g2)));[m[1,1],m[1,2],g1[3]!=g2[3]];\ |
| 10 | mob_inv(g)=if(g[3],[g[1],-conj(g[2]),1],[conj(g[1]),-g[2],0]);\ |
10 | mob_inv(g)=if(g[3],[g[1],-conj(g[2]),1],[conj(g[1]),-g[2],0]);\ |
| 11 | \\ Homographie (et anti) qui |
11 | \\ Homographie (et anti) qui envoie 0 sur a et 1 sur b, avec a \in D et b a l'horizon\ |
| 12 | mob_ori(a,b,c)=my(e=sqrt(b),g1=(e-conj(e)*a)/(1-norm(a)));[g1,a*conj(g1),c];\ |
12 | mob_ori(a,b,c)=my(e=sqrt(b),g1=(e-conj(e)*a)/(1-norm(a)));[g1,a*conj(g1),c];\ |
| 13 | \\ Point d'intersection de la demi-geodesique de a vers b avec l'horizon\ |
- | |
| 14 | hor(a,b)=my(z=mob([1,-a,0],b));mob([1,a,0],z/sqrt(norm(z)));\ |
- | |
| 15 | \\ Homographie (et anti) qui envoient (a,b) sur (c,d), sous l'hypothèse d(a,b)=d(c,d)\ |
- | |
| 16 | mob_abcd(a,b,c,d,e)=mob_mul(mob_ori(c,hor(c,d),e),mob_inv(mob_ori(a,hor(a,b))));\ |
- | |
| 17 | \\ Homographie qui echange a et b\ |
- | |
| 18 | mob_exg(a,b)={my(h=[1,a,0],h1=mob_inv(h),c=mob(h1,b));\ |
- | |
| 19 | mob_mul(h,mob_mul([I,-I*c,0],h1))};\ |
- | |
| 20 | \\ Reflection par rapport à la geodesique qui joint a et b\ |
13 | \\ Reflection par rapport à la geodesique qui joint a et b\ |
| 21 | mob_ref(a,b)={\ |
14 | mob_ref(a,b)={\ |
| 22 | my(num=a*b*conj(a-b)+b-a,den=conj(a)*b-conj(b)*a,c,d,h);\ |
15 | my(num=a*b*conj(a-b)+b-a,den=conj(a)*b-conj(b)*a,c,d,h);\ |
| 23 | d=if(norm(den)*1e8<norm(num),\ |
16 | d=if(norm(den)*1e8<norm(num),\ |
| 24 | if (norm(b)<norm(a),sqrt(a/conj(a)),sqrt(b/conj(b))),\ |
17 | if (norm(b)<norm(a),sqrt(a/conj(a)),sqrt(b/conj(b))),\ |
| 25 | c=num/den;(1+sqrt(1-norm(c)))/conj(c));\ |
18 | c=num/den;(1+sqrt(1-norm(c)))/conj(c));\ |
| 26 | h=mob_ori(a,d);\ |
19 | h=mob_ori(a,d);\ |
| 27 | mob_mul(h,mob_mul([1,0,1],mob_inv(h)))\ |
20 | mob_mul(h,mob_mul([1,0,1],mob_inv(h)))\ |
| 28 | };\ |
21 | };\ |
| 29 | \\ "Distance" entre a et b, comprise entre 0 et 1. La vraie est log((1+d)/(1-d))\ |
- | |
| 30 | dist(a,b)=sqrt(norm(mob([1,-a,0],b)));\ |
- | |
| 31 | \\ Angle abc, compris entre -Pi et Pi\ |
- | |
| 32 |
|
22 | lft_fwd(g,beta,l)=my(e=exp(I*beta/2));mob_mul(g,[e,e*l,0]);\ |
| 33 | \ |
23 | \ |
| 34 | \\ ------------------------------------------------------------------------------------\ |
- | |
| 35 | \\ Dessin d'arcs et de polygones\ |
- | |
| 36 | \\ ------------------------------------------------------------------------------------\ |
- | |
| 37 | \\ Trace (en tikz) la geodesique entre a et b\ |
- | |
| 38 |
|
24 | wims_export(pavage)={\ |
| 39 | my( |
25 | my(res1,res2,res3,res4,[sommets,paves,aretes,daretes]=pavage,n=#paves[1]-1);\ |
| 40 | if(norm(den)*1e8<=norm(num),\ |
- | |
| 41 |
|
26 | res1=matrix(#sommets,2,i,j,if(j==1,real(sommets[i]),imag(sommets[i])));\ |
| 42 | c=num/den;\ |
- | |
| 43 | arga=arg(a-c)/Pi*180;\ |
- | |
| 44 | argb=arg(b-c)/Pi*180;\ |
- | |
| 45 | if (abs(arga-argb)>180,if(arga<argb,arga+=360,argb+=360));\ |
- | |
| 46 |
|
27 | res2=matrix(#paves,n+2,i,j,if(j==1,n,if(j==n+2,paves[i][n+1][3],paves[i][j-1])));\ |
| 47 | };\ |
- | |
| 48 | \\ Trace un polygone hyperbolique, rempli ou non, etiquete ou non\ |
- | |
| 49 | tikz_poly(o,v,label,fill)={\ |
- | |
| 50 |
|
28 | [res1,res2]\ |
| 51 | if (label > 0,\ |
- | |
| 52 | z=vecsum(v)/n;filewrite1(o,strprintf("\\%s(%.4f,%.4f)node{\\tiny$%d$}(%.4f,%.4f)",\ |
- | |
| 53 | if(fill,"fill","draw"),real(z),imag(z),label,real(v[1]),imag(v[1]))),\ |
- | |
| 54 | filewrite1(o,strprintf("\\%s(%.4f,%.4f)",\ |
- | |
| 55 | if(fill,"fill","draw"),real(v[1]),imag(v[1]))));\ |
- | |
| 56 | for(i=1,n,tikz_arc(o,v[i],v[i%n+1]));\ |
- | |
| 57 | filewrite(o,";")\ |
- | |
| 58 | };\ |
29 | };\ |
| 59 | \ |
30 | \ |
| 60 | \\ ------------------------------------------------------------------------------\ |
- | |
| 61 | \\ Pavage obtenu a partir d'un polygone convexe pavant\ |
- | |
| 62 | \\ ------------------------------------------------------------------------------\ |
- | |
| 63 | \\ Entree: v_i, points du disque de Poincare et d_i>2 des entiers\ |
- | |
| 64 | \\ On suppose que les v_i forment le bord oriente d'un polygone convexe (pave) P0\ |
- | |
| 65 | \\ dont l'angle intérieur au point v_i est 2Pi/d_i\ |
- | |
| 66 | \\ Si deux cotes consecutifs sont inegaux, le d_i entre eux est suppose pair\ |
- | |
| 67 | \\ Renvoie sous forme de fichier off\ |
- | |
| 68 | \\ tous les paves dont au moins un sommet est dans le disque euclidien D(0,1-eps)\ |
- | |
| 69 | \\ Si eps>=1, on s'en sert comme limite sur le nombre de paves.\ |
- | |
| 70 | \\ Si z0 est présent, c'est un point du pavé de base dont les transformés seront calculés\ |
- | |
| 71 | \\ Comme base du pavage dual\ |
- | |
| 72 | \ |
- | |
| 73 | hyp_pav( |
31 | hyp_pav(v,d,eps)={\ |
| 74 | my( |
32 | my(n=#v,a,b,s,s1,s2,t,t1,t2,g,gg,cd0,cd1,cdd1,cd2,r2,f1,v1,w0,z,limit);\ |
| 75 | if(eps>=1,limit=eps;eps=0,limit=1000);\ |
33 | if(eps>=1,limit=eps;eps=0,limit=1000);\ |
| 76 | r2=(1-eps)^2;\ |
34 | r2=(1-eps)^2;\ |
| 77 | if(!v,return(0));\ |
35 | if(!v,return(0));\ |
| 78 | \ |
- | |
| 79 | \\ Les reflexions qui engendrent W\ |
36 | \\ Les reflexions qui engendrent W\ |
| 80 | g=vector(n,i,mob_ref(v[i],v[i%n+1]));\ |
37 | g=vector(n,i,mob_ref(v[i],v[i%n+1]));\ |
| 81 | \ |
38 | \ |
| 82 | \\ Creation du premier |
39 | \\ Creation du premier pave et de son squelette\ |
| 83 | \\ Pour chaque sommet, [arite restante, derniere arete cree, affixe, dans le disque?]\ |
40 | \\ Pour chaque sommet, [arite restante, derniere arete cree, affixe, dans le disque?]\ |
| 84 | cd2=List(vector(n,s,[d[s]-2,if(s==1,n,s),v[s],norm(v[s])<r2]));\ |
41 | cd2=List(vector(n,s,[d[s]-2,if(s==1,n,s),v[s],norm(v[s])<r2]));\ |
| 85 | \\ Pour chaque arete, [origine, extremite, type, premier polygone borde, active]\ |
42 | \\ Pour chaque arete, [origine, extremite, type, premier polygone borde, active]\ |
| 86 | cd1=List(vector(n,a,[a,a%n+1,a,1,cd2[a][4]||cd2[a%n+1][4]]));\ |
43 | cd1=List(vector(n,a,[a,a%n+1,a,1,cd2[a][4]||cd2[a%n+1][4]]));\ |
| - | 44 | \\ Pour chaque arete duale [pave origine, pave extremite, arete croisee]\ |
|
| - | 45 | cdd1=List();\ |
|
| 87 | \\ Pour chaque |
46 | \\ Pour chaque pave, ses aretes et l'élément du groupe\ |
| 88 | cd0=List([vector(n+1,a,if(a>n,[1,0,0],a))]);\ |
47 | cd0=List([vector(n+1,a,if(a>n,[1,0,0],a))]);\ |
| 89 | \ |
48 | \ |
| 90 | while(#cd0<limit&&f1<#cd1, f1+=1; v1=cd1[f1]; if(v1[5],\ |
49 | while(#cd0<limit&&f1<#cd1, f1+=1; v1=cd1[f1]; if(v1[5],\ |
| 91 | s=v1[3]; \\ type de l'arete (ambigu)\ |
50 | s=v1[3]; \\ type de l'arete (ambigu)\ |
| 92 | \\ Nouveau pave et ses aretes, manquantes ou pas\ |
51 | \\ Nouveau pave et ses aretes, manquantes ou pas\ |
| 93 | w0=vector(n+1);\ |
52 | w0=vector(n+1);\ |
| 94 | w0[n+1]=gg=mob_mul(cd0[v1[4]][n+1],g[s]);\ |
53 | w0[n+1]=gg=mob_mul(cd0[v1[4]][n+1],g[s]);\ |
| 95 | w0[s]=a=f1; cd1[a][5]=0;\ |
54 | w0[s]=a=f1; cd1[a][5]=0; listput(cdd1,[v1[4],#cd0+1,a]);\ |
| 96 | s1=cd1[a][1]; s2=cd1[a][2];\ |
55 | s1=cd1[a][1]; s2=cd1[a][2];\ |
| 97 | b=cd0[v1[4]][s%n+1];\ |
56 | b=cd0[v1[4]][s%n+1];\ |
| 98 | if(s2!=cd1[b][1]&&s2!=cd1[b][2],t=s1;s1=s2;s2=t); \\ arete mal orientee\ |
57 | if(s2!=cd1[b][1]&&s2!=cd1[b][2],t=s1;s1=s2;s2=t); \\ arete mal orientee\ |
| 99 | t1=(s-2)%n+1;\ |
58 | t1=(s-2)%n+1;\ |
| 100 | while(!cd2[s1][1]&&!w0[t1], \\ aretes precedent f1 qui sont deja la\ |
59 | while(!cd2[s1][1]&&!w0[t1], \\ aretes precedent f1 qui sont deja la\ |
| 101 | w0[t1]=a=cd2[s1][2]; cd1[a][5]=0;\ |
60 | w0[t1]=a=cd2[s1][2]; cd1[a][5]=0; listput(cdd1,[cd1[a][4],#cd0+1,a]);\ |
| 102 | s1=cd1[a][1]+cd1[a][2]-s1; t1=(t1-2)%n+1);\ |
61 | s1=cd1[a][1]+cd1[a][2]-s1; t1=(t1-2)%n+1);\ |
| 103 | t2=s%n+1;\ |
62 | t2=s%n+1;\ |
| 104 | while(!cd2[s2][1]&&!w0[t2], \\ aretes suivant f1 qui sont deja la\ |
63 | while(!cd2[s2][1]&&!w0[t2], \\ aretes suivant f1 qui sont deja la\ |
| 105 | w0[t2]=a=cd2[s2][2]; cd1[a][5]=0;\ |
64 | w0[t2]=a=cd2[s2][2]; cd1[a][5]=0; listput(cdd1,[cd1[a][4],#cd0+1,a]);\ |
| 106 | s2=cd1[a][1]+cd1[a][2]-s2; t2=t2%n+1);\ |
65 | s2=cd1[a][1]+cd1[a][2]-s2; t2=t2%n+1);\ |
| 107 | while(t1!=t2, \\ Il y a au moins deux aretes a creer\ |
66 | while(t1!=t2, \\ Il y a au moins deux aretes a creer\ |
| 108 | if(s1<s2,\ |
67 | if(s1<s2,\ |
| 109 | z=mob(gg,v[t1]);\ |
68 | z=mob(gg,v[t1]);\ |
| 110 | listput(cd2,[d[t1]-1,#cd1+1,z,norm(z)<r2]);\ |
69 | listput(cd2,[d[t1]-1,#cd1+1,z,norm(z)<r2]);\ |
| Line 120... | Line 79... | ||
| 120 | for(f=1,#cd0,\ |
79 | for(f=1,#cd0,\ |
| 121 | w=cd0[f];a=cd1[w[1]];b=cd1[w[n]];\ |
80 | w=cd0[f];a=cd1[w[1]];b=cd1[w[n]];\ |
| 122 | s=a[1];if(s!=b[1]&&s!=b[2],s=a[2]);\ |
81 | s=a[1];if(s!=b[1]&&s!=b[2],s=a[2]);\ |
| 123 | for(i=1,n,a=cd1[w[i]];w[i]=s;s=a[1]+a[2]-s);\ |
82 | for(i=1,n,a=cd1[w[i]];w[i]=s;s=a[1]+a[2]-s);\ |
| 124 | cd0[f]=w);\ |
83 | cd0[f]=w);\ |
| 125 | \\ Si les d_i ne sont pas tous pairs, la derniere colonne n'a pas de sens\ |
- | |
| 126 | res=vector(if(z0,4,2));\ |
- | |
| 127 |
|
84 | [vector(#cd2,i,cd2[i][3]),Vec(cd0),Vec(cd1),Vec(cdd1)]\ |
| 128 | res[2]=matrix(#cd0,n+2,i,j,if(j==1,n,if(j<=n+1,cd0[i][j-1],cd0[i][n+1][3])));\ |
- | |
| 129 | res\ |
- | |
| 130 | };\ |
85 | };\ |
| 131 | \ |
- | |
| 132 | \\ Dessine le pavage en tikz. r est un vecteur a deux composantes "off"\ |
- | |
| 133 | tikz_off(fname,r,rayon,fill,labels)={\ |
- | |
| 134 | my(pts=r[1],pvs=r[2],n=#pvs[1,]-2,o=fileopen(fname,"w"));\ |
- | |
| 135 | filewrite(o,strprintf("\\begin{tikzpicture}[scale=5]\n\\draw(0,0)circle(1);\n"));\ |
- | |
| 136 | if(rayon,filewrite(o,strprintf("\\draw(0,0)circle(%.4f);\n",rayon)));\ |
- | |
| 137 | for(i=1,#pvs[,1],\ |
- | |
| 138 | tikz_poly(o,vector(n,j,pts[pvs[i,j+1],1]+I*pts[pvs[i,j+1],2]),if(labels,i),fill&&pvs[i,n+2]));\ |
- | |
| 139 | if (#r>2, pts=r[3]; pvs=r[4]; for(i=1,#pvs[,1],\ |
- | |
| 140 | tikz_poly(o,vector(pts[i,1],j,pts[pvs[i,j+1],1]+I*pts[pvs[i,j+1],2]),if(labels,i))));\ |
- | |
| 141 | filewrite(o,strprintf("\\end{tikzpicture}"));\ |
- | |
| 142 | fileclose(o);\ |
- | |
| 143 | };\ |
- | |
| 144 | \ |
- | |
| 145 | \\ -----------------------------------------------------------------------------------\ |
- | |
| 146 | \\ Creation de polygones convexes d'angles et longueurs donnees\ |
- | |
| 147 | \\ -----------------------------------------------------------------------------------\ |
- | |
| 148 | \\ S'il existe un triangle de côtés a,b,c et angles A,B,C, les fonctions suivantes\ |
- | |
| 149 | \\ renvoient les paramètres manquants. Sinon, elles renvoient 0\ |
- | |
| 150 | abc(A,B,C)={\ |
86 | abc(A,B,C)={\ |
| 151 | if (A+B+C >= Pi, return(0));\ |
87 | if (A+B+C >= Pi, return(0));\ |
| 152 | my(cha=(cos(A)+cos(B)*cos(C))/(sin(B)*sin(C)),\ |
88 | my(cha=(cos(A)+cos(B)*cos(C))/(sin(B)*sin(C)),\ |
| 153 | chb=(cos(B)+cos(A)*cos(C))/(sin(A)*sin(C)),\ |
89 | chb=(cos(B)+cos(A)*cos(C))/(sin(A)*sin(C)),\ |
| 154 | chc=(cos(C)+cos(B)*cos(A))/(sin(B)*sin(A)));\ |
90 | chc=(cos(C)+cos(B)*cos(A))/(sin(B)*sin(A)));\ |
| 155 | [sqrt((cha-1)/(cha+1)),sqrt((chb-1)/(chb+1)),sqrt((chc-1)/(chc+1))]\ |
91 | [sqrt((cha-1)/(cha+1)),sqrt((chb-1)/(chb+1)),sqrt((chc-1)/(chc+1))]\ |
| 156 | };\ |
92 | };\ |
| 157 | ABC(a,b,c)={\ |
- | |
| 158 | if(c>=a+b-a*b || b>=a+c-a*c || a>=b+c-b*c, return (0));\ |
- | |
| 159 | my(cha=(1+a^2)/(1-a^2),chb=(1+b^2)/(1-b^2),chc=(1+c^2)/(1-c^2),\ |
- | |
| 160 | sha=2*a/(1-a^2),shb=2*b/(1-b^2),shc=2*c/(1-c^2));\ |
- | |
| 161 | [acos((chb*chc-cha)/(shb*shc)),\ |
- | |
| 162 | acos((cha*chc-chb)/(sha*shb)),\ |
- | |
| 163 | acos((chb*cha-chc)/(shb*sha))]\ |
- | |
| 164 | };\ |
- | |
| 165 | AbC(a,B,c)={\ |
- | |
| 166 | my(cha=(1+a^2)/(1-a^2),chc=(1+c^2)/(1-c^2),sha=2*a/(1-a^2),shc=2*c/(1-c^2),\ |
- | |
| 167 | chb=cha*chc-sha*shc*cos(B),shb=sqrt(chb^2-1));\ |
- | |
| 168 | [acos((chb*chc-cha)/(shb*shc)),sqrt((chb-1)/(chb+1)),acos((chb*cha-chc)/(shb*sha))]\ |
- | |
| 169 | };\ |
- | |
| 170 | aBc(A,b,C)={\ |
- | |
| 171 | my(chb=(1+b^2)/(1-b^2),cB=sin(A)*sin(C)*chb-cos(A)*cos(C),sB,cha,chc);\ |
- | |
| 172 | if (abs(cB)>=1,return(0),sB=sqrt(1-cB^2));\ |
- | |
| 173 | cha=(cos(A)+cB*cos(C))/(sB*sin(C));\ |
- | |
| 174 | chc=(cos(C)+cB*cos(A))/(sB*sin(A));\ |
- | |
| 175 | if(cha>1 && chc>1,[sqrt((cha-1)/(cha+1)),acos(cB),sqrt((chc-1)/(chc+1))],0)\ |
- | |
| 176 | };\ |
- | |
| 177 | \ |
- | |
| 178 | \\ S'il existe, renvoie le quadrilatère convexe [0,l,z3,z4]\ |
- | |
| 179 | \\ d'angles alpha,beta,gamma,delta et longueur(AB)=l, sinon renvoie 0\ |
- | |
| 180 | quad(al,be,ga,de,l)={\ |
- | |
| 181 | my(eps=1e-10,g=[1,l,0],t=aBc(al,l,be),eA=exp(I*al),eB=-exp(-I*be),\ |
- | |
| 182 | u,v,lC,lD,minC,maxC=1.);\ |
- | |
| 183 | if(t, u=abc(Pi-ga,t[2],Pi-de);\ |
- | |
| 184 | if(!u||u[1]>=t[3]||u[3]>=t[1], return(0));\ |
- | |
| 185 | lD=(t[3]-u[1])/(1-u[1]); lC=(t[1]-u[3])/(1-u[3]),\ |
- | |
| 186 | while(maxC-minC>eps, lC=(maxC+minC)/2; u=AbC(l,be,lC);\ |
- | |
| 187 | if(u[1]>=ga, minC=lC, v=aBc(al-u[3],u[2],ga-u[1]);\ |
- | |
| 188 | if(!v,maxC=lC, lD=v[3]; if(v[2]<de, maxC=lC, minC=lC)))));\ |
- | |
| 189 | [0,l,mob(g,lC*eB),lD*eA]\ |
- | |
| 190 | };\ |
- | |
| 191 | \ |
- | |
| 192 | \\ La tortue hyperbolique, turn left beta, then forward l\ |
- | |
| 193 | lft_fwd(g,beta,l)=my(e=exp(I*beta/2));mob_mul(g,[e,e*l,0]);\ |
- | |
| 194 | \ |
- | |
| 195 | \\ Entree: n angles et n-3 longueurs\ |
- | |
| 196 | \\ Sortie: [z1=0,z2=l1,z3,....,zn] n points du disque de Poincare qui forment le bord\ |
- | |
| 197 | \\ oriente d'un polygone convexe tel que... s'il existe. Sinon, 0.\ |
- | |
| 198 | polygone(a,l)={\ |
- | |
| 199 | my(n=#a,res=vector(n),theta,phi,v,g,z,eth,w);\ |
- | |
| 200 | if(n==3,v=abc(a[1],a[2],a[3]); return(if(v,[0,v[3],v[2]*exp(I*a[1])])));\ |
- | |
| 201 | g=[1,l[1],0]; res[2]=z=l[1];\ |
- | |
| 202 | for(i=2,n-3, g=lft_fwd(g,Pi-a[i],l[i]); z=mob(g,0);\ |
- | |
| 203 | if(arg(z)<=theta,return(0),theta=arg(z));\ |
- | |
| 204 | res[i+1]=z);\ |
- | |
| 205 | phi=Pi-angle(mob(g,1),z,0);\ |
- | |
| 206 | if(theta>=a[1]||phi>=a[n-2], return(0));\ |
- | |
| 207 | v=quad(a[1]-theta,a[n-2]-phi,a[n-1],a[n],sqrt(norm(z)));\ |
- | |
| 208 | if(!v,return(0));\ |
- | |
| 209 | eth=exp(I*theta); res[n-1]=eth*v[3]; res[n]=eth*v[4];\ |
- | |
| 210 | return(res)\ |
- | |
| 211 | };\ |
- | |
| 212 | \ |
- | |
| 213 | \\ Entree: n angles entre 0 et Pi, dont la somme est inferieure a (n-2)*Pi\ |
- | |
| 214 | \\ Sortie: L'unique polygone convexe dont tous les cotes sont tangents a un meme cercle\ |
- | |
| 215 | \\ de centre 0, d'angles interieurs a_i et dont le premier sommet est un reel positif.\ |
- | |
| 216 | \ |
- | |
| 217 | tangentiel( |
93 | tangentiel(a,centre)={\ |
| 218 | my(l,cs=apply(x->cos(x/2),a),\ |
94 | my(l,cs=apply(x->cos(x/2),a),\ |
| 219 | k=solve(t=0,1,vecsum(apply(x->asin(t*x),cs))-Pi),\ |
95 | k=solve(t=0,1,vecsum(apply(x->asin(t*x),cs))-Pi),\ |
| 220 | R=sqrt(2/(1+k)-1) |
96 | R=sqrt(2/(1+k)-1), g=[1,0,0], h, res=vector(#a));\ |
| 221 |
|
97 | if(centre,g=lft_fwd(lft_fwd([1,0,0],-asin(k*cs[1]),R),Pi/2,0));\ |
| 222 | \\ g=lft_fwd(lft_fwd([1,0,0],0,R),Pi/2,0),\ |
- | |
| 223 | res=vector(#a));\ |
- | |
| 224 | for(i=1,#a,\ |
98 | for(i=1,#a,\ |
| 225 | l=abc(Pi/2,a[i]/2,asin(k*cs[i]))[3];\ |
99 | l=abc(Pi/2,a[i]/2,asin(k*cs[i]))[3];\ |
| 226 | g=lft_fwd(g,0,l);\ |
100 | g=lft_fwd(g,0,l);\ |
| 227 | res[i]=mob(g,0);\ |
101 | res[i]=mob(g,0);\ |
| 228 | g=lft_fwd(g,Pi-a[i],l));\ |
102 | g=lft_fwd(g,Pi-a[i],l));\ |
| 229 |
|
103 | [res,R]\ |
| 230 | };\ |
104 | };\ |
| 231 | \ |
105 | \ |
| 232 | \\ ----------------------------------------------------------------------------\ |
- | |
| 233 | \\ Quelques paves simples\ |
- | |
| 234 | \\ ----------------------------------------------------------------------------\ |
- | |
| 235 | \ |
- | |
| 236 | \\ Construit un cerf-volant [0,z2,z3,z4] d'angles [a1,a2,a3,a4==a2]\ |
- | |
| 237 | build_kite(a1,a2,a3)={my(tr=polygone([a1/2,a2,a3/2]));\ |
- | |
| 238 | if(tr,[tr[1],tr[2],tr[3],mob(mob_ref(tr[1],tr[3]),tr[2])])};\ |
- | |
| 239 | \ |
- | |
| 240 | \\ d2 doit etre pair et 1/d1+2/d2+1/d3 < 1\ |
- | |
| 241 | kite(d1,d2,d3,eps,depl)={\ |
- | |
| 242 | my(p=build_kite(2*Pi/d1,2*Pi/d2,2*Pi/d3));\ |
- | |
| 243 | if(!p,return(0));\ |
- | |
| 244 | if(depl,p=vector(4,i,mob(depl,p[i])));\ |
- | |
| 245 | hyp_pav(p,[d1,d2,d3,d2],eps)};\ |
- | |
| 246 | \ |
- | |
| 247 | \\ Polygone a n cotes tous egaux, avec angles tous egaux a 2Pi/d\ |
- | |
| 248 | \\ On suppose donc (d-2)(n-2)>4\ |
- | |
| 249 | regular(n,d,eps,depl=[1,0,0])={\ |
- | |
| 250 | my(t=polygone([2*Pi/n,Pi/d,Pi/d]));\ |
- | |
| 251 | if(t,hyp_pav(vector(n,k,mob(depl,exp(2*I*k*Pi/n)*t[2])),vector(n,k,d),eps))};\ |
- | |
| 252 | \ |
- | |
| 253 | \\ 1/d1 + 1/d2+ 1/d3 < 1/2\ |
- | |
| 254 | \\ Si un des trois est impair, les autres sont supposes egaux\ |
- | |
| 255 | triangle(d1,d2,d3,eps,depl=[1,0,0])={\ |
- | |
| 256 | my(t=polygone([2*Pi/d1,2*Pi/d2,2*Pi/d3]));\ |
- | |
| 257 | if(t&&depl,t=vector(3,i,mob(depl,t[i])));\ |
- | |
| 258 | if(t,hyp_pav(t,[d1,d2,d3],eps))};\ |
- | |
| 259 | \ |
- | |
| 260 | \\ genre de parallelogramme: deux angles distincts\ |
- | |
| 261 | \\ depend d'un parametre mu continu compris entre 0 et 1\ |
- | |
| 262 | \\ On doit avoir 1/d1 + 1/d2 < 1/2\ |
- | |
| 263 | \\ Si d1 ou d2 est impair, on doit aussi avoir mu=1/2.\ |
- | |
| 264 | parallelogram(d1,d2,mu,eps,depl)={\ |
- | |
| 265 | my(t=polygone([2*Pi/d1,2*mu*Pi/d2,2*Pi*(1-mu)/d2]));\ |
- | |
| 266 | if(!t,return(0));\ |
- | |
| 267 | if(depl,t=vector(3,i,mob(depl,t[i])));\ |
- | |
| 268 | hyp_pav([t[1],t[2],mob(mob_exg(t[2],t[3]),t[1]),t[3]],[d1,d2,d1,d2],eps)};\ |
- | |
| 269 | \ |
- | |
| 270 | \\ Etant donnes le centre et le rayon (<1) d'un disque hyperbolique,\ |
- | |
| 271 | \\ renvoie le centre et le rayon du meme disque considere comme euclidien.\ |
- | |
| 272 | hyp_cercle(c, r)=my(R2=norm(c),den=1-r^2*R2);[(1-r^2)*c/den,(1-R2)*r/den];\ |
- | |
| 273 | \ |
- | |
| 274 | \\ On se donne n entiers d[i] >= 3, avec la convention d[] périodique modulo n\ |
- | |
| 275 | \\ On suppose que si d[i] est impair, alors on a d[i-1]=d[i+1]\ |
- | |
| 276 | \\ Calcule le pavage associé au polygone tangentiel d'angles interieurs 2*Pi/d[i]\ |
- | |
| 277 | \\ On peut afficher le pavage dual et les cercles inscrits /* TO DO */\ |
- | |
| 278 | catalan( |
106 | catalan(d,limite,centre)={\ |
| 279 | my( |
107 | my([h,R]=tangentiel(apply(x->2*Pi/x,d),centre));\ |
| 280 | if(depl,h=apply(x->mob(depl,x),h));\ |
- | |
| 281 | hyp_pav( |
108 | [hyp_pav(h,d,limite),R,if(centre,0,R*I)]\ |
| 282 | }\ |
- | |
| 283 | \ |
- | |
| 284 | \\ Etant donne le "fichier off" d'un pavage issu de catalan\ |
- | |
| 285 | \\ Calcule un "fichier off dual" dont le premier sommet est 0\ |
- | |
| 286 | cat_dual(off)={\ |
- | |
| 287 | my(cts=vector(#off[2]),fls=vector(#off[1]));\ |
- | |
| 288 | for(i=1,#off[2],0);\ |
- | |
| 289 | /* TO DO */\ |
- | |
| 290 | \ |
- | |
| 291 | [cts,fls]\ |
- | |
| 292 | };\ |
109 | };\ |
| 293 | \ |
- | |
| 294 | /*\ |
- | |
| 295 | tikz_off("8_3_5.tex",kite(8,3,5,0.01))\ |
- | |
| 296 | regular(7,3,0.1);\ |
- | |
| 297 | parallelogram(4,6,3,0.1);\ |
- | |
| 298 | */\ |
- | |