1)des discontinuités
2)des exclusions éventuelles (symbolisées par des demi-cercles)
2)de la non dérivabilité éventuelle aux bornes (cas où diff renvoie undef ou inf)
Voici donc le programme que j'ai testé en modifiant dans tous les sens ceci:
f(x):=piecewise(x<-5,2*sqrt(-x-5),x<=0,1-sqrt(-x),x<4,2*sqrt(x)-1,x<=6,4-x/4,x<=8,x-8,4-2*sqrt(x-6));
Graphe_piecewise();
Il est fort possible que des erreurs apparaissent sur d'autres exemples mais j'en ai appris un peu plus sur Xcas.
Code : Tout sélectionner
Rayon():={
//détermination du rayon des demi-cercles
//on cherche la longueur minimale des segments
//en excluant les extrémités
local k,X1,Y1,X2,Y2,L,T,s;
L:=NULL;
T:=f(x);
s:=size(f(x));
si s=3 alors
return 2;//modifier 2 ?
fsi;
si s>=4 alors
pour k de 1 jusque (s-3)/2 faire
X1:=T[2k-1][1];
X2:=T[2k+1][1];
Y1:=subst(T[2k+2],x=X1);
Y2:=subst(T[2k+2],x=X2);
L:=L,longueur(point(X1,Y1),point(X2,Y2));
fpour;
si s<8 alors return min(L)/10;sinon return min(L)/5;fsi;
//modifier 8,10,5 ?
fsi;
}
:;
Demi_cercle_gauche(a,E,b):={
local R,m,A,C;
R:=Rayon();
m:=evalf(subst(diff(E,x),x=a));
A:=point(a,subst(E,x=a));
//tester si m=undef ou m=inf
si type(m)!=DOM_IDENT et type(m)!=DOM_SYMBOLIC alors
C:=point(a-R/sqrt(1+m^2),subst(E,x=a)-R*m/sqrt(1+m^2));
return plot(E,x=a..b),cercle(C,R,-pi/2+arctan(m),pi/2+arctan(m));sinon
si subst(E,x=a)-subst(E,x=b)<0 alors
m:=inf;
C:=point(a,subst(E,x=a)-R);
return plot(E,x=a..b),cercle(C,R,-pi/2+arctan(m),pi/2+arctan(m));sinon
m:=inf;
C:=point(a,subst(E,x=a)+R);
return plot(E,x=a..b),cercle(C,R,-pi/2-arctan(m),pi/2-arctan(m));
fsi;
fsi;
}
:;
Demi_cercle_droite(a,E,b):={
local R,m,B,C;
R:=Rayon();
m:=evalf(subst(diff(E,x),x=b));
B:=point(b,subst(E,x=b));
//tester si m=undef ou m=inf
si type(m)!=DOM_IDENT et type(m)!=DOM_SYMBOLIC alors
C:=point(b+R/sqrt(1+m^2),subst(E,x=b)+R*m/sqrt(1+m^2));
return plot(E,x=a..b),cercle(C,R,pi/2+arctan(m),3*pi/2+arctan(m));sinon
si subst(E,x=a)-subst(E,x=b)>0 alors
m:=inf;
C:=point(b,subst(E,x=b)-R);
return plot(E,x=a..b),cercle(C,R,-pi/2+arctan(m),pi/2+arctan(m));sinon
m:=inf;
C:=point(b,subst(E,x=b)+R);
return plot(E,x=a..b),cercle(C,R,-pi/2-arctan(m),pi/2-arctan(m));
fsi;
fsi;
}
:;
Graphe_piecewise():={
local T,s,L,k;
affichage(epaisseur_ligne_3);
T:=f(x);L:=NULL;
s:=size(f(x));
si s=3 alors
si simplifier(subst(T[2],x=T[1][1])-subst(T[3],x=T[1][1]))!=0 et T[1][0]=='>' alors
L:=L,Demi_cercle_droite(T[1][1]-5,T[2],T[1][1]);
fsi;
si simplifier(subst(T[2],x=T[1][1])-subst(T[3],x=T[1][1]))!=0 et T[1][0]=='>=' alors
L:=L,Demi_cercle_gauche(T[1][1],T[3],T[1][1]+5);
fsi;
return L:=L,plot(T[2],x=T[1][1]-5..T[1][1]),plot(T[3],x=T[1][1]..T[1][1]+5);
fsi;
si s>=4 alors
si simplifier(subst(T[2],x=T[1][1])-subst(T[4],x=T[1][1]))!=0 et T[1][0]=='>' alors
L:=L,Demi_cercle_droite(T[1][1]-5,T[2],T[1][1]);
fsi;
si simplifier(subst(T[s-1],x=T[s-2][1])-subst(T[s],x=T[s-2][1]))!=0 et T[s-2][0]=='>=' alors
L:=L,Demi_cercle_gauche(T[s-2][1],T[s],T[s-2][1]+5);
fsi;
si simplifier(subst(T[s-1],x=T[s-2][1])-subst(T[s],x=T[s-2][1]))!=0 et T[s-2][0]=='>' alors
L:=L,Demi_cercle_droite(T[s-4][1],T[s-1],T[s-2][1]);
fsi;
L:=L,plot(T[2],x=T[1][1]-5..T[1][1]),
plot(T[s],x=T[s-2][1]..T[s-2][1]+5);
pour k de 2 jusque (s-1)/2 faire
si simplifier(subst(T[2k-2],x=T[2k-3][1])-subst(T[2k],x=T[2k-3][1]))!=0 et T[2k-3][0]=='>=' alors
L:=L,Demi_cercle_gauche(T[2k-3][1],T[2k],T[2k-1][1]);
fsi;
si k!=(s-1)/2 alors
si simplifier(subst(T[2k],x=T[2k-1][1])-subst(T[2k+2],x=T[2k-1][1]))!=0 et T[2k-1][0]=='>' alors
L:=L,Demi_cercle_droite(T[2k-3][1],T[2k],T[2k-1][1]);
fsi;
fsi;
L:=L,plot(T[2k],x=T[2k-3][1]..T[2k-1][1]);
fpour;
return L;
fsi;
}
:;