Funzioni che elaborano il valore dell'ampiezza di un segnale a forma d'onda nota in funzione del parametro tempo
//==============================================================================
// Forme d'onda
//==============================================================================
//------------------------------------------------------------------------------
// Onda quadra
//t: tempo in secondi
//Per: Periodo in secondi
//Amp: Ampiezza (Valore Massimo) in Volt
//Offset: scostamento dallo 0 in volt
function Quadra(t,Per,Amp,Offset:real):real;
begin
if frac(t/Per)>0.5 then
result:=-Amp+Offset
else
result:=Amp+Offset;
end;
//------------------------------------------------------------------------------
// Dente di sega
//t: tempo in secondi
//Per: Periodo in secondi
//Amp: Ampiezza (Valore Massimo) in Volt
//Offset: scostamento dallo 0 in volt
function DenteSega(t,Per,Amp,Offset:real):real;
begin
result:=-Amp+frac(t/Per)*Amp*2;
end;
//------------------------------------------------------------------------------
// Onda triangolare
//t: tempo in secondi
//Per: Periodo in secondi
//Amp: Ampiezza (Valore Massimo) in Volt
//Offset: scostamento dallo 0 in volt
function Triangolare(t,Per,Amp,Offset:real):real;
var
f:real;
begin
f:=frac(t/Per);
if f>0.5 then
result:=-Amp+(1-f)*Amp*4+Offset
else
result:=-Amp+f*Amp*4+Offset;
end;
//------------------------------------------------------------------------------
// Sinusoide
//t: tempo in secondi
//Per: Periodo in secondi
//Amp: Ampiezza (Valore Massimo) in Volt
//Offset: scostamento dallo 0 in volt
//Fase: sfasamento in radianti
function Sinusoide(t,Per,Amp,Offset,Fase:real):real;
begin
result:=Offset+Amp*sin(2*pi/Per*t+Fase);
end;
Disegna grafico dei dati presenti in una Stringgrid dentro un oggetto Image.
La prima colonna rappresenta l'asse x il resto delle colonne: le grandezze
nell'asse y
La prima riga viene considerata come intestazione delle grandezze rappresentate
nelle colonne.
//==============================================================================
// Grafico
//==============================================================================
procedure TForm1.Grafico(S:TStringGrid;I:TImage);
const
ytxtfmt='%5.2g';
xtxtfmt='%5.2g';
ColoreSf=clWhite;
ColoriY:array[1..4] of TColor=(clBlue,clRed,clGreen,clFuchsia);
MgSx =30;
MgDx =50;
MgSu =20;
MgGiu=35;
DivR =8;
DivC =10;
StepLeg=20;
var
MinX,MaxX:real;
MinY,MaxY:real;
MinY1,MaxY1:real;
MinY2,MaxY2:real;
n,m,x,y:integer;
dqy,dqx:integer;
kx,ky:real;
st:string;
x1,x2,y1,y2:integer;
procedure marker(x,y:integer);
const
sz=3;
begin
I.Canvas.Rectangle(x-sz,y-sz,x+sz,y+sz);
end;
function ElabMin(C:integer):real;
var
r:integer;
v:real;
begin
with S do
begin
result:=StrToFloat(Cells[C,1]);
for r:=2 to RowCount-1 do
begin
v:=StrToFloat(Cells[C,r]);
if v<result then
result:=v;
end;
end;
end;
function ElabMax(C:integer):real;
var
r:integer;
v:real;
begin
with S do
begin
result:=StrToFloat(Cells[C,1]);
for r:=2 to RowCount-1 do
begin
v:=StrToFloat(Cells[C,r]);
if v>result then
result:=v;
end;
end;
end;
begin
//Cancella grafico
I.Canvas.Brush.Color:=ColoreSf;
I.Canvas.Pen.Style:=psSolid;
I.Canvas.Pen.Color:=ClBlack;
I.Canvas.Rectangle(0,0,I.Width,I.Height);
//Elabora massimi e minini
MinX :=ElabMin(0);
MaxX :=ElabMax(0);
MinY :=ElabMin(1);
MaxY :=ElabMax(1);
for n:=2 to S.ColCount-1 do
begin
MinY1:=ElabMin(n);
if MinY>MinY1 then
MinY:=MinY1;
MaxY1:=ElabMax(n);
if MaxY<MaxY1 then
MaxY:=MaxY1
end;
//Disegna Reticolo
dqy:= (I.Height-MgSu-MgGiu) div DivR;
dqx:= (I.Width -MgSx-MgDx) div DivC;
ky:=dqy*DivR/(MaxY-MinY);
kx:=dqx*DivC/(MaxX-MinX);
I.Canvas.Pen.Style:=psDot;
I.Canvas.Pen.Color:=ClGray;
//Righe
for n:=0 to DivR do
begin
with I.Canvas do
begin
MoveTo(MgSx,I.Height-MgGiu-(n*dqy));
LineTo(MgSx+(DivC*dqx),I.Height-MgGiu-(n*dqy));
st:=Format(ytxtfmt,[MinY+(MaxY-MinY)*n/DivR]);
TextOut(MgSx-TextWidth(st)-2,I.Height-MgGiu-(n*dqy)-TextHeight(st) div 2-2,st);
end;
end;
//Colonne
for n:=0 to DivC do
begin
with I.Canvas do
begin
MoveTo(MgSx+(n*dqx),I.Height-MgGiu);
LineTo(MgSx+(n*dqx),I.Height-MgGiu-(DivR*dqy));
st:=Format(ytxtfmt,[MinX+(MaxX-MinX)*n/DivC]);
TextOut(MgSx+(n*dqx)-TextWidth(st) div 2,I.Height-MgGiu+4,st);
end;
end;
//Asse X
I.Canvas.TextOut(MgSx+(I.Width-MgSx-MgDx) div 2-I.Canvas.TextWidth(S.Cells[0,0]) div 2,
I.Height-I.Canvas.TextHeight(S.Cells[0,0])-2,
S.Cells[0,0]);
//Legenda
y:=MgSu+(I.Height-MgSu-MgGiu) div 2 - (S.ColCount-1) * StepLeg div 2;
x:=I.Width-MgDx+5;
I.Canvas.Pen.Style:=psSolid;
for n:=1 to S.ColCount-1 do
begin
with I.Canvas do
begin
Pen.Color:=clBlack;
TextOut(x,y+(n-1)*StepLeg,S.Cells[n,0]);
Pen.Color:=ColoriY[n];
MoveTo(x,y+(n-1)*StepLeg+TextHeight(S.Cells[n,0])+2);
LineTo(x+TextWidth(S.Cells[n,0]),y+(n-1)*StepLeg+TextHeight(S.Cells[n,0])+2);
end;
end;
I.Canvas.Pen.Color:=clBlack;
//Grafica
with I.Canvas do
begin
for n:=2 to S.RowCount-1 do
begin
for m:=1 to S.ColCount-1 do
begin
Pen.Color:=ColoriY[m];
x1:=MgSx+round((StrToFloat(S.Cells[0,n-1])-MinX)*kx);
y1:=I.Height-MgGiu-round((StrToFloat(S.Cells[m,n-1])-MinY)*ky);
x2:=MgSx+round((StrToFloat(S.Cells[0,n])-MinX)*kx);
y2:=I.Height-MgGiu-round((StrToFloat(S.Cells[m,n])-MinY)*ky);
if n=2 then
marker(x1,y1);
marker(x2,y2);
MoveTo(x1,y1);
LineTo(x2,y2);
end;
end;
end;
end;