4859

Спектральный анализ кусочно-линейных функций с разрывами

Лабораторная работа

Информатика, кибернетика и программирование

Спектральный анализ кусочно-линейных функций с разрывами Цель работы Разработать приложение Спектральный анализ кусочно-линейных функций с разрывами. Разработать собственный компонент и использовать его в разработанном приложении. Задание к ла...

Русский

2012-11-28

183.5 KB

6 чел.

Спектральный анализ кусочно-линейных функций с разрывами

Цель работы

Разработать приложение Спектральный анализ кусочно-линейных функций  с разрывами. Разработать собственный компонент и использовать его в разработанном приложении.

Задание к лабораторной работе

1. Используя рекомендованную литературу, изучить технику отладки приложений для Windows в инструментальной среде Delphi .

2. Изучить приложение "Спектральный анализ кусочно-линейных функций с разрывами", приведенное в методичке 3804.

3. Разработать таблицу свойств графических компонентов, из которых построен интерфейс приложения "Спектральный анализ кусочно-линейных функций с разрывами". В таблице указать названия компонентов, свойства компонентов, а также устанавливаемые значения свойств. Достаточно указать лишь те свойства, значения которых необходимо установить, исходя из постановки задачи спектрального анализа кусочно-линейных функций с разрывами.

4. Разработать таблицу событий, связанных с графическими компонентами, из которых построен интерфейс приложения "Спектральный анализ кусочно-линейных функций с разрывами". В таблице указать названия компонентов, используемые события, а также имена процедур-обработчиков событий.

5. Выполнить визуальное проектирование графического интерфейса, а также редактирование и отладку программного кода приложения "Спектральный анализ кусочно-линейных функций с разрывами".

6. Создать собственный визуальный компонент.

7. Запустить приложение "Спектральный анализ кусочно-линейных функций с разрывами" и выполнить эксперименты по заданию функций и получению их спектра (гармонических составляющих).

8. Составить отчет по работе, включающий постановку задачи, интерфейс приложения, таблицу свойств и событий графических компонентов, листинг программного кода, а также выводы по работе.

Теоретический материал

Спектром функции времени Y(t) называют совокупность ее гармонических составляющих (гармоник). В случае периодической  функции Y(t) гармонические составляющие образуют ряд Фурье, конечный отрезок которого имеет вид

где Y0=M0/2 – постоянная составляющая,  – гармоники, t – время, Mk – амплитуда, Qk – фазовый угол (рад), f1 =1/Т – частота первой гармоники, Т – период повторения функции Y(t), m – количество гармоник.

Спектральный анализ периодической  функции Y(t) заключается в нахождении коэффициентов Фурье Аk и Вk , которые определяют неизвестные параметры гармоник, а именно: амплитуду  и фазу . Если Y(t) является кусочно-линейной функцией с разрывами и может быть синтезирована из треугольников, прямоугольников и трапеций, то коэффициенты Фурье Аk, Вk и постоянная составляющая M0 вычисляются по точным формулам следующего вида [8]:

В приведенных формулах используются значения функции Y(t) в точках ti  (i=0,2,…,N), которые образуются на временной оси путем разбиения интервала [0,Т] на N равных частей величиной t = T/N, т.е. ti = ti. Промежуточная переменная z  обозначает произведение z = f1kt.

Каждое значение функции Y(t) задается моментом времени ti и двумя значениями: Y(ti–0) слева и Y(ti+0) справа, где 0 понимается как бесконечно малое приращение. Если Y(ti–0) = Y(ti+0), то в точке ti зависимость Y(t) не имеет разрыва. Если в точке ti имеется разрыв, то он задается соответствующими значениями функции до и после разрыва.

Приложение "Спектральный анализ кусочно-линейных функций с разрывами" разработано в среде Delphi 7 в виде приложения SDI. Оно обеспечивает получение спектра функций, которые задаются таблично в равноотстоящих точках времени известного интервала [0,Т]. Предполагается, что интервал [0,Т] разбивается не более чем на 10  равных частей величиной t (Nmax=10). В таблицу заносятся только ненулевые значения функции. Получаемый спектр функций ограничивается семью гармониками (m=7).

Выполнение работы

Таблица 1. Свойства графических компонентов

Компонент

Свойство

Значение свойства

Form1(TForm)

Caption

Спектральный анализ кусочно-линейных функций с разрывами

StringGrid1(TStringGrid)

RowCount

12

StringGrid1(TStringGrid)

ColCount

3

StringGrid1(TStringGrid)

Options.GoEding

True

StringGrid1(TStringGrid)

Options.GoTabs

True

Lbl1(TLabel)

Caption

Задание функции

Lbl2(TLabel)

Caption

Время

Lbl3(TLabel)

Caption

Значение

Lbl4(TLabel)

Caption

Секунд

CountBtn1(TCountBtn)

Caption

Выполнить

CountBtn1(TCountBtn)

Count

0

CountBtn1(TCountBtn)

MaxType

8

CountBtn1(TCountBtn)

ShowType

CountToCaption

Button2

Caption

Выход

Таблица 2. События графических компонентов

Компонент

Событие

Form1

OnCreate

Button2

OnClick

CountBtn1

OnClick

PaintBox1

OnPaint

Листинг программы:

unit Unit1;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, StdCtrls, ExtCtrls, Grids, CountBtn;

type

 TForm1 = class(TForm)

   StringGrid1: TStringGrid;

   Button2: TButton;

   PaintBox1: TPaintBox;

   lbl1: TLabel;

   lbl2: TLabel;

   lbl3: TLabel;

   lbl4: TLabel;

   CountBtn1: TCountBtn;

   procedure FormCreate(Sender: TObject);

   procedure CountBtn1Click(Sender: TObject);

   procedure Button2Click(Sender: TObject);

   procedure PaintBoxPaint(Sender: Tobject);

 

 private

   { Private declarations }

 public

   { Public declarations }

 end;

const

 RowCount=12; //количество строк таблицы StringGrid

 HarmCount=8; //количество гармоник +1

var

 Form1: TForm1;

 //дискретные значения времени

 MasT: array[1..RowCount-1] of Real;

 //значение функции в точках разрыва

 MasYl: array[1..RowCount-1] of Real;// левые

 MasYr: array[1..RowCount-1] of Real;// правые

implementation

{$R *.dfm}

procedure FuncSpectr;

var

 l,p: Integer; //левый нижний угол области вывода

 w,h: Integer; //ширина и высота области вывода

 t: Real; //время

 tmax: Real; // верхняя граница времени

 dt: Real; //приращение

 Ymax: Real; //верхнее значение функции

 N: integer; // количество точек задания фунуции

 Harm1, Harm2: array[1..HarmCount] of Real;// значение гармоник спектра

 A,A1,A2,B,B1,B2,M: array[0..HarmCount] of Real;// амплитуды гармоник

 Q: array [0..HarmCount] of Real; // фазы гармоник

 f1:Real;// частота первой гармоники

 mt,mr: Real; // масштабы

 cx0,cy0:Integer;//координаты начала координат графиков функции

 chy0: array[0..HarmCount] of Integer;//и спектра

 cy: Integer;// текущая Y координата

 z: Real; // вспомогательные переменные

 i,k: Integer;

begin

// область вывода граффиков

with Form1.PaintBox1 do

begin

Canvas.Pen.Color:=clBlack;

Canvas.Brush.Color:=clWhite;

Canvas.Rectangle(0,0,Width,Height);

l:=70;//x координата левого верхнего угла

 p:=Height-20;// y координата левого верхнего угла

 h:=Height-50;// высота

 w:=Width-85;// ширина

 end;

// количество точек задания функции

N:=1;

while (MasT[N+1]>MasT[N]) and (N<RowCount-1) do

N:=N+1;

//спектральный анализ кусочно-линейной функции с разрывами

if N>1 then

begin

 tmax:=MasT[N];

 f1:=1/tmax;

 dt:=(MasT[N]-MasT[1])/(N-1);

 M[0]:=0;

 for i:=1 to N do

 M[0]:=M[0]+MasYl[i]+MasYr[i];

 M[0]:=M[0]/2/N;

 for k:=1 to HarmCount do

  begin

  z:=Pi*f1*k*dt;

  A1[k]:=0;

  A2[k]:=0;

  B1[k]:=0;

  B2[k]:=0;

  for i:=1 to N do

   begin

   A1[k]:=A1[k]+MasYl[i]*Sin(2*z*i)-MasYr[i]*Sin(2*z*(i-1));

   A2[k]:=A2[k]+MasYl[i]-MasYr[i]*Sin(z*(2*i-1));

   B1[k]:=B1[k]+MasYl[i]*Cos(2*z*(i-1))-MasYr[i]*Cos(2*z*i);

   B2[k]:=B2[k]+MasYl[i]-MasYr[i]*Cos(z*(2*i-1));

   end;

  A[k]:=A1[k]/z/N-Sin(z)*A2[k]/Sqr(N)/N;

  B[k]:=B1[k]/z/N+Sin(z)*B2[k]/Sqr(N)/N;

  M[k]:=Sqrt(Sqr(A[k])+Sqr(B[k]));

  if A[k]<>0 then

  Q[k]:=-ArcTan(B[k]/A[k]);

  end;

 end;

// максимальное значение функции

 Ymax:=0;

 for i:=1 to N do

begin

  if Abs(MasYl[i]) > Ymax then Ymax:=Abs(MasYl[i]);

  if Abs(MasYr[i]) > Ymax then Ymax:=Abs(MasYr[i]);

end;

// масштабы

 mr:=(h-20)/(2+2*HarmCount);   // относительных единиц по Y-координате                            // по Y-координате

 if N>1 then mt:=(w-15)/tmax;  // времени по X-координате

 with Form1.PaintBox1.Canvas do

begin

  // разметка осей для графика функции

  // вертикальная ось

  cx0:=l;

  cy:=p-h;

  TextOut(cx0+w div 4,cy-25,'Функция');

  MoveTo(cx0,cy); LineTo(cx0,cy+Round(2*mr));

  MoveTo(cx0-3,cy); LineTo(cx0+3,cy);

  TextOut(cx0-20,cy-7,'+1');

  cy0:=cy+Round(mr);

  TextOut(cx0-63,cy0-10,'Y(t)/Ymax');

  // горизонтальная ось

  MoveTo(cx0,cy0); LineTo(cx0+w,cy0);

  if N>1 then

  for i:=1 to N do

  begin

    MoveTo(cx0+Round(MasT[i]*mt),cy0-3);

    LineTo(cx0+Round(MasT[i]*mt),cy0+3);

    if (i<>1) and (i mod 2 = 1) then

    TextOut(cx0+Round(MasT[i]*mt)-7,cy0+2,FloatToStr(MasT[i]));

  end;

  TextOut(w+70,cy0+2,'t');

  cy:=cy0+Round(mr);

  MoveTo(cx0-3,cy); LineTo(cx0+3,cy);

  TextOut(cx0-20,cy-7,'-1');

  // разметка осей для графиков спектра

  cy:=cy+30;

  TextOut(cx0+w div 5,cy-20,'Спектр функции');

  MoveTo(cx0,cy); LineTo(cx0,p+10);

  for k:=0 to HarmCount do

  begin

    MoveTo(cx0-3,cy); LineTo(cx0+3,cy);

    chy0[k]:=cy+Round(mr);

    TextOut(cx0-45,chy0[k]-7,'Y'+IntToStr(k)+'/M1');

    MoveTo(cx0,chy0[k]); LineTo(cx0+w,chy0[k]);

    if N>1 then

    begin

      MoveTo(cx0+Round(tmax*mt),chy0[k]-3);

      LineTo(cx0+Round(tmax*mt),chy0[k]+3);

    end;

    TextOut(w+70,chy0[k]+2,'t');

    cy:=chy0[k]+Round(mr);

  end;

  MoveTo(cx0-3,cy); LineTo(cx0+3,cy);

  // построение графика функции

  Pen.Color:=clRed;

  Pen.Width:=2;

  MoveTo(cx0,cy0);

  if Ymax<>0 then

  for i:=1 to N do

  begin

    LineTo(cx0+Round(MasT[i]*mt),cy0-Round((MasYl[i]/Ymax)*mr));

    MoveTo(cx0+Round(MasT[i]*mt),cy0-Round((MasYl[i]/Ymax)*mr));

    LineTo(cx0+Round(MasT[i]*mt),cy0-Round((MasYr[i]/Ymax)*mr));

    MoveTo(cx0+Round(MasT[i]*mt),cy0-Round((MasYr[i]/Ymax)*mr));

  end;

  Pen.Width:=1;

  // построение графиков спектра

  t:=0;

  dt:=0.001;

  if (N>1) and (M[1]<>0) then

  begin

    MoveTo(cx0,chy0[0]-Round(M[0]/M[1]));

    LineTo(cx0+Round(tmax*mt),chy0[0]-Round(M[0]/M[1]));

    repeat

    for k:=1 to HarmCount do

      begin

        Harm2[k]:=(M[k]/M[1])*cos(2*Pi*k*f1*t+Q[k]);

        if t=0 then MoveTo(cx0+Round(t*mt),chy0[k]-Round(Harm2[k]*mr)) else

                   MoveTo(cx0+Round((t-dt)*mt),chy0[k]-Round(Harm1[k]*mr));

        LineTo(cx0+Round(t*mt),chy0[k]-Round(Harm2[k]*mr));

        Harm1[k]:=Harm2[k];

      end;

    t:=t+dt;

    until (t>=tmax);

  end;

end;

end;

procedure TForm1.FormCreate(Sender: Tobject);

var

 i: integer;

begin

 // количество столбцов таблицы StringGrid

 StringGrid1.ColCount:= 3;

 // разметка таблицы

 StringGrid1.ColCount:= 3;

 StringGrid1.Cells[0,0]:= '      t';

 StringGrid1.Cells[1,0]:= '  Y(t-0) ';

 StringGrid1.Cells[2,0]:= '  Y(t+0) ';

 for i:=1 to RowCount-1 do

 begin

   // заполнение таблицы нулями

   Form1.StringGrid1.Cells[0,i]:= '0';

   Form1.StringGrid1.Cells[1,i]:= '0';

   Form1.StringGrid1.Cells[2,i]:= '0';

   // инициализация массивов нулевыми значениями

   MasT[i]:=StrToFloat(Form1.StringGrid1.Cells[0,i]);

   MasYl[i]:=StrToFloat(Form1.StringGrid1.Cells[1,i]);

   MasYr[i]:=StrToFloat(Form1.StringGrid1.Cells[2,i]);

 end;

end;

procedure Tform1.CountBtn1Click(Sender: Tobject);

var

 i:integer;

begin

 for i:=1 to RowCount-1 do

 begin

   // обновление значений времени и функции

   MasT[i]:=StrToFloat(Form1.StringGrid1.Cells[0,i]);

   MasYl[i]:=StrToFloat(Form1.StringGrid1.Cells[1,i]);

   MasYr[i]:=StrToFloat(Form1.StringGrid1.Cells[2,i]);

    

 end;

 FuncSpectr;

end;

procedure Tform1.PaintBoxPaint(Sender: Tobject);

begin

 FuncSpectr;

end;

procedure Tform1.Button2Click(Sender: Tobject);

begin

 Application.Terminate;

end;

end.  

Создание нового визуального компонента

Для более детального изучения принципов  ООП введем новый визуальный компонент TCountBtn, наследник от TButton.

Новый компонент представляет собой кнопку, которая может выполнять свойства счетчика, а также может прервать работу с приложением при достижении определенного значения щелчков. Отображение количества щелчков на кнопке и максимальное количество щелчков задаются в инспекторе объектов.

Здесь можно увидеть один из принципов ООП: инкапсуляция: прямой доступ к объекту (экземпляру класса)  будет заменен на доступ к полям и методам через свойства.

Возможность создания производных от класса-потомка отражается в принципе наследования:

Листинг компонента TMyPanel:

unit CountBtn;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ExtCtrls;

type

TShowTp = (Normal, CountToCaption);

TCountBtn = class(TButton)

private

{ Private declarations }

FShowType:TShowTp;

FCount:integer;

FMaxType:integer;

protected

{ Protected declarations }

procedure Click;override;

public

{ Public declarations }

procedure ShowCount;

published

{ Published declarations }

property MaxType:integer read FMaxType write FMaxType;

property ShowType: TshowTp read FshowType write FShowType;

property Count:integer read FCount write FCount;

constructor Create(aowner:Tcomponent);override;

end;

procedure Register;

implementation

procedure Register;

begin

 RegisterComponents('Samples', [TCountBtn]);

end;

constructor TCountBtn.Create(aowner:Tcomponent);

begin

inherited create(Aowner);

end;

procedure Tcountbtn.Click;

begin

inherited click;

FCount:=Fcount+1;

if(FCount=FMaxType) then

ShowCount;

if ShowType = Normal then

Caption:=Caption;

if ShowType = CountToCaption then

Caption:=inttostr(count)+' клик(а/ов)';

end;

procedure TCountBtn.ShowCount;

begin

Showmessage(' Вы сделали: '+inttostr(FCount)+' клик(а/ов)');

Application.Terminate;

end;

end.

Рисунок 1. Приложение " Спектральный анализ кусочно-линейных функций  с разрывами "

Рисунок 2. Приложение " Спектральный анализ кусочно-линейных функций  с разрывами "

Максимальное количество щелчков

Рисунок 3. Окно инспектора объектов

Выводы

  1.  В данной работе были исследованы механизмы событий Windows и некоторые принципы ООП: инкапсуляция и наследование.
  2.  В результате выполнения работы было создано приложение «Спектральный анализ кусочно-линейных функций с разрывами».
  3.  Был разработан новый компонент, со своими методами, полями и свойствами, производный от класса TButton.