- •Комп’ютерна графіка
- •1.3 Перетворення прямих ліній (відрізків)
- •1.4 Обертання
- •1.5 Відображення
- •1.6 Зміна масштабу
- •1.7 Двовимірний зсув і однорідні координати
- •2.6 Відображення в просторі
- •2.2 Тривимірна зміна масштабу
- •2.3 Перетворення трьохвимірних координат в двовимірні
- •2.4 Тривимірний зсув
- •2.7 Просторовий перенос
- •2.8 Тривимірне обертання навколо довільної осі
- •3.2 Косокутні проекції
- •Лабораторна робота №4 Алгоритм креслення відрізків
- •Теоретичні основи
- •Лабораторна робота № 5 Метод цифрового диференціального аналізатора
- •Теоретичні відомості
- •Алгоритм Брезенхема розкладання в растр відрізка для першого октанта
- •6.2. Загальний алгоритм Брезенхема.
- •Узагальнений цілочисельний алгоритм Брезенхема для усіх квадрантів
- •Лабораторна робота № 7 Алгоритм Брезенхема для генерації кола
- •Теоретичні основи
- •8.2 . Простий алгоритм з упорядкованим списком ребер
- •Простий алгоритм з упорядкованим списком ребер
- •8.3. Більш ефективні алгоритми з упорядкованим списком ребер
- •Більш ефективний алгоритм з упорядкованим списком ребер
- •9.1 Простий алгоритм заповнення з запалом і стеком
- •9.2 Простий алгоритм заповнення
- •Приклад 9.1. Простий алгоритм заповнення з запалом
- •Приклад 9.2. Алгоритм заповнення з запалом для багатокутника з діркою
- •9.3 Порядковий алгоритм заповнення з запалом
- •9.4 Алгоритм порядкового заповнення з запалом
- •9.5 Порядковий алгоритм заповнення з запалом
- •Приклад 9.3. Порядковий алгоритм заповнення з запалом
- •Література
- •Комп’ютерна графіка Методичні вказівки
Алгоритм Брезенхема розкладання в растр відрізка для першого октанта
Передбачається, що кінці відрізка (x1, y1) і (x2, y2) не збігаються
Integer - функція перетворення в ціле
x, y, Dx, Dy - цілі
е - дійсне
Ініціалізація змінних
x=x1
y=y1
Dx=x2-x1
Dy=y2-y1
Ініціалізація з виправленням на половину піксела
е=Dy/Dx-1/2
початок основного циклу
for i=1 to Dx
plot (x,y)
while (e=>0)
y=y+1
e=e-1
end while
x=x+1
e=e+Dy/Dx
next i
finish
6.2. Загальний алгоритм Брезенхема.
Щоб реалізація алгоритму Брезенхема була повною, необхідно розглянути побудову відрізків у всіх октантах. Модифікацію легко зробити, враховуючи в алгоритмі номер квадранта, в якому лежить відрізок і його кутовий коефіцієнт. Коли абсолютна величина кутового коефіцієнта більше 1, у постійно змінюється на одиницю, а критерій похибки Брезенхема використовується для ухвалення рішення про зміну величини x. Вибір постійно змінюваної координати (на +1 чи -1) залежить від квадранта (рис.4.1.).
Загальний алгоритм може бути оформлений у такому вигляді:
Узагальнений цілочисельний алгоритм Брезенхема для усіх квадрантів
Передбачається, що кінці відрізка (x1, y1) і (x2, y2) не збігаються.
Усі змінні вважаються цілими.
Sign - функція, що повертає -1, 0, 1 для від’ємного, нульового і додатнього аргумента відповідно.
Ініціалізація змінних
x=x1
y=y1
Dx=abs(x2-x1)
Dy=abs(y2-y1)
s1=Sign(x2-x1)
s2=Sign(y2-y1)
обмін значень Dx і Dy в залежності від кутового коефіцієнта нахилу відрізка
if Dy<Dx then
Temp=Dx
Dx=Dy
Dy=Temp
Обмін=1
else
Обмін=0
end if
ініціалізація e з виправленням на половину піксела
e=2*Dy-Dx
основний цикл
for i=1 to Dx
Plot(x,y)
while(e=>0)
if Обмін=1 then
x=x+s1
else
y=y+s2
end if
e=e-2*Dx
end while
if Обмін=1 then
y=y+s2
else
x=x+s1
end if
e=e+2*Dy
next i
finish
Рис.6.3. Розгляд випадків для узагальненого алгоритму Брезенхема.
Для ілюстрації розглянемо відрізок із точки (0, 0) у точку (-8, -4).
Початкові установки
x=0 y=0 Dx=8 Dy=4 s1=-1 s2=-1 Обмін=0 е=0
Таблиця 6.2
Результати роботи покрокового циклу
Рис.6.4. Результат роботи узагальненого алгоритму Брезенхема в третьому квадранті
ПОРЯДОК ВИКОНАННЯ РОБОТИ
1. Побудуйте декартову двовимірну систему координат, у якій максимальне значення по осях x i y було би близько 10 і початок координат був би по центру.
2. Розграфте площину побудови відрізків у вигляді сітки, на якій будуть будуватися піксели.
3. Побудуйте псевдовідрізок, який би з’єднував початок з кінцем відрізку.
4. Приведіть результат роботи алгоритму накреслення відрізку, методом Брезенхема, у якому би підсвічувалися піксели, або ж клітинки сітки.
5. Проаналізуйте результати.
ЗМІСТ ЗВІТУ
Звіт повинен містити:
1) назву роботи;
2) мету роботи;
3) короткий теоретичний вступ;
4) завдання до лабораторної роботи;
5) тексти розроблених і відлагоджених програм;
6) малюнки з реалізацією програми;
7) висновки.
ПРИКЛАД ПРОГРАМНОЇ РЕАЛІЗАЦІЇ
unit Unit1;
interface
uses
StdCtrls, Controls, ExtCtrls, Spin, Classes,forms,graphics,SysUtils;
type
b=array[1..2,1..2] of real;
TForm1 = class(TForm)
p: TPaintBox;
Label1: TLabel;
Label2: TLabel;
SpinEdit1: TSpinEdit;
Panel1: TPanel;
Panel2: TPanel;
r1: TRadioButton;
r2: TRadioButton;
procedure pPaint(Sender: TObject);
procedure pMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure pMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure pMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure SpinEdit1Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Panel2Click(Sender: TObject);
procedure Panel1Click(Sender: TObject);
procedure r2Click(Sender: TObject);
end;
var
Form1: TForm1;
pos:b;
DR:boolean=false;
temp_x,temp_y:real;
dx:integer;
lab:byte=6;
implementation
{$R *.DFM}
procedure draw_7;
var x,y,di,d:integer;
begin
x:=0;
y:=round(pos[2,2]);
di:=round(2*(1-y));
while y>0 do
begin
if form1.r2.Checked then
form1.p.Canvas.Rectangle(round(x), round(y),round(x+dx),round(y+dx))
else
begin
form1.p.Canvas.Pen.Width:= form1.p.Canvas.Pen.Width+10;
form1.p.Canvas.MoveTo(round(x),round(y));
form1.p.Canvas.LineTo(round(x),round(y));
orm1.p.Canvas.Pen.Width:= form1.p.Canvas.Pen.Width-10;
end;
if di<0 then
begin //1
d:=2*di+2*y-1;
if d<=0 then
begin //2
x:=x+dx;
di:=di+2*x+1;
end //2
else
begin //3
x:=x+dx;
y:=y+dx;
di:=di+2*x-2*y+2;
end //3
end //2
else
if di>0 then
begin //1a
d:=2*di+2*x-1;
if d<=0 then
begin //2a
x:=x+dx;
di:=di+2*x+1;
end //2a
else
begin //3a
y:=y-dx;
di:=di-2*y+1;
end // 3a
end //1a
else
if di=0 then
begin //1z
x:=x+dx;
y:=y+dx;
di:=di+2*x-2*y+2;
end //1z
end;
end;
procedure draw_6;
var pos_x,pos_y,pos_xx,pos_yy:real;
i:integer;
Dy,Dxx,l:real;
delta:boolean;
begin
form1.p.Canvas.Brush.Style:=bssolid;
if abs(pos[2,1]-pos[1,1])>=abs(pos[2,2]-pos[1,2]) then
L:=abs((pos[2,1]-pos[1,1])) else L:=abs(pos[2,2]-pos[1,2]) ;
dxx:=((pos[2,1]-pos[1,1])/l)*dx;
dy:=((pos[2,2]-pos[1,2])/l)*dx;
pos_x:=((pos[1,1]*dx));
pos_y:=((pos[1,2]*dx));
i:=1; form1.p.Canvas.Brush.Color:=cllime;
if form1.r2.Checked then
form1.p.Canvas.Rectangle(round(pos_x), round(pos_y), round(pos_x+dx),round(pos_y+dx))
else
begin
form1.p.Canvas.Pen.Width:= form1.p.Canvas.Pen.Width+10;
form1.p.Canvas.MoveTo(round(pos_x), round(pos_y));
form1.p.Canvas.LineTo(round(pos_x), round(pos_y));
form1.p.Canvas.Pen.Width:= form1.p.Canvas.Pen.Width-10;
end;
form1.p.Canvas.Brush.Color:=clblack;
while i<=l do
begin
pos_xx:=0;
pos_yy:=0;
delta:=false;
pos_x:=(pos_x+dxx);
pos_y:=(pos_y+dy);
form1.p.Canvas.Brush.Style:=bssolid;
form1.p.Canvas.Brush.Color:=cllime;
begin
if (round(pos_y) mod dx) <>0 then
begin
pos_yy:=round((pos_y) / dx);
if ((pos_Y-(pos_yy*DX))> dx/2) or ((pos_Y-(pos_yy*DX))*-1> (dx/2)) then
delta:=true;
if delta then
pos_yy:=pos_yy+1;
pos_yy:=pos_yy*dx;
pos_xx:=pos_x;
delta:=false;
end else pos_yy:=pos_y;
if (round(pos_x) mod dx) <>0 then
begin
pos_xx:=round((pos_x) / dx);
if ((pos_x-(pos_xx*DX))> dx/2) or ((pos_x-(pos_xx*DX))*-1> (dx/2)) then
delta:=true;
if delta then
pos_xx:=pos_xx+1;
pos_xx:=pos_xx*dx;
pos_yy:=pos_y;
delta:=false;
end else pos_xx:=pos_x; end;
if form1.r1.Checked then
begin
form1.p.Canvas.Pen.Width:= form1.p.Canvas.Pen.Width+10;
form1.p.Canvas.MoveTo(round(pos_xx), round(pos_yy));
form1.p.Canvas.LineTo(round(pos_xx), round(pos_yy));
form1.p.Canvas.Pen.Width:= form1.p.Canvas.Pen.Width-10;
end else
form1.p.Canvas.Rectangle(round(pos_xx), round(pos_yy),
round(pos_xx+dx),round(pos_yy+dx));
form1.p.Canvas.Brush.Color:=clblack;
inc(i);
end;
end;
procedure TForm1.pPaint(Sender: TObject);
var i:integer;
begin
p.Canvas.FillRect(clientrect); i:=0;
p.Canvas.Pen.Color:=clgray;
while i<=p.Width do
begin
p.Canvas.moveto(i,0);
p.Canvas.lineto(i,p.Height);
inc(i,dx);
end; i:=0;
while i<=p.height do
begin
p.Canvas.moveto(0,i);
p.Canvas.lineto(p.width,i);
inc(i,dx);
end;
end;
procedure TForm1.pMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ppaint(form1);
DR:=true;
pos[1,1]:=x;
pos[1,2]:=y;
temp_x:=pos[1,1];
temp_y:=pos[1,2];
end;
procedure TForm1.pMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if dr then
begin
p.Canvas.Pen.Mode:=pmxor;
p.Canvas.MoveTo(round(pos[1,1]),round(pos[1,2]));
p.Canvas.lineTo(round(temp_x),round(temp_y));
p.Canvas.Pen.Color:=clyellow;
pos[2,1]:=x;
pos[2,2]:=y;
form1.Canvas.Font.Color:=cllime;
label1.Caption:=’X = ‘+IntToStr(Round(pos[2,1]/dx))+#10+#13+’Y = ‘+IntToStr(Round(pos[2,2]/dx));
p.Canvas.MoveTo(round(pos[1,1]), round(pos[1,2]));
p.Canvas.lineTo(round(x),round(y));
temp_x:=x;
temp_y:=y;
end;
end;
procedure TForm1.pMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var i:byte;
begin
i:=0;
if round(pos[1,1]) mod dx <>0 then
while round(pos[1,1]-i) mod dx <>0 do
inc(i);
pos[1,1]:=pos[1,1]-i;
i:=0;
if round(pos[1,2]) mod dx <>0 then
while round(pos[1,2]-i) mod dx <>0 do
inc(i);
pos[1,2]:=pos[1,2]-i ;
i:=0;
if round(x) mod dx <>0 then
while round(x-i) mod dx <>0 do
inc(i);
pos[2,1]:=x-i;
i:=0;
if round(y) mod dx <>0 then
while round(y-i) mod dx <>0 do
inc(i);
pos[2,2]:=y-i ;
pos[2,1]:=pos[2,1] / dx;
pos[2,2]:=pos[2,2] / dx;
pos[1,1]:=pos[1,1] / dx;
pos[1,2]:=pos[1,2] / dx;
dr:=false;
if (pos[1,1]<>pos[2,1]) or(pos[2,2]<>pos[1,2]) then
case lab of
6:draw_6;
7:draw_7;
end
end;
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
if SpinEdit1.Value>0 then
dx:=SpinEdit1.Value;
ppaint(form1);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SpinEdit1.Value:=50;
dx:=SpinEdit1.value;
end;
procedure TForm1.Panel2Click(Sender: TObject);
begin
panel2.BevelOuter:=bvLowered;
panel2.Color:=clActiveBorder;
panel1.BevelOuter:=bvRaised;
panel1.Color:=clBtnFace;
form1.Caption:=’LAB 7';
lab:=7;
end;
procedure TForm1.Panel1Click(Sender: TObject);
begin
panel1.BevelOuter:=bvLowered;
panel1.Color:=clActiveBorder;
panel2.BevelOuter:=bvRaised;
panel2.Color:=clBtnFace;
form1.Caption:=’LAB 6';
lab:=6;
end;
procedure TForm1.r2Click(Sender: TObject);
begin
case lab of
6:draw_6;
7:draw_7;
end;
end;
end.
