Метод цифрового диференціального аналізатора

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Кафедра автоматизованих систем управління

Інформація про роботу

Рік:
2008
Тип роботи:
Лабораторна робота
Предмет:
Комп'ютерна графіка
Група:
КН

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти та науки України Національний університет «Львівська політехніка» Кафедра автоматизованих систем управління  Лабораторна робота №5 з дисципліни «Комп’ютерна графіка» на тему: “Метод цифрового диференціального аналізатора” Мета: Освоїти розкладання відрізка в растр методом цифрового диференціального аналізатора. ТЕОРЕТИЧНІ ОСНОВИ Один з методів розкладання відрізка в растр полягає в розв’язуванні диференціального рівняння, що описує цей процес. Для прямої лінії маємо dy/dx=const чи Dy/Dx=(y2-y1)/(x2-x1) Розв’язок представляється у вигляді yi+1=yi+Dy yi+1=yi+Dx(y2-y1)/(x2-x1) [1] де x1, y1 і x2, y2 - кінці відрізка, що розкладається, і yi - початкове значення для чергового кроку вздовж відрізка. Фактично рівняння [1] являє собою рекурентне співвідношення для послідовних значень y вздовж потрібного відрізка. Цей метод, використовуваний для розкладання в растр відрізків, називається цифровим диференціальним аналізатором (ЦДА). У простому ЦДА або Dx, або Dy (більше із збільшень) вибирається як одиниця растра. Нижче наводиться простий алгоритм, що працює у всіх квадрантах: Процедура розкладання в растр відрізка по методу цифрового диференціального аналізатора (ЦДА) передбачається, що кінці відрізка (x1, y1) і (x2, y2) не збігаються Integer - функція перетворення дійсного числа в ціле. Sign - функція, що повертає -1, 0, 1 для від’ємного, нульового і додатнього аргументу відповідно апроксимуємо довжину відрізка if abs(x2-x1)>=abs(y2-y1) then Довжина=abs(x2-x1) else Довжина=abs(y2-y1) end if назначаємо більше із збільшень Dx чи Dy рівним одиниці растра Dx=(x2-x1)/Довжина Dy=(y2-y1)/Довжина округляємо величини, а не відкидаємо дробову частину використання знакової функції робить алгоритм придатним для всіх квадрантів x=x1+0.5*Sign(Dx) y=y1+0.5*Sign(Dy) початок основного циклу i=1 while (i<=Довжина) Plot (Integer(x), Integer(y)) x=x+Dx y=y+Dy i=i+1 end while finish Наведемо приклад ілюструючий роботу алгоритму: Приклад 2.1. Простий ЦДА в першому квадранті Розглянемо відрізок із точки (0,0) у точку (5,5). Використовуємо ЦДА для розкладання цього відрізка в растр. Результати роботи алгоритму такі: початкові установки x1=0 y1=0 x2=5 y2=5 Довжина=5 Dx=1 Dy=1 x=0,5 y=0,5 результати роботи покрокового циклу i Plot x y    0,5 0,5  1 (0,0)      1,5 1,5  2 (1,1)      2,5 2,5  3 (2,2)      3,5 3,5  4 (3,3)      4,5 4,5  5 (4,4)      5,5 5,5  Отримане растрове представлення відрізка зображене на рис.2.1. Зауважимо, що кінцеві точки визначені точно, обрані піксели рівномірно розподілені вздовж відрізка. Однак якщо початковим значенням змінної і взяти нуль замість одиниці, то виявиться активованим піксел з координатами (5,5), що небажано. Якщо адреса піксела задана цілими координатами лівого нижнього кута, то активація цього піксела дасть явно невірну кінцеву точку відрізка (рис.2.1). До того ж при кресленні серії послідовних відрізків піксел (5,5) буде активований двічі: наприкінці даного відрізка і на початку наступного. Такий піксел може виглядати як більш яскравий чи мати інший колір. Наведемо приклад ілюструючий роботу алгоритму в третьому квадранті.  Рис.2.1. Результати роботи простого ЦДА в першому квадранті. Розглянемо відрізок із точки (0,0) у точку (-8,-4) в третьому квадранті. Використовуємо ЦДА для розкладання цього відрізка в растр. Результати роботи алгоритму такі: початкові установки x1=0 y1=0 x2=-8 y2=-4 Довжина=8 Dx=-1 Dy=-0,5 x=-0,5 y=-0,5 результати роботи покрокового циклу Plot x y    -0,5 -0,5  1 (-1,-1)      -1,5 -1,0  2 (-2,-1)      -2,5 -1,5  3 (-3,-2)      -3,5 -2,0  4 (-4,-2)      -4,5 -2,5  5 (-5,-3)      -5,5 -3,0  6 (-6,-3)      -6,5 -3,5  7 (-7,-4)      -7,5 -4,0  8 (-8,-4)      -8,5 -4,5  Незважаючи на те що результати, представлені на рис.2.2, виглядають цілком прийнятними, аналіз відрізків, проведених із точки (0,0) у точку (-8,4) і (8,-4), показує, що розкладений у растр відрізок лежить по одну сторону від реального і що на одному з кінців відрізка з'являється зайва точка, тобто результат роботи алгоритму залежить від орієнтації. Отже точність у кінцевих точках зменшується.  Рис.2.2. Результати роботи простого ЦДА в третьому квадранті. Текст програми unit Unit1; unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Spin, ExtCtrls; type TForm1 = class(TForm) Image1: TImage; SpinEdit1: TSpinEdit; Label1: TLabel; Button1: TButton; Button2: TButton; SpinEdit2: TSpinEdit; SpinEdit3: TSpinEdit; SpinEdit4: TSpinEdit; SpinEdit5: TSpinEdit; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Button3: TButton; Button4: TButton; Button5: TButton; Button6: TButton; procedure Button1Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); //procedure clear_field(where: TImage); //procedure Button6Click(Sender:TObject); //procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; w,h,zn1,zn2:integer; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var k,m,i:integer; begin if SpinEdit1.Value<=0 then SpinEdit1.Value:=5; i:=SpinEdit1.Value; k:=0; m:=0; h:=0; w:=0; Image1.Canvas.Brush.Color:=clWhite; Image1.Canvas.Brush.Style:=bsSolid; Image1.Canvas.Rectangle(0,0,Image1.Width,Image1.Height); Image1.Canvas.Pen.Color:=clLime; Image1.Canvas.Pen.Style:=psSolid; while k< Image1.Width do begin k:=k+i; Image1.Canvas.MoveTo(k,0); Image1.Canvas.LineTo(k,Image1.Height); k:=k+i; Image1.Canvas.MoveTo(k,Image1.Height); Image1.Canvas.LineTo(k,0); w:=w+2; end; while m< Image1.Height do begin m:=m+i; Image1.Canvas.MoveTo(0,m); Image1.Canvas.LineTo(Image1.Width,m); m:=m+i; Image1.Canvas.MoveTo(Image1.Width,m); Image1.Canvas.LineTo(0,m); h:=h+2; end; Image1.Canvas.Pen.Color:=clBlack; Button5.Click; end; {procedure TForm1.Button2Click(Sender: TObject); var x1,y1,x2,y2,i:integer; begin SpinEdit2.Visible:=True; SpinEdit3.Visible:=True; SpinEdit4.Visible:=True; SpinEdit5.Visible:=True; Button3.Visible:=True; Button4.Visible:=True; Label2.Visible:=True; Label3.Visible:=True; Label4.Visible:=True; Label5.Visible:=True; SpinEdit2.Value:=0; SpinEdit3.Value:=0; SpinEdit4.Value:=1; SpinEdit5.Value:=1; end; } procedure TForm1.Button3Click(Sender: TObject); var x1,y1,x2,y2,i:integer; begin i:=SpinEdit1.Value; x1:=SpinEdit2.Value; y1:=SpinEdit3.Value; x2:=SpinEdit4.Value; y2:=SpinEdit5.Value; if y1<0 then zn1:=-1 else zn1:=1; if y2<0 then zn2:=-1 else zn2:=1; Image1.Canvas.Brush.Color:=clFuchsia; Image1.Canvas.Brush.Style:= bsSolid; Image1.Canvas.Pen.Color:=clLime; Button5.Click; Image1.Canvas.FloodFill(trunc((w-1)/2)*i+i*x1-1,Image1.Height+1-i*y1-trunc((h-zn1)/2)*i,clLime, fsBorder); Image1.Canvas.FloodFill(trunc((w-1)/2)*i+i*x2-1,Image1.Height+1-i*y2-trunc((h-zn2)/2)*i,clLime, fsBorder); Image1.Canvas.Pen.Color:=clBlack; Button5.Click; end; procedure TForm1.Button4Click(Sender: TObject); var i,x1,y1,x2,y2,xm,ym,xr,yr:integer; dx,dy,xk,yk,znx,zny:real; begin i:=SpinEdit1.Value; x1:=SpinEdit2.Value; y1:=SpinEdit3.Value; x2:=SpinEdit4.Value; y2:=SpinEdit5.Value; Image1.Canvas.Pen.Color:=clLime; Button5.Click; znx:=1; zny:=1; if y2<y1 then zny:=-1; if x2<x1 then znx:=-1; xk:=x1; yk:=y1; xr:=abs(x2-x1); yr:=abs(y2-y1); if xr>yr then begin dy:= yr/xr; while abs(xk-x2)>1 do begin xk:=xk+znx; yk:=yk+dy*zny; Image1.Canvas.Brush.Color:=clFuchsia ; Image1.Canvas.Brush.Style:= bsSolid; Image1.Canvas.FloodFill(round(trunc((w-1)/2)*i+i*xk-1),round(Image1.Height+1-i*yk-trunc((h-zn1)/2)*i),clLime, fsBorder); end; end else begin dx:= xr/yr; while abs(yk-y2)>1 do begin yk:=yk+zny; xk:=xk+dx*znx; Image1.Canvas.Brush.Color:=clFuchsia ; Image1.Canvas.Brush.Style:= bsSolid; Image1.Canvas.FloodFill(round(trunc((w-1)/2)*i+i*xk-1),round(Image1.Height+1-i*yk-trunc((h-zn2)/2)*i),clLime, fsBorder); end; end; Image1.Canvas.Pen.Color:=clBlack; Button5.Click; end; procedure TForm1.Button5Click(Sender: TObject); var i:integer; begin i:=SpinEdit1.Value; Image1.Canvas.Pen.Style:=psSolid; Image1.Canvas.MoveTo(0,trunc(h/2)*i); Image1.Canvas.LineTo(Image1.Width,trunc(h/2)*i); Image1.Canvas.MoveTo(trunc((w-1)/2)*i,0); Image1.Canvas.LineTo(trunc((w-1)/2)*i,Image1.Height); end; procedure clear_field(where: TImage); begin where.canvas.Pen.color:=clWhite; where.canvas.Brush.Color := clWhite; where.canvas.Rectangle(0, 0, where.width, where.Height); where.canvas.Pen.color:=clBlack; end; procedure TForm1.Button6Click(Sender: TObject); var k,m,i:integer; begin clear_field(image1); if SpinEdit1.Value<=0 then SpinEdit1.Value:=5; i:=SpinEdit1.Value; k:=0; m:=0; h:=0; w:=0; Image1.Canvas.Brush.Color:=clWhite; Image1.Canvas.Brush.Style:=bsSolid; Image1.Canvas.Rectangle(0,0,Image1.Width,Image1.Height); Image1.Canvas.Pen.Color:=clBlack; Image1.Canvas.Pen.Style:=psSolid; while k< Image1.Width do begin k:=k+i; Image1.Canvas.MoveTo(k,0); Image1.Canvas.LineTo(k,Image1.Height); k:=k+i; Image1.Canvas.MoveTo(k,Image1.Height); Image1.Canvas.LineTo(k,0); w:=w+2; end; while m< Image1.Height do begin m:=m+i; Image1.Canvas.MoveTo(0,m); Image1.Canvas.LineTo(Image1.Width,m); m:=m+i; Image1.Canvas.MoveTo(Image1.Width,m); Image1.Canvas.LineTo(0,m); h:=h+2; end; Image1.Canvas.Pen.Color:=clRed; Button5.Click; end; end.  Висновок: в даній лабораторній роботі я ознайомився з основами комп’ютерної графіки – алгоритмом побудови відрізків методом цифрового диференціального аналізатора.
Антиботан аватар за замовчуванням

01.01.1970 03:01-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!