Clebsch, ses 27 droites, les points de Eckardt
Le programme suivant a été développé afin de tracer les différents éléments explicités dans le paragraphe correspondant du site de Robert Ferréol sur la surface de Clebsch
Surface de Clebsch à 7 points de Eckardt à distance finie | |||
Surface opaque
|
Surface transparente
|
Droites seules |
Plans de Sylvester |
ou | |||
| |||
Surface opaque
|
Surface transparente
|
Droites seules |
Plans de Sylvester |
ou |
I. Plans de Sylvester, points de Eckardt, droites diagonales, droites de Schlafli
restart: # =========== passage équations de droites en paramétrique [x(t),y(t),z(t)] parametrage:= proc(L) local n,i,j,k,tamp, uu,vv,ww; global t: tamp:=NULL: t:='t': n:=nops(L): for i from 1 to n do uu:=convert(L[i],list): vv:=uu: for j from 1 to 3 do if lhs(uu[j])=rhs(uu[j]) then if lhs(uu[j])=x then vv[1]:=t: elif lhs(uu[j])=y then vv[2]:=t: else vv[3]:=t : fi; ww:=subs(uu[j]=NULL,uu); for k from 1 to 2 do if lhs(ww[k])=x then vv[1]:= subs(y=t,z=t,rhs(ww[k])): elif lhs(ww[k])=y then vv[2]:= subs(x=t,z=t,rhs(ww[k])): else vv[3]:= subs(x=t,y=t,rhs(ww[k])): fi; od: fi; od: tamp:=tamp,vv: od: [tamp]; end: # ====== PS[1..5] les 5 plans de Sylvester ========== PS:=[seq([ x[i]=0 ,convert(subsop(i=NULL,[seq(x[j], j= 1..5 )]),`+`)=0],i=1..5)]: |
# ===== DE[i] les 10 "droites de Sylvester" DE:='DE': for i from 1 to 4 do for j from i+1 to 5 do DE[i,j]:=[ x[i]=0 , x[j] =0 ,convert(subsop(i=NULL,j=NULL,[seq(x[j], j= 1..5 )]),`+`)=0]; od: od: #print(DE); |
# ====== Pts_eck les 10 points de Eckardt ========== pt:='pt': for i from 1 to 3 do for j from i+1 to 4 do for k from j+1 to 5 do pt[i,j,k]:=[x[i]=0,op(2,DE[i,j]),op(2,DE[i,k]), subs(x[i]=0,op(2,DE[i,j]),op(2,DE[i,k]),add(x[l],l=1..5))=0]: od;od:od: Pts_eck:=convert(pt,set): pt:='pt': #nops(Pts_eck); print(Pts_eck); |
# ====== droites diagonales ========== # ***** DD[i,j] i=1..5, j=1..3 tamp:=NULL: DD:=NULL: dep:={seq(x[j], j= 1..5 )}: for i from 1 to 5 do reste:=subs(dep[i]=NULL,dep); tamp:=dep[i]: un:= reste[1]: reste:=subs(reste[1]=NULL,reste); for j from 1 to 3 do deux:=reste[j]: reste1:=subs(deux=NULL,reste): DD:=DD,[tamp,un+reste[j],convert(reste1,`+`)] od: od: DD:=[DD]: |
# ====== droites de Schlafli ========== # ***** Sch1, Sch2 , 1 <= i < = 6 Sch1:=NULL: Sch2:=NULL: fip:=(1+sqrt(5))/2: fim:=(1-sqrt(5))/2: for i from 1 to 3 do for j from i+1 to 4 do reste:=subs(x[i]=NULL,x[j]=NULL,[x[1],x[2],x[3],x[4]]): Sch1:=Sch1,[x[i]+fip*x[j]+reste[1],fip*x[i]+x[j]+reste[2],-fip*(x[i]+x[j])+x[5]]: Sch2:=Sch1,[x[i]+fim*x[j]+reste[1],fim*x[i]+x[j]+reste[2],-fim*(x[i]+x[j])+x[5]]: od: od: Sch1:=[Sch1]: Sch2:= [Sch2]: |
penta:=[add(x[i]^3, i= 1..5),add(x[i], i= 1..5 )]: |
II. Recherche de solutions à 10 points de Eckardt à distance finie
quelques exemples
#tr:= [x[1] = X, x[2] = Y, x[3] = Z, x[4] = T+X+2*Y+3*Z] ;#10 Eck #tr:= [x[1] = X, x[2] = Y, x[3] = Z, x[4] = T+X-2*Y+2*Z] ;#10 Eck #tr:= [x[1] = X-2*Y+Z, x[2] = X+Y-2*Z, x[3] = Y+Z-2*X, x[4] = T+X] ;#10 Eck #tr:= [x[1] = X, x[2] = Y, x[3] = Z, x[4] =-T+X+2*Y+3*Z] ;#10 Eck #tr:= [x[1] = X, x[2] = Y, x[3] = Z, x[4] =-T-X-Y-Z] ;#4 eck 24 dr #tr:= [x[1]=(-3*X+Y+Z+T)/4,x[2]=(X-3*Y+Z+T)/4,x[3]=(X+Y-3*Z+T)/4,x[4] =(X+Y+Z-T)/2] ;#Ferreol 7 Eck 27 dr #tr:=[x[1] = X+Y, x[2] = Y+Z, x[3] = Z+X, x[4] = T-1*(X+Y+Z)];# forme à 7 pts concise #tr:=[x[1] = -3^(1/2)*Y+X+1/4*Z, x[2] = 3^(1/2)*Y+X+1/4*Z, x[3] = -2*X+1/4*Z, x[4] = 3/4*Z+T];# mienne à 7 termes #tr:= [x[1]=(-9*X+3*Y+3*Z+T)/4,x[2]=(3*X-9*Y+3*Z+T)/4, # x[3]=(3*X+3*Y-9*Z+T)/4,x[4]=(3*X+3*Y+3*Z-T)/2];#hunt #tr:=[x[1]=-X+Y+Z,x[2] =-Y+Z+T,x[3]=X-Z+T,x[4]=T-(X+Y+Z)];#10 eck ,peu dissymétrique #tr:=[x[1] = -2*X+Y, x[2] = -2*Y+Z, x[3] = -2*Z+X, x[4] = T+Z];#10 eck ,peu dissymétrique #tr:=[x[1]=-X+2*Y+T,x[2] =-Y+2*Z+T,x[3]=2*X-Z+T,x[4]=X+Y];#10 eck |
#============= essai de coordonnées ===================== mat:='mat': tr:=[x[1] = -2*X+Y, x[2] = -2*Y+Z, x[3] = -2*Z+X, x[4] = T+Z]; liste:=map(rhs,tr): liste:=map(u ->[coeff(u,X),coeff(u,Y),coeff(u,Z),coeff(u,T)],liste) : mat:=matrix(4,4,liste): poss:=linalg[det](mat): if poss=0 then printf("%s\n", "Incorrect : Changement de variables non bijectif "): else printf("%s\n", "Correct : Changement de variables bijectif "): fi; |
eq3:=subs(op(tr),penta[1]): eq4:=subs(op(tr),penta[2]): solx5:=solve(eq4,{x[5]}): pass_dir:= op(tr),op(solx5) ; SH:=subs(solx5,eq3): pts:=subs(pass_dir,Pts_eck): ptsnew:=[seq(solve({op(pts[i])},{X,Y,Z,T}),i=1..nops(pts))]: print("nombre de Eckardt ( dist. finie ou non) = ",nops(pts)): tamp:=NULL: for i from 1 to nops(ptsnew) do if not(has(ptsnew[i],'T=0')) then tamp:=tamp,ptsnew[i] fi; od: ptsreels:=[tamp]: print("nombre de Eckardt à dist. finie = ",nops(ptsreels)); if nops(pts)=10 then verif:= [seq(has(ptsnew[i],'T=0'),i=1..nops(ptsnew))]; print(verif); if has(verif,true)then printf("%a ne marche pas,%a points de Eckardt à distance finie \n",tr,nops(ptsreels)) else printf("%a, marche : 10 pts de Eckardt à distance finie\n",tr): fi: else printf("%a ne marche pas\n",tr) fi: S:= subs(X=x,Y=y,Z=z,T=1,SH); eqE:=subs(X=x,Y=y,Z=z,T=1,ptsreels): Eck:={seq(solve({op(eqE[i])},{x,y,z}),i=1..nops(eqE))}: Eckardt:=map(u -> subs(op(u),[x,y,z]),Eck): #### print(DD); Ps:=subs(X=x,Y=y,Z=z,T=1,subs(pass_dir,PS)): Dd1:=subs(X=x,Y=y,Z=z,T=1,subs(pass_dir,DD)): Sc1:=subs(X=x,Y=y,Z=z,T=1,subs(pass_dir,Sch1)): Sc2:=subs(X=x,Y=y,Z=z,T=1,subs(pass_dir,Sch2)): DD1:=parametrage([seq(solve({op(Dd1[i])},{x,y,z}),i=1..nops(Dd1))]): SC1:=parametrage([seq(solve({op(Sc1[i])},{x,y,z}),i=1..nops(Sc1))]): SC2:=parametrage([seq(solve({op(Sc2[i])},{x,y,z}),i=1..nops(Sc1))]): S:=expand(S): printf("Surface = %a\n eq. développée = %a\n",SH,S/96); printf("Plans de Sylvester : %a\n",Ps); printf("Eckardt (%a) = %a \nDr. diagonales (%a) :\n%a\nDr. de Sclafli (%a) :\n%a\n%a\n" ,nops(Eckardt),Eckardt,nops(DD1),DD1,nops(SC1)+nops(SC2),SC1,SC2): |
Vérification éventuelle du double-six
Les droites du double-six sont mises bout à bout et les indices du double-six sont :
[1,2,3,4, 5, 6 ]
[7,8,9,10,11,12]
La vérification calcule les coordonnées des points d'intersection et les indices des droites correspondantes à ce point sous la forme :
[ [x,y,z], {indice droite 1,indice droite 2} ]
# les droites de Schlaefli sont SC1 et SC2: |
> | #### recherche du numéro d'ordre dans l'ensemble "droites" ##### numero:=proc(dr) local j: for j from 1 while (j<= nops(droites)) and evalb(droites[j]<>dr) do od: j; end: #### Numéros d'ordre d'une partie de l'ensemble "droites" ###### ordre_partie:= proc(partie,affichage::{0,1}) local ordre,i: ordre:=[seq(0,i=1..nops(partie))]: for i from 1 to 6 do ordre[i]:=numero(partie[i]); od: if affichage = 1 then printf("Numéros des droites %a",ordre); |
> | for i from 1 to nops(ordre) do print(partie[i],"___",droites[ordre[i]]) od; fi; ordre; end: |
#### 0 pas d'affichage, 1 affichage des points ptscom:=proc(tot,affichage::{0,1}) local i,j,n,sol,pts ,w: n:=nops(tot):pts:=NULL: for i from 1 to n-1 do for j from i+1 to n do sol:=[solve({op(expand(tot[i]-subs(t=w,tot[j])))}, {t,w})]: if sol<>[] then pts:=pts,[radnormal(subs(op(sol),tot[i]),'rationalized'),{i,j}] fi; od; od: pts:=[pts]: if affichage =1 then printf(" Nombre de droites = %d\n",nops(tot)); printf("Nombre de points d'intersection = %a %s",nops(pts), "--- [ point,[n° dr1, n° dr2] dans l'ens. donné]"); print(pts); fi; pts; end: |
# ====== faire effectuer l'instruction suivante désirée ============ |
> | #### points communs de toutes les droites pts_dble_six:=ptscom([op(SC1),op(SC2)],1): |
> |
# =============== tracés =============== with(plots): dx:=-4: fx:=4: dy:=-4: fy:= 4: dz:=-4: fz:=4: dt:=-4: ft:=4: g_surf:=implicitplot3d(S,x=dx..fx,y=dy..fy,z=dz..fz,grid=[40,40,40],style=patchnogrid): g_diag:=spacecurve({op(DD1)},t=dt..ft,numpoints=2,color=blue,thickness=3): g_sc1:=spacecurve({op(SC1)},t=dt..ft,numpoints=2,color=red,thickness=3): g_sc2:=spacecurve({op(SC2)},t=dt..ft,numpoints=2,color=red,thickness=3): plotsetup(inline): display([g_surf,g_diag,g_sc1,g_sc2],scaling=constrained,lightmodel=light2,view=[dx..fx,dy..fy,dz..fz],orientation=[0,75]); #display([g_diag,g_sc1,g_sc2],scaling=constrained,lightmodel=light2,view=[dx..fx,dy..fy,dz..fz],orientation=[0,75]); |