Міністерство освіти і науки України
Національний університет «Львівська політехніка»
Інститут комп’ютерних наук та інформаційних технологій
Кафедра автоматизованих систем управління
Лабораторна робота №5
З курсу:
«Комп’ютерна графіка»
Тема: Метод цифрового диференціального аналізатора.
Мета: Освоїти розкладання відрізка в растр методом цифрового диференціального аналізатора.
.
ТЕОРЕТИЧНІ ОСНОВИ
Один з методів розкладання відрізка в растр полягає в розв’язуванні диференціального рівняння, що описує цей процес. Для прямої лінії маємо dy/dX=const Dy/DX=(y2 – y1)/(x2 -Xl)
Розв’язок представляється у вигляді
yі+1 =yi+Dy yі+1 = yi +Dx(y2-yl)/(x2-xl)
де х1 , у1 i х2 , у2 - кінці відрізка, що розкладається, i уі - початкове значення для чергового кроку вздовж відрізка. Фактично рівняння являє собою рекурентне співвідношення для послідовних значень у вздовж потрібного відрізка. Цей метод, використовуваний для розкладання в растр відрізків, називається цифровим диференціальним аналізатором (ЦДА). У простому ЦДА або Dx, або Dy (більше iз збільшень) вибирається як одиниця растра. Нижче наводиться простий алгоритм, що працює у вcix квадрантах:
Процедура розкладання в растр відрізка по методу цифрового диференціального аналізатора
Передбачається, що кінці відрізка (х1 у1) i (х2 у2) не збігаються
Апроксимуємо довжину відрізка
if abs(x2-xl)>=abs(y2-yl) then
Довжина= abs (х2-х1)
else Довжина= abs (у2-у1)
End { if }
назначаемо більше iз збільшень Dx чи Dy рівним одиниці растра
Dx =(х2-х1)/Довжина
Dy = (y2-yl )/Довжина
округляємо величини, а не відкидаємо дробову частину
використання знакової функції робить алгоритм придатним для вcix квадрантів
x= х1; y= yl;
Plot (round(x), round(y)) //промалювання пікселя
початок основного циклу i=l
while (i=Довжина) do x=x+Dx; y=y+Dy; i=i+l;
Plot (round(x), round(y)); End
Текст програмного коду:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls, ExtCtrls,math;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
Button1: TButton;
Image1: TImage;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure koord();
procedure draw_P(x_k,y_k:integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
x0,y0,delta:integer;
implementation
procedure TForm1.koord();
var delta_p,x1,x2,x3,x4,y1,y2,y3,y4,i:integer;
begin
x0:=round(image1.Width/2);
y0:=round((image1.Height)/2);
with image1.Canvas do
begin
if (image1.Width-x0)>(image1.Height-y0) then
delta:=round((image1.Height-y0)/10)
else
delta:=round((image1.Width-x0)/10);
x1:=x0;
x2:=x0;
x3:=x0;
x4:=x0;
y1:=y0;
y2:=y0;
y3:=y0;
y4:=y0;
for i:=0 to 30 do begin
delta_p:=delta;
MoveTo(x0,y1);
LineTo(x0,y1-delta_p);
moveto(x0-2,y1-delta_p);
LineTo (x0+2,y1-delta_p);
y1:=y1-delta_p;
MoveTo(x0,y2);
LineTo(x0,y2+delta_p);
moveto(x0-2,y2+delta_p);
LineTo (x0+2,y2+delta_p);
y2:=y2+delta_p;
MoveTo(x3,y0);
LineTo(x3+delta_p,y0);
moveto(x3+delta_p,y0-2);
LineTo (x3+delta_p,y0+2);
x3:= x3+delta_p;
MoveTo(x4,y0);
LineTo(x4-delta_p,y0);
moveto(x4-delta_p,y0-2);
LineTo (x4-delta_p,y0+2);
x4:= x4-delta_p;
end;
x1:=x0;
x2:=x0;
x3:=0;
x4:=x0;
y1:=Image1.Height;
y2:=y0;
y3:=y0;
y4:=y0;
for i:=0 to 30 do begin
delta_p:=delta;
pen.Style:=psDot;
moveto(0,y1-delta_p);
LineTo (image1.Width,y1-delta_p);
moveto(x3+delta_p,0);
LineTo (x3+delta_p,image1.Height);
y1:=y1-delta_p;
x3:= x3+delta_p;
end;
end;
end;
procedure TForm1.draw_P(x_k,y_k:integer);
var xx,yy,col:integer;
begin
with image1.Canvas do
begin
pen.Color:=clgray;
pen.Width:=5;
xx:=x0+x_k*delta;
yy:= y0-y_k*delta;
MoveTo(xx,yy);
LineTo(xx,yy);
pen.Width:=1;
col:= brush.Color;
brush.Color:=clGreen;
fillRect(rect(xx,yy,xx+delta,yy-delta));
brush.Color:=col;
TextOut(x0+x_k*delta,y0+7,inttostr(x_k));
TextOut(x0+7,y0-y_k*delta,inttostr(y_k));
pen.Style:=psSolid;
end;
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
str: array[0..2] of array[0..2] of integer;
x:array[0..2]of array[0..2] of integer;
a:array[0..2]of array[0..2] of integer;
i,j,l,x_t0,y_t0,x_tk,y_tk,flag:integer;
x_t,y_t,dx,dy,m,e:double;
begin
image1.Canvas.FillRect(Rect(0,0,image1.Width,image1.Height));
image1.Transparent:=true;
koord();
x_t0:=strtoint(StringGrid1.Cells[0,0]);
y_t0:=strtoint(StringGrid1.Cells[1,0]);
draw_P(x_t0,y_t0);
///*****************
x_tk:=strtoint(StringGrid2.Cells[0,0]);
y_tk:=strtoint(StringGrid2.Cells[1,0]);
draw_P(x_tk,y_tk);
//**********
if abs (x_tk-x_t0) >= abs (y_tk-y_t0) then
m:= abs (x_tk-x_t0)
else
m:= abs (y_tk-y_t0);
dx:= (x_tk-x_t0)/m;
dy:= (y_tk-y_t0)/m;
x_t:=x_t0;
y_t:=y_t0;
i:=1;
while(i<m) do
begin
x_t:=x_t+dx;
y_t:=y_t+dy;
i:=i+1;
draw_P(round(x_t),round(y_t));
end;
with image1.Canvas do
begin
pen.color:=clRed;
Moveto(x0+x_t0*delta,y0-y_t0*delta);
LineTo(x0+delta+x_tk*delta,y0-delta-y_tk*delta);
pen.color:=clBlack;
end;
end;
end.
Результати роботи програми:
Рис. 1. Результати роботи простого ЦДА
Висновок: На даній лабораторній роботі я освоїла розкладання відрізка в растр методом цифрового диференціального аналізатора.