Міністерство освіти та науки України
Національний університет «Львівська політехніка»
Кафедра автоматизованих систем управління
Лабораторна робота №6
з дисципліни
«Комп’ютерна графіка»
на тему:
“Алгоритм Брезенхема для побудови прямих”
Мета: Освоїти алгоритм Брезенхема для побудови прямих.
ТЕОРЕТИЧНІ ОСНОВИ
Хоча алгоритм Брезенхема був спочатку розроблений для цифрових графопобудовувачів, проте він має застосування для растрових пристоїв з ЕПТ. Алгоритм вибирає оптимальні растрові координати для представлення відрізка. У процесі роботи одна з координат – або x, або y (в залежності від кутового коефіцієнта) – змінюється на одиницю. Зміна іншої координати (на 0 чи 1) залежить від відстані між дійсним положенням відрізка і найближчих координат сітки. Таку відстань ми називаємо похибкою. Алгоритм побудований так, що потрібно перевірити лише знак цієї похибки.
Оскільки бажано перевіряти тільки знак похибки, то вона спочатку встановлюється рівною -½. Таким чином, якщо кутовий коефіцієнт відрізка дорівнює чи більший ½, то величина похибки в наступній точці растра з координатами (a,b) може бути обчислена як е = е + m, де m – кутовий коефіцієнт.
Якщо е від’ємне, то відрізок пройде нижче середини піксела. Отже, пікселі на тому ж самому горизонтальному рівні краще апроксимує положення відрізка, тому y не збільшується.
Якщо е додатнє, то відрізок пройде вище середньої точки. Отже, y збільшується на 1.
Перш ніж розглядати наступний пікселі, необхідно відкоректувати відніманням від неї 1.
Загальний алгоритм Брезенхема:
Передбачається, що кінці відрізка не збігаються. Усі змінні вважаються цілими. Sigh – функція, що повертає -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
ініціалізація е з виправленням на половину пікселі
e=2*Dy – Dx
основний цикл
for i=1 to Dx do
if e>=0 then
if Обмін=1 then x=x+s1
else y=y+s2
while e>=0 do e=e – 2*Dx
if Обмін=1 then y=y+s2
else x=x+s1
e=e+2*Dy
Plot(x,y)
finish
ПОРЯДОК РОБОТИ
Побудувати декартову двовимірну систему координат, у якій максимальне значення по осях х і у було би близько 10.
Розграфте площину побудови відрізків у вигляді сітки, на якій будуть малюватися пікселі.
Побудуйте псевдовідрізок, який би з’єднував початок з кінцем відрізку.
Приведіть результат роботи алгоритму накреслення відрізку, методом Брезенхема, у якому би підсвічувалися пікселі, або ж клітинки сітки.
Проаналізуйте результати.
Текст програми
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Menus, StdCtrls, Buttons;
type
TForm1 = class(TForm)
Bevel1: TBevel;
PaintBox1: TPaintBox;
BitBtn1: TBitBtn;
Label3, Label4, Label5, Label6: TLabel;
Label7, Label8, Label9, Label10: TLabel;
Label11, Label12, Label13, Label1: TLabel;
Label2, Label14, Label15, Label16: TLabel;
Label17, Label18, Label19, Label20: TLabel;
Label21: TLabel, Lbel22: TLabel;
ex1, ey1, ex2, ey2: TEdit;
procedure Chusto;
procedure Sitka;
procedure Tochka(x,y: integer);
function Sign(k: integer): integer;
procedure Vidrizok(x1,y1,x2,y2: integer);
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
private
public
end;
const CP=20;//ціна поділки
var Form1: TForm1;
x0,y0,w,h,x1,x2,y1,y2: integer;
new,draw: Boolean;
implementation
{$R *.DFM}
procedure TForm1.Chusto;
begin new:=true; PaintBox1.Repaint; end;
procedure TForm1.Sitka;
var j: integer;
begin
with PaintBox1.Canvas do
begin
Pen.Color:=clGray;
for j:=0 to CP+1 do
begin
MoveTo(0+j*CP,h); LineTo(0+j*CP,0);
MoveTo(0,h-j*CP); LineTo(w,h-j*CP);
end;
end;
end;
procedure TForm1.Tochka(x,y: integer);
begin
with PaintBox1.Canvas do
begin
Brush.Color:=clGreen;
Rectangle(x0+x*CP,y0-(y+1)*CP,x0+(x+1)*CP,y0-y*CP);
FloodFill(x0+x*CP+1,y0-(y+1)*CP+1,clGreen,fsBorder);
end;
end;
function TForm1.Sign(k: integer): integer;
begin
if k<0 then begin Sign:=-1; exit; end;
if k=0 then begin Sign:=0; exit; end;
if k>0 then begin Sign:=1; exit; end;
end;
procedure TForm1.Vidrizok(x1,y1,x2,y2: integer);
var x,y,Dx,Dy,s1,s2,temp,obmin,i: integer;
e: double;
begin
x:=x1; y:=y1;
Dx:=abs(x2-x1); s1:=Sign(x2-x1);
Dy:=abs(y2-y1); s2:=Sign(y2-y1);
if Dy>Dx then begin temp:=Dx; Dx:=Dy; Dy:=temp; obmin:=1; end
else obmin:=0;
e:=2*Dy-Dx; Tochka(x,y);
for i:=1 to Dx do
begin
if e>=0 then
begin
if obmin=1 then x:=x+s1 else y:=y+s2;
while e>=0 do e:=e-2*Dx;
end;
if obmin=1 then y:=y+s2 else x:=x+s1;
e:=e+2*Dy; Tochka(x,y);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
w:=PaintBox1.Width; x0:=9*CP;
h:=PaintBox1.Height; y0:=h-9*CP;
draw:=false; Chusto;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if (ex1.Text='')or(ex2.Text='')or(ey1.Text='')or(ey2.Text='') then begin Chusto; exit; end;
x1:=StrToInt(ex1.Text); y1:=StrToInt(ey1.Text);
x2:=StrToInt(ex2.Text); y2:=StrToInt(ey2.Text);
draw:=true; new:=true; PaintBox1.Repaint;
end;
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
if new=true then begin new:=false; Sitka; end;
if draw=true then begin draw:=false; Vidrizok(x1,y1,x2,y2); end;
end;
end.
Результат роботи програми
Висновок: в даній лабораторній роботі я ознайомився з основами комп’ютерної графіки – алгоритмом побудови прямих метод Брезенхема.