From 4a030fcab21d7bf8937b305f0f43c69d1da2d3d3 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 13 Nov 2017 23:49:06 +0000 Subject: repere (13nov17) git-svn-id: svn://tug.org/texlive/trunk@45779 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/metapost/repere/README.md | 2 +- .../texmf-dist/doc/metapost/repere/repere-doc.pdf | Bin 428827 -> 456296 bytes .../texmf-dist/doc/metapost/repere/repere-doc.tex | 82 +++++++- Master/texmf-dist/metapost/repere/repere.mp | 212 +++++++++++++++++++-- 4 files changed, 270 insertions(+), 26 deletions(-) (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/metapost/repere/README.md b/Master/texmf-dist/doc/metapost/repere/README.md index 4af59b21bfb..51ec41481bc 100644 --- a/Master/texmf-dist/doc/metapost/repere/README.md +++ b/Master/texmf-dist/doc/metapost/repere/README.md @@ -1,4 +1,4 @@ -Package repere - Version 17.11 - November 6, 2017 +Package repere - Version 17.11.2 - November 12, 2017 This package provides MetaPost macros for drawing sec­ondary school math­e­mat­ics figures in a coordinate system : - axis, grids diff --git a/Master/texmf-dist/doc/metapost/repere/repere-doc.pdf b/Master/texmf-dist/doc/metapost/repere/repere-doc.pdf index bd1df01be57..ab144948041 100644 Binary files a/Master/texmf-dist/doc/metapost/repere/repere-doc.pdf and b/Master/texmf-dist/doc/metapost/repere/repere-doc.pdf differ diff --git a/Master/texmf-dist/doc/metapost/repere/repere-doc.tex b/Master/texmf-dist/doc/metapost/repere/repere-doc.tex index 84248a2c5d5..f2e4d1f9397 100644 --- a/Master/texmf-dist/doc/metapost/repere/repere-doc.tex +++ b/Master/texmf-dist/doc/metapost/repere/repere-doc.tex @@ -853,6 +853,8 @@ fin; \subsection{Interpolation} + + \MP{} propose les commandes suivantes (qui peuvent être combinées dans une même courbe) : \begin{description} @@ -860,11 +862,14 @@ fin; \item[A..B..C..] Courbe de Bézier passant par les points $A$, $B$, $C$... \end{description} -\verb|repere.mp| propose aussi les commandes suivantes : +\subsubsection*{Interpolation polynomiale} +\verb|repere.mp| propose aussi les commandes ci-dessous (pas toujours la meilleure méthode d'approximation...). À compiler avec \verb|mpost -numbersystem="decimal" fichier.mp| pour gagner en précision. \begin{description} -\item[lagrange(A,B,C,...)] Courbe passant par $A$, $B$, $C$... représentant le polynôme de degré maximal $n-1$ tel que $P(x_A)=y_A$, $P(x_B)=y_B$... -\item[lagrange(x1,y1,x2,y2,x3,y3...)] Courbe passant par les points $(x_1;y_1)$, $(x_2;y_2)$, $(x_3;y_3)$... représentant le polynôme de degré maximal $n-1$ tel que $P(x_i)=y_i$. +\item[lagrange(A,B,C,...)()] Courbe passant par $A$, $B$, $C$... représentant le polynôme de degré maximal $n-1$ tel que $P(x_A)=y_A$, $P(x_B)=y_B$... sur l'intervalle définissant le repère. +\item[lagrange(A,B,C,...)(xmin,xmax)] Même courbe que précédemment mais sur l'intervalle $[xmin;xmax]$. +\item[lagrange(x1,y1,x2,y2,x3,y3...)()] Courbe passant par les points $(x_1;y_1)$, $(x_2;y_2)$, $(x_3;y_3)$... représentant le polynôme de degré maximal $n-1$ tel que $P(x_i)=y_i$ sur l'intervalle définissant le repère. +\item[lagrange(x1,y1,x2,y2,x3,y3...)(xmin,xmax)] Même courbe que précédemment mais sur l'intervalle $[xmin;xmax]$. \end{description} \begin{exemple}[0.55] @@ -873,8 +878,8 @@ pair A[],B[]; A[1]=(1,1);A[2]=(3,5);A[3]=(5,8); A[4]=(7,2);A[5]=(9,4); B[1]=(1,6);B[2]=(3,7);B[3]=(6,4);B[4]=(8,9); -path L;L=lagrange(A[1],A[2],A[3],A[4],A[5]); -path C;C=lagrange(1,6,3,7,6,4,8,9); +path L;L=lagrange(A[1],A[2],A[3],A[4],A[5])(); +path C;C=lagrange(1,6,3,7,6,4,8,9)(0,8); draw quadrillage(1,1); draw axes(1,1); draw L epaisseur 1 couleur rouge; @@ -888,21 +893,51 @@ fin; \begin{description} -\item[hermite((x1,y1,y'1),(x2,y2,y'2)...)] Courbe passant par les points $(x_1;y_1)$, $(x_2;y_2)$, $(x_3;y_3)$... représentant le polynôme de degré maximal $2n-1$ tel que $P(x_i)=y_i$ et $P'(x_i)=y'_i$. -\item[hermite(A,y'A,B,y'B,C,y'C...)] Courbe passant par les points $A$, $B$, $C$... représentant le polynôme de degré maximal $2n-1$ tel que $P(x_A)=y_A$ et $P'(x_A)=y'_A$... +\item[hermite((x1,y1,y'1),(x2,y2,y'2)...)()] Courbe passant par les points $(x_1;y_1)$, $(x_2;y_2)$, $(x_3;y_3)$... représentant le polynôme de degré maximal $2n-1$ tel que $P(x_i)=y_i$ et $P'(x_i)=y'_i$ sur l'intervalle définissant le repère. +\item[hermite((x1,y1,y'1),(x2,y2,y'2)...)(xmin,xmax)] Même courbe que précédemment mais sur l'intervalle $[xmin;xmax]$. +\item[hermite(A,y'A,B,y'B,C,y'C...)()] Courbe passant par les points $A$, $B$, $C$... représentant le polynôme de degré maximal $2n-1$ tel que $P(x_A)=y_A$ et $P'(x_A)=y'_A$... sur l'intervalle définissant le repère. +\item[hermite(A,y'A,B,y'B,C,y'C...)(xmin,xmax)] Même courbe que précédemment mais sur l'intervalle $[xmin;xmax]$. +\end{description} + +\begin{exemple}[0.55] +repere.orth(-1,10,7cm,-1,10); +draw quadrillage(1,1); +draw axes(1,1); +path H;H=hermite((1,2,0.5),(4,8,0),(8,2,2))(); +draw H epaisseur 1 couleur bleu; +draw tangente.double(H,1) couleur bleu; +draw tangente.double(H,4) couleur bleu; +draw tangente.double(H,8) couleur bleu; +pair A,B,C; A:=(1,8);B:=(4,4);C:=(7,6); +path I;I=hermite(A,-1,B,0.5,C,2)(0,7.5); +draw I epaisseur 1 couleur rouge; +draw tangente.double(I,1) couleur rouge; +draw tangente.double(I,4) couleur rouge; +draw tangente.double(I,7) couleur rouge; +fin; +\end{exemple} + + +\subsubsection*{Interpolation à l'aide de splines cubiques} + +\begin{description} +\item[splineder(A,y'A,B,y'B,C,y'C...)()] Courbe passant par les points $A$, $B$, $C$ représentant une fonction cubique par morceaux telle que $f(x_A)=y_A$ et $f'(x_A)=y'_A$ sur l'intervalle définissant le repère. +\item[splineder(A,y'A,B,y'B,C,y'C...)(xmin,xmax)] Même courbe que précédemment mais sur l'intervalle $[xmin;xmax]$. +\item[splineder(xA,yA,y'A,xB,yB,y'B,...)()] Même courbe que précédemment (sur l'intervalle définissant le repère) mais les valeurs sont données sous forme de liste. +\item[splineder(xA,yA,y'A,xB,yB,y'B,...)(xmin,xmax)] Même courbe que précédemment mais sur l'intervalle $[xmin;xmax]$. \end{description} \begin{exemple}[0.55] repere.orth(-1,10,7cm,-1,10); draw quadrillage(1,1); draw axes(1,1); -path H;H=hermite((1,2,0.5),(4,8,0),(8,2,2)); +path H;H=splineder(1,2,0.5,4,8,0,8,2,2)(); draw H epaisseur 1 couleur bleu; draw tangente.double(H,1) couleur bleu; draw tangente.double(H,4) couleur bleu; draw tangente.double(H,8) couleur bleu; pair A,B,C; A:=(1,8);B:=(4,4);C:=(7,6); -path I;I=hermite(A,-1,B,0.5,C,2); +path I;I=splineder(A,-1,B,0.5,C,2)(0,7.5); draw I epaisseur 1 couleur rouge; draw tangente.double(I,1) couleur rouge; draw tangente.double(I,4) couleur rouge; @@ -910,6 +945,35 @@ draw tangente.double(I,7) couleur rouge; fin; \end{exemple} + + +\begin{description} +\item[spline(A,B,C...)()] Courbe passant par les points $A$, $B$, $C$ représentant une fonction cubique par morceaux telle que $f(x_A)=y_A$, $f(x_B)=y_B$... sur l'intervalle définissant le repère. +\item[spline(A,B,C...)(xmin,xmax)] Même courbe que précédemment mais sur l'intervalle $[xmin;xmax]$. +\item[spline(xA,yA,xB,yB,xC,yC,...)()] Même courbe que précédemment (sur l'intervalle définissant le repère) mais les valeurs sont données sous forme de liste. +\item[spline(xA,yA,xB,yB,xC,yC...)(xmin,xmax)] Même courbe que précédemment mais sur l'intervalle $[xmin;xmax]$. +\end{description} + +\begin{exemple}[0.55] +repere.orth(-1,10,7cm,-1,10); +pair A[],B[]; +A[1]=(1,1);A[2]=(3,5);A[3]=(5,8); +A[4]=(7,2);A[5]=(9,4); +B[1]=(1,6);B[2]=(3,7);B[3]=(6,4);B[4]=(8,9); +path L;L=spline(A[1],A[2],A[3],A[4],A[5])(); +path C;C=spline(1,6,3,7,6,4,8,9)(0,8); +draw quadrillage(1,1); +draw axes(1,1); +draw L epaisseur 1 couleur rouge; +draw C epaisseur 1 couleur bleu; +for i=1 upto 5: nomme.llft(A[i]) couleur rouge; +endfor +for i=1 upto 4: nomme.llft(B[i]) couleur bleu; +endfor +fin; +\end{exemple} + + \section{Suites} \begin{description} \item[suite(u,deb,fin)] figure formée des points $(i;u_i)$ pour $i$ variant entre \verb+deb+ et \verb+fin+. diff --git a/Master/texmf-dist/metapost/repere/repere.mp b/Master/texmf-dist/metapost/repere/repere.mp index f12b866c56e..2c568e3884c 100644 --- a/Master/texmf-dist/metapost/repere/repere.mp +++ b/Master/texmf-dist/metapost/repere/repere.mp @@ -2,7 +2,7 @@ %% repere.mp %% %% Macros pour la construction de figures dans un repère %% %% o.peault@posteo.net %% -%% Version 17.11 (Novembre 2017) %% +%% Version 17.11.2 (Novembre 2017) %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This work may be distributed and/or modified under the conditions of @@ -1318,6 +1318,17 @@ vardef courbef_(suffix f)(expr xmin, xmax, n) = %Courbe représentative d'une enddef; +vardef courbef_l(suffix f)(expr xmin, xmax, n) = %Courbe représentative d'une fonction + save $,x; + path $; + $=((xmin,f(xmin)) + for i=1 upto n-1: + ...(xmin+i*(xmax-xmin)/(n-1),f(xmin+i*(xmax-xmin)/(n-1))) + endfor ); + $ +enddef; + + vardef courbefonc(suffix f)(text t)= save cc;path cc; save k,Val;numeric k,Val[]; @@ -1331,6 +1342,19 @@ vardef courbefonc(suffix f)(text t)= enddef; +vardef courbefoncl(suffix f)(text t)= + save cc;path cc; + save k,Val;numeric k,Val[]; + Val[1]:=Xmin;Val[2]:=Xmax;Val[3]:=100; + k:=1; + for i=t: + Val[k]:=i; + k:=k+1; + endfor + courbef_l(f,Val[1],Val[2],Val[3]) +enddef; + + vardef courbepoints(suffix f)(expr xmin, xmax, n) = %Points non reliés @@ -1437,19 +1461,22 @@ enddef; %Novembre 2017 vardef polynomelagrange(text t)(expr x)= + save tmp; + numeric tmp; for i=t: - if pair i: polynomelagrangept(t)(x) - else: polynomelagrangeval(t)(x) - fi - exitif true + if pair i: tmp:=polynomelagrangept(t)(x) + else: tmp:=polynomelagrangeval(t)(x) + fi; + exitif true; endfor + tmp enddef; %Novembre 2017 -vardef lagrange(text t)= +vardef lagrange(text t)(text q)= vardef _tmp_poly_lag(expr x)= polynomelagrange(t)(x) enddef; - courbefonc(_tmp_poly_lag)() + courbefonc(_tmp_poly_lag)(q) enddef; @@ -1476,33 +1503,186 @@ enddef; %Novembre 2017 vardef polynomehermiteptder(text t)(expr x)= -save tmp,k,j,re,gr,bl; -color tmp[];numeric k,j,re,gr,bl; +save tmp,k,j,re,gr,bl,i; +color tmp[];numeric k,j,re,gr,bl,i; k:=0;j:=0; for i=t: if pair i: re:= xpart i; gr:= ypart i else: bl:=i; k:=k+1; tmp[k]=(re,gr,bl) fi; endfor -polynomehermite(tmp[1] for ii=2 upto k: ,tmp[ii] endfor)(x) +polynomehermitetriplet(tmp[1] for ii=2 upto k: ,tmp[ii] endfor)(x) enddef; %Novembre 2017 vardef polynomehermite(text t)(expr x)= + save tmp; + numeric tmp; for i=t: - if color i: polynomehermitetriplet(t)(x) - else: polynomehermiteptder(t)(x) - fi - exitif true + if color i: tmp:=polynomehermitetriplet(t)(x) + else: tmp:=polynomehermiteptder(t)(x) + fi; + exitif true; endfor + tmp enddef; %Novembre 2017 -vardef hermite(text t)= +vardef hermite(text t)(text q)= vardef _tmp_poly_her(expr x)= polynomehermite(t)(x) enddef; - courbefonc(_tmp_poly_her)() + courbefoncl(_tmp_poly_her)(q) +enddef; + + +% Novembre 2017 +vardef spcuhezz (expr t)= 2*(t**3)-3*(t**2)+1 enddef; +vardef spcuheuz (expr t)= t**3-2*(t**2)+t enddef; +vardef spcuhezu (expr t)= -2*(t**3)+3*(t**2) enddef; +vardef spcuheuu (expr t)= t**3-t**2 enddef; + + +% Novembre 2017 +vardef splinecubique (expr xa,ya,da,xb,yb,db)(expr x)= +% On donne deux points et les dérivées en ces points + save t; + numeric t; + t=(x-xa)/(xb-xa); + (spcuhezz(t))*ya + (spcuheuz(t))*da*(xb - xa) + (spcuhezu(t))*yb + (spcuheuu(t))*db*(xb - xa) +enddef; + +% Novembre 2017 +vardef splineinterpolderfonct_coul(text t)(expr x)= +% On donne points et dérivées sous forme de triplets (x,y,y') + save pta,ptb,prem,sortie; + color pta,ptb; + boolean prem,sortie; + prem:=true;sortie:=false; + for i=t: + if prem: ptb:=i; prem:=false + else: + pta:=ptb; + ptb:=i; + if x< redpart ptb: sortie:=true fi; + fi; + exitif sortie; + endfor + splinecubique(redpart pta, greenpart pta, bluepart pta,redpart ptb, greenpart ptb, bluepart ptb)(x) +enddef; + +% Novembre 2017 +vardef splineinterpolderfonct_pt(text t)(expr x)= +% On donne points et dérivées sous forme de liste (A,y'A,B,y'B...) + save tmp,k,re,gr,bl; + color tmp[]; + numeric re,gr,bl,k; + k:=0; + for i=t: + if pair i: k:=k+1; re:= xpart i; gr:= ypart i + else: bl:=i; tmp[k]:=(re,gr,bl) + fi; + endfor + splineinterpolderfonct_coul(tmp[1] for ii=2 upto k: ,tmp[ii] endfor)(x) +enddef; + +% Novembre 2017 +vardef splineinterpolderfonct_listeval(text t)(expr x)= +% On donne points et dérivées sous forme de liste de valeurs (xA,yA,y'A,xB,yB,y'B...) + save tmp,k,j,re,gr,bl; + color tmp[]; + k:=0;j:=0; + for i=t: + if j=0: re:= i; j:=1 + elseif j=1: gr:=i; j:=2 + else: bl:=i; tmp[k]:=(re,gr,bl); j:=0;k:=k+1 + fi; + endfor + splineinterpolderfonct_coul(tmp[0] for ii=1 upto k-1: ,tmp[ii] endfor)(x) +enddef; + + +% Novembre 2017 +vardef splinederfonct(text t)(expr x)= + save tmp; + numeric tmp; + for i=t: + if color i: tmp:=splineinterpolderfonct_coul(t)(x) + elseif pair i: tmp:=splineinterpolderfonct_pt(t)(x) + else: tmp:=splineinterpolderfonct_listeval(t)(x) + fi; + exitif true; + endfor + tmp +enddef; + +% Novembre 2017 +vardef splineder(text t)(text q)= + vardef _tmp_poly_splineder(expr x)= splinederfonct(t)(x) enddef; + courbefoncl(_tmp_poly_splineder)(q) enddef; +% Novembre 2017 +vardef deriveesplinecubique(suffix k)(suffix xs,ys)(expr n)= +% renvoie les dérivées pour interpolation avec splines cubiques +% source : https://en.wikipedia.org/wiki/Spline_interpolation +% xs[] et ys[] sont des listes, n est le nombre de valeurs +% Renvoie les dérivées dans la liste k[] + (2k[0] + k[1])/(xs[1] - xs[0]) = 3(ys[1]-ys[0])/((xs[1]-xs[0])**2); + for i=1 upto n-1: + k[i-1]/(xs[i] - xs[i-1]) + 2k[i]/(xs[i] - xs[i-1]) + 2k[i]/(xs[i+1] - xs[i]) + k[i+1]/(xs[i+1] - xs[i]) = 3(ys[i] - ys[i-1])/((xs[i]-xs[i-1])**2) + 3(ys[i+1] - ys[i])/((xs[i+1]-xs[i])**2); + endfor + (k[n-1] + 2k[n])/(xs[n]-xs[n-1]) = 3(ys[n]-ys[n-1])/((xs[n]-xs[n-1])**2); +enddef; + +% Novembre 2017 +vardef splineinterpolfonct_pt(text t)(expr x)= +% t est la liste des points A,B,C... + save xa,ya,dd,n; + numeric xa[],ya[],dd[],n; + n:=-1; + for i=t: + n := n + 1; + xa[n] := xpart i; ya[n] := ypart i; + endfor + deriveesplinecubique(dd)(xa,ya)(n); + splinederfonct((xa[0],ya[0],dd[0]) for ii=1 upto n: , (xa[ii],ya[ii],dd[ii]) endfor)(x) +enddef; + +vardef splineinterpolfonct_listeval(text t)(expr x)= +% t est la liste des valeurs (x1,y1,x2,y2,x3,y3...) + save xa,ya,tmp,k,j; + numeric xa,ya,k,j; + pair tmp[]; + k:=0;j:=0; + for i=t: + if j=0: xa:= i + else: ya:=i; tmp[k]:= (xa,ya); k:= k+1 + fi; + j:=1-j; + endfor + splineinterpolfonct_pt(tmp[0] for ii=1 upto k-1: ,tmp[ii] endfor)(x) +enddef; + +% Novembre 2017 +vardef splinefonct(text t)(expr x)= + save tmp; + numeric tmp; + for i=t: + if pair i: tmp:=splineinterpolfonct_pt(t)(x) + else: tmp:=splineinterpolfonct_listeval(t)(x) + fi; + exitif true; + endfor + tmp +enddef; + +% Novembre 2017 +vardef spline(text t)(text q)= + vardef _tmp_poly_spline(expr x)= splinefonct(t)(x) enddef; + courbefonc(_tmp_poly_spline)(q) +enddef; + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3