Малюємо графік функції в delphi - статті

У цій статті ми розглянемо кілька способів намалювати графік якої-небудь функції. Малювати графік ми будемо на канві компонента Image.

Малювання по пикселам

Малювати на канві можна різними способами. Перший варіант - малювати по пікселям. Для цього використовується властивість канви Pixels. Це властивість є двовимірний масив, який відповідає за кольору канви. Наприклад Canvas.Pixels [10,20] - відповідає кольору пікселя з координатами (10,20). З масивом пікселів можна звертатися, як з будь-яким властивістю: змінювати колір, задаючи пікселя нове значення, або визначати його колір, по зберігається в ньому значенню. На прикладі нижче ми поставимо чорний колір пікселя з координатами (10,20):

Тепер ми спробуємо намалювати графік функції F (x), якщо відомий діапазон її змін Ymax і Ymin. і діапазон зміни аргументу Xmax і Xmin. Для цього ми напишемо для користувача функцію, яка буде обчислювати значення функції F в точці x, а також буде повертати максимум і мінімум функції і її аргументу.

function Tform1.F (x: real; var Xmax, Xmin, Ymax, Ymin: real): real;
Begin
F: = Sin (x);
Xmax: = 4 * pi;
Xmin: = 0;
Ymax: = 1;
Ymin: = - 1;
End;

Не забудьте також вказати заголовок цієї функциии в розділі Public:

public

function F (x: real; var Xmax, Xmin, Ymax, Ymin: real): real;

Тут для ясності ми просто вказали діапазон зміни функції Sin (x) і її аргументу, нижче ця функція буде описана цілком. Параметри Xmax, Xmin, Ymax, Ymin - описані зі словом Var бо вони є вхідними-вихідними, тобто через них функція буде повертати значення обчислень цих даних в основну програму. Тому треба оголосити Xmax, Xmin, Ymax, Ymin як глобальні змінні в розділі Implementation.

Тепер поставимо на форму кнопку і в її обробнику події OnClick напишемо наступний код:

procedure TForm1.Button1Click (Sender: TObject);
var x, y: real;
PX, PY: longInt;
begin
for PX: = 0 to Image1.Width do
begin
x: = Xmin + PX * (Xmax-Xmin) /Image1.Width;
y: = F (x, Xmax, Xmin, Ymax, Ymin);
PY: = trunc (Image1.Height- (y-Ymin) * Image1.height / (Ymax-Ymin));
image1.Canvas.Pixels [PX, PY]: = clBlack;
end;
end;

У цьому коді вводяться змінні x і y, які є значеннями аргументу і функції, а також змінні PX і PY, що є координатами пікселів, відповідних x і y. Сама процедура складається з циклу за всіма значеннями горизонтальної координати пікселів PX компонента Image1. Спочатку вибране значення PX перераховується до відповідного значення x. Потім проводиться виклик функції F (x) і визначається її значення Y. Це значення перераховується в вертикальну координату пікселя PY

Малювання за допомогою пера Pen

У канви є властивість Pen - перо. Це об'єкт в свою чергу має ряд властивостей. Одне з них властивість Color - колір, яким наноситься малюнок. Друге властивість Width - ширина лінії, задається в пікселях (за умовчанням 1).

Властивість Style визначає вид лінії і може набувати таких значень:

Суцільна лінія, але при Width> 1 допускає кольору, відмінні від палітри Windows

Всі стилі зі штрихами і пунктиром доступні тільки при товщині ліній рівної 1. Інакше ці лінії малюються як суцільні.

У канви є властивість PenPos, типу TPoint. Це властивість визначає в координатах канви поточну позицію пера. Переміщення пера без промальовування здійснюється методом MoveTo (x, y). Після виклику цього методу канви точка з координатами (x, y) стає вихідної, від якої методом LineTo (x, y) можна провести лінію, в будь-яку точку з координатами (x, y).

Давайте тепер спробуємо намалювати графік синуса пером. Для цього додамо перед циклом оператор:

Image1.Canvas.MoveTo (0, Image1.height div 2);

А перед заключним end циклу додайте наступний оператор:

Таким чином у Вас повинен вийти такий код:

procedure TForm1.Button1Click (Sender: TObject);
var x, y: real;
PX, PY: longInt;
begin
Image1.Canvas.MoveTo (0, Image1.height div 2);
for PX: = 0 to Image1.Width do
begin
x: = Xmin + PX * (Xmax-Xmin) /Image1.Width;
y: = F (x, Xmax, Xmin, Ymax, Ymin);
PY: = trunc (Image1.Height- (y-Ymin) * Image1.height / (Ymax-Ymin));
image1.Canvas.Pixels [PX, PY]: = clBlack;
Image1.Canvas.LineTo (PX, PY);
end;
end;

Як Ви вже встигли помітити, якщо запустили програму, якість малювання графіка пером, набагато краще, ніж малювання по пікселям.

Як обіцяв зараз напишу приклад програми яка знаходить максимум і мінімум функції. Я маленько змінив структуру процедур і функцій, щоб було ясніше. Ось готовий код програми:

.
type
TForm1 = class (TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click (Sender: TObject);
private

public
function F (x: real): real;
Procedure Extrem1 (Xmax, Xmin: real; Var Ymin: real);
Procedure Extrem2 (Xmax, Xmin: real; Var Ymax: real);

end;

implementation
Const e = 1e-4; // точність одна тисячна
var Xmax, Xmin, Ymax, Ymin: real;

function Tform1.F (x: real): real;
Begin
F: = Sin (x);
End;

// пошук мінімуму функції
Procedure TForm1.Extrem1 (Xmax, Xmin: real; Var Ymin: real);
Var x, h: real; j, n: integer;
Begin
n: = 10;
Repeat
x: = Xmin;
n: = n * 2;
h: = (Xmax-Xmin) / n;
Ymin: = F (Xmin);
For j: = 1 to n do begin
if f (x)x: = x + h;
end;
Until abs (f (Ymin) -f (Ymin + h))End;

// пошук максимуму функції
Procedure TForm1.Extrem2 (Xmax, Xmin: real; Var Ymax: real);
Var x, h: real; j, n: integer;
Begin
n: = 10;
Repeat
x: = Xmin;
n: = n * 2;
h: = (Xmax-Xmin) / n;
Ymax: = F (Xmin);
For j: = 1 to n do begin
if f (x)> = Ymax then Ymax: = f (x);
x: = x + h;
end;
Until abs (f (Ymax) -f (Ymax + h))End;


procedure TForm1.Button1Click (Sender: TObject);
var x, y: real;
PX, PY: longInt;
begin
// тут необхідно вказати діапазон зміни x
Xmax: = 8 * pi;
Xmin: = 0;

// обчислюємо екстремуми функції
Extrem1 (Xmax, Xmin, Ymin);
Extrem2 (Xmax, Xmin, Ymax);

// малюємо графік функції
Image1.Canvas.MoveTo (0, Image1.height div 2);
for PX: = 0 to Image1.Width do
begin
x: = Xmin + PX * (Xmax-Xmin) /Image1.Width;
y: = F (x);
PY: = trunc (Image1.Height- (y-Ymin) * Image1.height / (Ymax-Ymin));
image1.Canvas.Pixels [PX, PY]: = clBlack;
Image1.Canvas.LineTo (PX, PY);
end;
end;
end.

Схожі статті