Одно из наиболее востребованных применений компьютерной графики - построение графиков функций. Давайте нарисуем на экране синусоиду. Форма должна иметь вид, показанный на Рис. 7.6.
Рис. 11.6 Форма программы построения графика функции.
Сама программа расчета очевидна:
procedure TForm1.Button1Click(Sender: TObject);
VAR Xmin, Xmax, h, y : REAL;
cx,cy:REAL;
begin
TRY
Xmin:=StrToFLoat(LabeledEdit1.Text);
Xmax:=StrToFLoat(LabeledEdit2.Text);
h:=StrToFLoat(LabeledEdit3.Text)
EXCEPT
MessageDlg('Неверные данные', mtError, [mbOK],0);
Exit
END;
IF Xmax<=Xmin THEN
BEGIN
MessageDlg('Xmin>Xmax!', mtError, [mbOK],0);
Exit
END;
Memo1.Lines.Clear;
WITH Image1.Canvas DO
BEGIN
Brush.Color:=clBlue;
FillRect(Image1.ClientRect);
// Ось Х
Pen.Color:=clWhite;
MoveTo(0,Image1.Height DIV 2);
LineTo(Image1.Width, Image1.Height DIV 2);
cx:=(Xmax-Xmin)/Image1.Width;
cy:=2/Image1.Height;
IF cy>cx THEN
cx:=cy;
MoveTo(0,Image1.Height DIV 2); // начало графика
WHILE Xmin<=Xmax DO
BEGIN
y:=sin(xmin);
Memo1.Lines.Add('sin('+
FloatToStrF(Xmin,ffFixed,10,4)+')='+
FloatToStrF(y,ffFixed,10,4));
LineTo(TRUNC(Xmin/cx),
Image1.height DIV 2 - TRUNC(y/cx));
Xmin:=Xmin+h
END
END
end;
Остановимся на командах построения графика. Сначала мы заливаем весь холст синим цветом и проводим посередине горизонтальную белую линию – это ось ОХ. Затем необходимо рассчитать масштабные коэффициенты по осям координат, чтобы при любых значениях Xmin, Xmax и h график уместился в окне. Для функции sin(x) очевидно, что по оси OY ее значения будут изменяться от -1 до 1 (значение синуса достигает четырех только в военное время), а по оси ОХ – от Xmin до Xmax. Коэффициенты по осям будут равны:
;
Рис. 11.7 Результат построения синусоиды.
Из этих двух коэффициентов нужно выбратьнаибольший, тогда весь график гарантированно уместится на холсте. Далее для получения экранных координат текущие значения x и sin(x) надо разделить на рассчитанный ранее максимальный коэффициент. Наконец, при построении графика его надо сместить вниз на половину высоты холста, поскольку ось ОХ проходит посередине. Обратите внимание на использование функции TRUNC для получения целочисленных значений координат. Построенная синусоида показана на Рис. 7.7.
Было бы любопытно увидеть процесс постепенной отрисовки графика функции. График бы "полз", создавая иллюзию анимации. Попробуем поставить в цикл расчета функции команду задержки Sleep(100), останавливающую программу на 100мс:
. . .
WHILE Xmin<=Xmax DO
BEGIN
Sleep(100);
y:=sin(xmin);
. . .
Нажимаем F9, и… ничего не изменилось, только расчет стал выполняться медленнее, но график все равно отображается только в самом конце. Почему? Здесь мы столкнулись с одной важной особенностью программ на Delphi: при работе цикла никаких действий с элементами интерфейса не выполняется. Они как бы накапливаются и затем выполняются все сразу. Что же делать? Надо сказать Delphi, чтобы он не ленился и даже в цикле производил перерисовку нашего графика. Делается это просто – достаточно в теле цикла записать команду Application.ProcessMessages. Вот теперь все получилось, график красиво "ползет".