1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
unit uTraceCourbe;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, Buttons;
type
TfrmTraceCourbe = class(TForm)
boutonCourbe: TSpeedButton;
Image1: TImage; // On trace la courbe sur un BitMap qu'on place dans Image1
// l'intérêt du BitMap est de pouvoir être ensuite facilement manipulé :
// envoi via le presse-papier, sauvegarde sur disque, insertion sous Word etc.
bAgrandirY: TSpeedButton;
bAjusterCourbe: TSpeedButton;
bReduireY: TSpeedButton;
procedure boutonCourbeClick(Sender: TObject);
procedure bAgrandirYClick(Sender: TObject); // Agrandit l'échelle Y
procedure bReduireYClick(Sender: TObject); // Réduit l'échelle Y
procedure bAjusterCourbeClick(Sender: TObject); // Rend Echelle Y égale à celle des X
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;
var
frmTraceCourbe: TfrmTraceCourbe;
implementation
{$R *.DFM}
type tFonc = function (X : Extended) : Extended;
// ici la collection de fonctions du type y:=f(x)
function y1(x : Extended) : Extended;
begin Result:=x*x-6*x+5; end;
function y2(x : Extended) : Extended;
begin Result:=sin(x); end;
type oCourbe = object
F : tFonc; Affichee : boolean;
kx,ky : real; // coeff échelle des Y et des X
DeX,JusquaX : Extended;
bmpCourbe : tBitMap;
Larg,Haut : integer;
cCourbe : tColor;
procedure init( iFun : tfonc; iLarg,iHaut : integer;
iDeX,iJusquaX : Extended; // courbe tracée depuis x=iDeX jusqu'à x=iJusquaX
coulCourbe : tColor);
procedure CreebmpCourbe;
procedure Affiche;
procedure ReAffiche;
procedure free;
end;
procedure oCourbe.init( iFun : tfonc; iLarg,iHaut : integer;
iDeX,iJusquaX : Extended;
coulCourbe : tColor);
begin F:=iFun;
Larg:=iLarg; Haut:=iHaut;
ky:=150; // coeff d'échelle Y donné à priori, mais réglable par boutons
DeX:=iDeX;
JusquaX:=iJusquaX;
cCourbe:=coulCourbe;
end;
procedure oCourbe.CreebmpCourbe;
label Saut;
var bmp : tBitMap;
rr : tRect; i,yO,xO,yec,xec,yecF1,yecF2,yecFF,iCoul : integer;
xf,yf : Extended; //= x et y de la fonction F
ex,courbeInvisible : boolean;
plagex : Extended;
begin bmp := tBitMap.create;
bmp.width:=Larg;
bmp.height:=Haut;
bmp.pixelformat := pf24bit;
with bmp.canvas do
begin Pen.mode:=pmcopy;
Pen.Width:=1;
Brush.Color:=clWhite;
rr:=rect(0,0,bmp.width,bmp.height);
FillRect(rr);
yO:=bmp.height div 2;
pen.color:=clBlack;
MoveTo(35,yO); LineTo(bmp.width-5,yO); // axe des X
moveTo(bmp.width-25,yO+2); lineTo(bmp.width-5,yO);
moveTo(bmp.width-25,yO-2); lineTo(bmp.width-5,yO);
textOut(bmp.width-25,yO+8,'x');
textOut(5,yO-7,'f(x) = 0');
if (JusquaX<=0) and (DeX<=0)
then plagex:=abs(JusquaX)-abs(DeX)
else plagex:=JusquaX-DeX;
kx:=bmp.width/plagex;
xO:=round(kx*(0 - DeX));
yecFF:=0;
if xO>35 then // axe des Y
begin moveTo(xO,yecFF+5); lineTo(xO,bmp.height-10);
moveTo(xO-2,yecFF+20); lineTo(xO,yecFF+5);
moveTo(xO+2,yecFF+20); lineTo(xO,yecFF+5);
textOut(xO+8,yecFF+15,'y');
end;
// Tracé courbe :
courbeInvisible:=true; ex:=true;
Saut :
for xec:=0 to bmp.width-1 do
begin xf:=DeX+xec/kx;
try yf:=F(xf); //
yec:=yO-round(ky*yf);
if (yec<0) or (yec>bmp.height-1) then ex:=true;
if (yec>=0) and (yec<=bmp.height-1) then
begin if ex
then begin ex:=false; moveTo(xec,yec); end
else begin pen.color:=cCourbe;
lineTo(xec,yec); courbeInvisible:=false;
end;
end;
except
bmpCourbe:=bmp; EXIT;
end;
end;
if courbeInvisible then begin ky:=ky/2; goto Saut; end;
end;
bmpCourbe:=bmp;
end; // oCourbe.CreebmpCourbe(icCourbe
procedure oCourbe.Affiche;
begin CreebmpCourbe;
frmTraceCourbe.Image1.Picture.Graphic:=bmpCourbe;
frmTraceCourbe.Image1.visible:=true;
Affichee :=true;
end;
procedure oCourbe.ReAffiche;
begin with frmTraceCourbe.Image1 do
if visible then
begin Picture.Graphic.CleanupInstance; bmpCourbe.free; CreebmpCourbe;
Picture.Graphic:=bmpCourbe;
end;
end;
procedure oCourbe.free;
begin Affichee :=false;
bmpCourbe.Free;
end;
// Utilisation de l'objet oCourbe
var Courbe : oCourbe;
procedure TfrmTraceCourbe.BoutonCourbeClick(Sender: TObject);
var FF: tFonc;
begin FF:=y1; // <- Première fonction
//FF:=y2; // <- Deuxième fonction
Courbe.init( FF, frmTraceCourbe.Image1.width, frmTraceCourbe.Image1.height,
-20,20.5, clRed);
Courbe.Affiche;
end;
procedure TfrmTraceCourbe.bAgrandirYClick(Sender: TObject);
begin with Courbe do begin ky:=ky*2; ReAffiche; end; end;
procedure TfrmTraceCourbe.bReduireYClick(Sender: TObject);
begin with Courbe do begin ky:=ky/2; ReAffiche; end; end;
procedure TfrmTraceCourbe.bAjusterCourbeClick(Sender: TObject);
begin with Courbe do begin ky:=kx; ReAffiche; end; end;
end. |