Télécharger le
fichier Maple "zippé"

 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



Les mêmes images que celles qui sont en fin du programme Maple, obtenues avec PovRay à partir des mêmes données.
les droites "diagonales" sont en cyan, les 12 droites de Schlafli en rouge.

Télécharger le fichier Povray correspondant à la surface de Clebsch  forme usuelle

Télécharger le fichier Povray correspondant à la surface de Clebsch  à 10 points de Eckardt


Surface de Clebsch à 7 points de Eckardt à distance finie

Surface opaque


voir en 800x600

Surface transparente


voir en 800x600

Droites seules


voir en 800x600

Plans de Sylvester


voir en 800x600

ou  
fond blanc


Surface de Clebsch à 10 points de Eckardt à distance finie

Surface opaque


voir en 800x600

Surface transparente


voir en 800x600

Droites seules


voir en 800x600

Plans de Sylvester


fond couleur

ou  
fond blanc



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 )]:



Début  

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]);



Début