Построение графиков функций

К.т.н., доц. Троицкий Д.И.

Рассмотрено на заседании кафедры

"__" апреля 2003, протокол №___

Зав. кафедрой АСС д.т.н., проф.

_______________

Иноземцев А.Н.

Графика в Delphi

Хорошие снимки обычно делаются при закрытом объективе.

Из законов Мэрфи

Для вывода изображений на форме необходимо разместить один из графических компонентов. Графический компонент представляет собой окно со своей системой координат, в котором можно выполнять разнообразные построения. Проще всего использовать объект Image, находящийся на закладке Additional ( ). Поместите объект Image на форму (рис. 1).

Рис. 1 – Графический компонент Image.

В Image можно загрузить статическую картинку из файла в формате bmp, gif, jpeg, ico, wmf, emf. Для этого щелкните мышью по кнопке с тремя точками рядом со свойством Picture и в открывшемся окне нажмите кнопку Load. Свойство Stretch указывает, будет ли загруженная из файла картинка вписана в прямоугольник на форме (пусть даже с искажениями) или, если она больше, будет отображаться только ее кусочек. Свойство AutoSize позволяет автоматически подстроить размер компонента (высоту и ширину) под размер загруженной картинки. Однако при этом компонент может даже вылезти за пределы формы.

Простейшие построения

Части, которые просто нельзя собрать неправильно,

все же будут собраны неправильно.

Из законов Мэрфи.

Построение изображений из программы основано на вызове методов объекта Canvas (по англ. "холст"). У объекта Image есть свойство Canvas, поэтому запись команд рисования выглядит примерно так:

Image1.Canvas.команда;

Принцип рисования в Delphi заключается в том, что картинка строится пером (pen), которое перемещается по холсту, проводя на нем линии. Кроме пера, у холста еще есть кисть (brush), которой можно закрашивать большие области. Наконец, имеются отдельные команды для построения отрезков, прямоугольников, эллипсов (окружность – частный случай эллипса). Давайте нарисуем изображение, показанное на рис. 2.

Рис. 2 – Пример изображения.

Прежде всего надо понимать, что размер нашего поля рисования в пикселах – величина переменная. Пользователь может растянуть форму, поменять разрешение экрана и т.д. Поэтому ширину поля рисования нужно брать из свойства Image1.Width, а высоту – из свойства Image1.Height.

Как и обычно, процедуру рисования будем писать так, чтобы она вызывалась при нажатии на кнопку. Для этого поместим на форму кнопку "Рисовать". Процедура рисования будет выглядеть следующим образом:

procedure TForm1.Button1Click(Sender: TObject);

begin

WITH Image1.Canvas DO

BEGIN

Brush.Color:=clWhite;

Pen.Color:=clBlack;

FillRect(Image1.ClientRect);

MoveTo(0,Image1.Height DIV 2);

LineTo(Image1.Width,Image1.Height DIV 2);

MoveTo(Image1.Width DIV 2,0);

LineTo(Image1.Width DIV 2,Image1.Height);

Brush.Color:=clGreen;

Rectangle(Image1.Width DIV 2 - 50, Image1.Height DIV 2 - 50,

Image1.Width DIV 2 + 50, Image1.Height DIV 2 + 50);

Brush.Color:=clRed;

Ellipse(Image1.Width DIV 2 - 10, Image1.Height DIV 2 - 10,

Image1.Width DIV 2 + 10, Image1.Height DIV 2 + 10);

END

end;

Разберемся, что здесь написано. Оператор WITH "выносит за скобки" слова Image1.Canvas, чтобы их не приходилось писать в каждой строчке. Команды Brush.Color и Pen.Color задают будущие цвета заливки и контура, соответственно. Сами цвета обозначаются по их имени, перед которым идут буквы cl, например, clWhite, clRed, clGreen. Команда FillRect рисует закрашенный прямоугольник. Здесь она применена для очистки всего поля рисования, поэтому в качестве прямоугольника задается тот прямоугольник, который занимает весь объект Image1. Он хранится в свойстве ClientRect. Проще говоря, команда FillRect(Image1.ClientRect)заливает весь холст цветом заливки.

Рисование отрезка от точки x1,y1 в точку x2,y2 выполняется пером в два этапа. Сначала перо командой MoveTo(x1,y1) позиционируется без проведения линии в начальную точку отрезка, а затем отрезок проводится командой LineTo(x2,y2). Координаты начал и концов отрезков показаны на рис. 2, они легко вычисляются. Не забывайте, что координаты на экране могут быть только целыми, поэтому надо использовать операцию целочисленного деления DIV.

Команда Rectangle рисует прямоугольник с заданными цветами контура и заливки. Прямоугольник задается координатами концов любой его диагонали. В нашем случае длина стороны прямоугольника будет 20 пикселов и он строится симметрично относительно середины холста.

Команда Ellipse строит окружности и эллипсы. Параметры ее немного необычны – нужно указать координаты концов диагонали прямоугольника, в который будет вписан эллипс или окружность.

Порядок рисования фигур имеет значение. Если переставить местами команды Rectangle и Ellipse, то прямоугольник закроет собой окружность и вы ее никогда не увидите.

Помимо сплошной заливки, можно применять и другие ее виды (штриховка, точки и т.д.), меняя свойство Style объекта Brush:

Рис. 3 – Способы заливки.

Значение bsSolid соответствует сплошной заливке, bsClear – ее отсутствию, что позволяет рисовать незакрашенные фигуры.

Для линий свойство Pen.Style устанавливает вид линии:

psSolid сплошная линия
psDash пунктирная линия
psDot линия из точек
psDashDot штрих – пунктирная линия
psDashDotDot линия "тире – точка – точка"
psClear линия не рисуется (например, для построения объекта без контура)

Построение графиков функций

Если требуется провести прямую, получайте ее только по двум точкам.

Из законов Мэрфи

Одно из наиболее интересных применений графических средств Delphi – построение графиков функций. Давайте нарисуем на экране синусоиду, которую мы вычисляли на прошлой лабораторной работе. Форма должна иметь вид, показанный на рис. 4.

Рис. 4 – Форма программы построения графика функции.

Сама программа расчета не отличается от той, что мы делали в прошлый раз.

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. Коэффициенты по осям будут равны:

;

Из этих двух коэффициентов нужно выбрать наибольший, тогда весь график гарантированно уместится на холсте. Далее для получения экранных координат текущие значения x и sin(x) надо разделить на рассчитанный ранее максимальный коэффициент. Наконец, при построении графика его надо сместить вниз на половину высоты холста, поскольку ось ОХ проходит посередине. Обратите внимание на использование функции TRUNC для получения целочисленных значений координат.

Рис. 5 – Результат работы программы.

Наши рекомендации