Rev 17213 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
16993 | bpr | 1 | !set slib_header_patron=default(realprecision,3);\ |
16886 | bpr | 2 | normalise={v->1/sqrt(norml2(v))*v;};\ |
3 | /* calcule une image 2D isometrique des faces du polyedre*/\ |
||
16993 | bpr | 4 | wedge={(a,b)->[a[2]*b[3]-a[3]*b[2],a[3]*b[1]-a[1]*b[3],a[1]*b[2]-a[2]*b[1]]};\ |
17156 | bpr | 5 | depl_standard(f, xyz)={\ |
16993 | bpr | 6 | my(res2D = vector(#f),no = vector(#f),t2,w);\ |
16886 | bpr | 7 | for (k = 1, #f,\ |
8 | w=vector(f[k][1],i,xyz[f[k][i+1]+1,]);\ |
||
9 | my(t1=normalise(w[2]-w[1])~,n=normalise(wedge(t1,w[3]-w[1])),t2=wedge(n,t1)~);\ |
||
16993 | bpr | 10 | no[k]=n;\ |
16991 | bpr | 11 | res2D[k]=vector(#w,i,[w[i]*t1,w[i]*t2]));\ |
16993 | bpr | 12 | [res2D,no];\ |
16886 | bpr | 13 | };\ |
14 | deplacement_poly (a,b,f,i1,i2)={\ |
||
17039 | bpr | 15 | /* rotation et translation de f qui envoie l'arête joignant les sommets\ |
16 | numero i1 et numero i2 sur (a,b).\ |
||
16886 | bpr | 17 | On suppose (a,b) et (f[i1], f[i2]) de même longueur.*/\ |
18 | my(v1=f[i2]-f[i1],v2=b-a,v=normalise([v1*v2~,v1[1]*v2[2]-v1[2]*v2[1]]));\ |
||
19 | my(m1=[v[1],v[2];-v[2],v[1]]);\ |
||
20 | my(dec=a-f[i1]*m1);\ |
||
21 | vector(#f, i, if(i==i1,a,if(i==i2,b,f[i]*m1 + dec)));\ |
||
22 | };\ |
||
23 | a_gauche={(a,b,c)->(b[1]-a[1])*(c[2]-a[2])>(b[2]-a[2])*(c[1]-a[1]);}\ |
||
24 | /* 1 si le point c est à gauche (au sens strict) de la droite orientee ab*/\ |
||
25 | tout_a_droite(a,b,poly)={\ |
||
17213 | bpr | 26 | /* 1 si tous les sommets de poly sont à droite (au sens large)\ |
27 | de la droite orientee ab */\ |
||
16886 | bpr | 28 | for (k=1,#poly,if(a_gauche(a,b,poly[k]),return(0)));\ |
29 | 1;\ |
||
30 | };\ |
||
31 | interieur(pt,poly)={\ |
||
32 | /* 1 si le point pt est dans le polygone convexe ouvert dont le bord oriente\ |
||
33 | est donne par le vecteur de points poly*/\ |
||
34 | for (k=2,#poly,if(a_droite(poly[k-1],poly[k],pt),return(0)));\ |
||
17213 | bpr | 35 | a_droite(poly[#poly],poly[1],pt)==0\ |
16886 | bpr | 36 | };\ |
37 | intersecte(pol1, pol2)={\ |
||
38 | /* 1 si les deux polygones convexes ouverts ont une intersection non vide*/\ |
||
39 | for (k=2,#pol1,if(tout_a_droite(pol1[k-1],pol1[k],pol2),return(0)));\ |
||
40 | if (tout_a_droite(pol1[#pol1],pol1[1],pol2),return(0));\ |
||
41 | for (k=2,#pol2,if(tout_a_droite(pol2[k-1],pol2[k],pol1),return(0)));\ |
||
42 | tout_a_droite(pol2[#pol2],pol2[1],pol1)==0;\ |
||
43 | };\ |
||
44 | /* m est la matrice d'adjacence d'un graphe de sommets 1..#m,\ |
||
45 | un arbre couvrant est une fonction de 1..#m dans lui-même qui 'aboutit' toujours à #m*/\ |
||
46 | \ |
||
47 | arbres_couvrants(m,but)={\ |
||
17213 | bpr | 48 | /* si but == 0, renvoie le nombre total d'arbres couvrants\ |
49 | sinon, renvoie le but-ieme arbre couvrant */\ |
||
16886 | bpr | 50 | my(k=1,l=1,n,v=vector(#m,x,x),nb=0);\ |
51 | while(k,\ |
||
52 | if(m[k,l],\ |
||
53 | n=l;while(v[n]!=n,n=v[n]);if(n!=k,v[k]=l;if(k==#m-1,\ |
||
54 | nb+=1; if(nb==but, return(v)),k+=1;l=0)));\ |
||
55 | while(k>1&&l==#m,v[k]=k;k-=1;l=v[k]);if(l==#m,k-=1,v[k]=k;l+=1));\ |
||
56 | nb;\ |
||
57 | };\ |
||
58 | arbre_couvrant_aleatoire0(m)={arbres_couvrants(m,1+random(arbres_couvrants(m,0)));};\ |
||
59 | arbre_couvrant_aleatoire1(m)={\ |
||
60 | my (n=#m, m1 = matrix(n,n),v=vector(n), reste=n, start=n, next1);\ |
||
61 | for (l = 1, n,\ |
||
62 | k = 0;\ |
||
17213 | bpr | 63 | for (c = 1, n, if (m[l, c], k += 1; m1[l, k] = c)); /* calcul de nombre de voisins)*/\ |
16886 | bpr | 64 | m1[l, n] = k;\ |
65 | );\ |
||
66 | v[n] = n;\ |
||
67 | while (reste > 1,\ |
||
68 | next1 = m1[start,1+random(m1[start,n])];\ |
||
69 | if (v[next1]==0, v[next1]=start; reste -=1);\ |
||
70 | start = next1;\ |
||
71 | );\ |
||
72 | v;\ |
||
73 | };\ |
||
74 | arbre_couvrant_aleatoire2(m)={\ |
||
75 | /* Le même algo, implementation plus simple un peu moins efficace ?*/\ |
||
76 | my (n=#m, v=vector(n), reste=n, start=n, next1=n);\ |
||
77 | v[n] = n;\ |
||
78 | while (reste > 1,\ |
||
79 | until (m[start,next1], next1 = 1+random(n));\ |
||
80 | if (v[next1]==0, v[next1]=start; reste-=1);\ |
||
81 | start = next1;\ |
||
82 | );\ |
||
83 | v;\ |
||
84 | };\ |
||
85 | arbre_couvrant_aleatoire(m)={arbre_couvrant_aleatoire2(m);}\ |
||
86 | {pred=(v,k)->v[if(k>2,k-1,#v)];}\ |
||
87 | {succ=(v,k)->v[if(k<#v,k+1,2)];}\ |
||
88 | \ |
||
17167 | bpr | 89 | /* retourne l'indice dans f1 et f2\ |
90 | des sommets communs à f1 et f2 s'ils existent et 0 sinon*/\ |
||
17189 | bpr | 91 | adj(f1,f2)={my(ns1=f1[1]+1,ns2=f2[1]+1);\ |
92 | for(i=2,ns1,for(j=2,ns2,\ |
||
17167 | bpr | 93 | if(f1[i]==f2[j],\ |
17189 | bpr | 94 | if(pred(f1,i)==succ(f2,j),return([if(i>2,i-1,ns1),if(j<ns2,j+1,2),i,j]));\ |
95 | if(succ(f1,i)==pred(f2,j),return([i,j,if(i<ns1,i+1,2),if(j>2,j-1,ns2)]));\ |
||
16886 | bpr | 96 | return(0))));\ |
97 | 0;\ |
||
98 | };\ |
||
17167 | bpr | 99 | /* retourne les numéros des deux sommets communs à f1 et f2 s'ils existent et 0 sinon*/\ |
17189 | bpr | 100 | adj1(f1,f2)={my(ns1=f1[1]+1,ns2=f2[1]+1);\ |
101 | for(i=2,ns1,for(j=2,ns2,\ |
||
17167 | bpr | 102 | if(f1[i]==f2[j],\ |
103 | if(pred(f1,i)==succ(f2,j),return([pred(f1,i),f1[i]]));\ |
||
104 | if(succ(f1,i)==pred(f2,j),return([f1[i],succ(f1,i)]));\ |
||
105 | return(0))));\ |
||
106 | 0\ |
||
107 | };\ |
||
108 | adjacence={f->matrix(#f,#f,i,j,adj1(f[i],f[j]));};\ |
||
16886 | bpr | 109 | etale(v,f,f2,ns)={\ |
110 | /* v est un arbre couvrant du graphe des faces,\ |
||
17213 | bpr | 111 | // f contient la liste des numeros des sommets des faces en 3D\ |
112 | // f2 contient les coordonnees 2D d'une projection\ |
||
113 | // ns est le nombre de sommets du polyedre\ |
||
114 | // le resultat est le polygone generalise (2D)\ |
||
115 | // si le deploiement associe est injectif\ |
||
16886 | bpr | 116 | // 0 sinon. */\ |
117 | my(p,r,nbs,l,n1=f[#f][1],\ |
||
118 | pat=vector(#f),s2D=matrix(2*ns-2,3),f2D=vector(#f));\ |
||
16944 | bpr | 119 | f2D[#f]=vector(n1+1,x,if(x==1,n1,x-2));\ |
16886 | bpr | 120 | pat[#f]=r=f2[#f];\ |
121 | for(k=1,#f2[#f],s2D[k,1]=r[k][1];s2D[k,2]=r[k][2];s2D[k,3]=f[#f][k+1]);\ |
||
122 | nbs = n1;\ |
||
123 | for(kk=1,#f-1,\ |
||
124 | while(f2D[kk]==0,\ |
||
125 | l=kk; while(f2D[v[l]]==0,l=v[l]);\ |
||
126 | [i1,j1,i2,j2]=adj(f[l],f[v[l]]);\ |
||
127 | n1=f[l][1];\ |
||
16944 | bpr | 128 | r=deplacement_poly(s2D[f2D[v[l]][j1]+1,1..2],s2D[f2D[v[l]][j2]+1,1..2],f2[l],i1-1,i2-1);\ |
17222 | bpr | 129 | for (t=1,#f,if(pat[t] && intersecte(pat[t],r),print("pseudonet")));\ |
16886 | bpr | 130 | pat[l]=r;\ |
131 | rr=vector(n1+1);\ |
||
132 | rr[1]=n1;\ |
||
133 | rr[i1]=f2D[v[l]][j1];\ |
||
134 | rr[i2]=f2D[v[l]][j2];\ |
||
135 | for(k=2,n1+1,if(k!=i1 && k!=i2,\ |
||
16944 | bpr | 136 | rr[k]=nbs; nbs+=1; s2D[nbs,1]=r[k-1][1];s2D[nbs,2]=r[k-1][2];s2D[nbs,3]=f[l][k]));\ |
16886 | bpr | 137 | f2D[l]=rr));\ |
138 | return([s2D,f2D,pat]);\ |
||
17167 | bpr | 139 | };\ |
17213 | bpr | 140 | /* v est un arbre couvrant du graphe de matrice d'adjacence m\ |
141 | ns est le nombre de sommets\ |
||
142 | renvoie l'arbre couvrant dual */\ |
||
17167 | bpr | 143 | dual(v,m,ns)={\ |
144 | my(m1=matrix(ns,ns),s1,s2);\ |
||
145 | for(i=1,#m,for(j=1,#m,\ |
||
146 | if(m[i,j],m1[m[i,j][1]+1,m[i,j][2]+1]=1)));\ |
||
147 | for(l=1,#m-1,[s1,s2]=m[l,v[l]];m1[s1+1,s2+1]=m1[s2+1,s1+1]=0);\ |
||
148 | /* m1 est maintenant la matrice d'adjacence de l'arbre cherché*/\ |
||
149 | arbre_couvrant_aleatoire1(m1);\ |
||
150 | };\ |
||
17213 | bpr | 151 | /* renvoie l'indice de s dans la face f, s'il existe, 0 sinon*/\ |
152 | cherche(f,s)={for(j=2,f[1]+1,if(f[j]==s,return(j)));0};\ |
||
153 | /* dit si f contient le couple (s,t)*/\ |
||
154 | cherche2(f,s,t)={for(j=2,f[1]+1,if(f[j]==s,return(succ(f,j)==t)));0};\ |
||
17167 | bpr | 155 | ffdual(ff,ns)={\ |
156 | my(res=vector(ns),s,t,u);\ |
||
157 | for(i=1,ns,s=i-1;\ |
||
158 | for(j=1,#ff,if(f=cherche(ff[j],s),\ |
||
159 | t=pred(ff[j],f);\ |
||
160 | u=succ(ff[j],f);\ |
||
161 | l=List([j-1]);\ |
||
162 | while(t!=u,for(k=1,#ff,if(cherche2(ff[k],s,t),\ |
||
163 | listput(l,k-1);t=pred(ff[k],cherche(ff[k],s));break)));\ |
||
164 | break));\ |
||
165 | res[i]=concat([#l],Vec(l)));\ |
||
166 | matconcat(res~)\ |
||
16886 | bpr | 167 | }; |