Алгоритм Брезенхейма — алгоритм, який визначає які точки в n-вимірному растрі мають бути накреслені для формування близького наближення для прямої лінії між двома заданими точками. Він загально використовується для малювання ліній на екрані через те, що використовує тільки цілочисельну суму, віднімання та бітові операції, всі ці операції дуже «дешеві» в стандартній архітектурі комп'ютерів. Це один з перших алгоритмів розроблених в галузі комп'ютерної графіки. Незначно розширений початковий алгоритм також обробляє малювання кіл.
Хоча алгоритм Ву також часто використовується в сучасній комп'ютерній графіці через підтримку згладжування, алгоритм Брезенхейма залишається вживаним завдяки його швидкісті і простоті. Алгоритм використовується в графобудівниках і графічних процесорах сучасних відеокарт. Також його можна знайти в багатьох програмних графічних бібліотеках. Через свою простоту алгоритм часто реалізується або як вбудована програма або як апаратне забезпечення сучасних відеокарт.
Позначка "Брезенхейм" використовується сьогодні для цілого сімейства алгоритмів, що розширюють або модифікують початковий алгоритм Брезенхейма.
Алгоритм
Будемо слідувати загальноприйнятій домовленості, що координати ростуть вниз і праворуч, а також, що ми використовуємо центри пікселів, що мають цілочисельні координати. Кінцевими точками відрізка є пікселі з координатами та , де перша координата за горизонталлю, друга за вертикаллю.
Спочатку алгоритм буде розглянутий для октанта в якому відрізок спрямований праворуч і донизу (), і його горизонтальна проєкція довша за вертикальну (лінія має кутовий коефіцієнт за модулем менше 1 і більше ніж 0.) В цьому октанті для кожного стовпця x між та , існує лише один рядок y (обчислений за допомогою алгоритму) з пікселем на лінії, тоді як кожний рядок між та може містити декілька пікселів лінії.
Алгоритм Брезенхейма обирає ціле y таким чином, щоб центр пікселя був найближчим до ідеального (дробового) y для того ж x; y може залишитися тим самим або бути збільшеним на 1. Загальне рівняння лінії через дві точки таке:
Тому що ми знаємо стовпець x, рядок y отримується шляхом округлення наступного результату:
- або ,
де кутовий коефіцієнт залежить тільки від координат точок і може бути обчислений заздалегідь, і ідеальний y для відповідного цілого x може бути обчислений починаючи від додаючи кутовий коефіцієнт раз за разом, а .
На практиці, через те, що кутовий коефіцієнт за модулем менший ніж 1 і більший ніж 0, ми на кожному кроці або збільшуємо y на 1 або залишаємо попереднє значення, зберігаючи дробову частину в додатковій змінній c
. Тоді .
Тоді, якщо , покладемо , інакше .
Зауважимо, що через те, що точка належить прямій .
В наступному псевдокоді plot(x,y)
малює точку і abs
повертає абсолютну величину:
function line(x0, x1, y0, y1) int deltax := x1 - x0 int deltay := y1 - y0 real c := 0 real k := deltay / deltax // Припускаємо, що deltax != 0 (пряма не вертикальна), // зауважимо, що це ділення має бути зроблено у спосіб, що зберігає дробову частину int y := y0 for x from x0 to x1 plot(x,y) c := c + k if abs(c) ≥ 0.5 then y := y + 1 c := c - 1.0
Порівнювати з нулем зручніше ніж з 0.5, тому введемо нову допоміжну величину , зауважимо, що (тому що ).
void line(int x0, int y0, int x1, int y1, int color) { double k = ((double)(y1 - y0))/(x1-x0); double d = 2*k - 1; int y = y0; putpixel(x0, y0, color); for (int x = x0 + 1; x <= x1; x++) { if (d > 0) { d += 2*k - 2; y++; } else d += 2*k; putpixel(x, y, color); } }
Попри те, що вхідні дані цілочисельні і всі операції здійснюються на цілочисельній ґратці, алгоритм використовує операції з дійсними числами. Щоб позбутися необхідності їх використання, зауважимо, що всі дійсні числа присутні в алгоритмі є числами виду . Тому можливо домножити та на , і отримати в результаті тільки цілі числа. Тим самим отримаємо алгоритм Брезенхейма.
// найпростіший алгоритм Брезенхейма. 0 <= y1 - y0 <= x1 - x0 void line (int x0, int x1, int y0, int y1, int color) { int dx = x1 - x0; int dy = y1 - y0; int d = (dy << 1) - dx; int d1 = dy << 1; int d2 = (dy - dx) << 1; putpixel(x0, y0, color); for(int x = x0 + 1, y = y0; x <= x1; x++) { if ( d >0) { d += d2; y += 1; } else d += d1; putpixel(x, y, color); } }
Також наведемо узагальнений алгоритм, який враховує можливі напрямки відрізка, а також співвідношення до :
void segment(int x0, int y0, int x1, int y1, int color) { int dx = abs(x1 - x0); int dy = abs(y1 - y0); int sx = x1 >= x0 ? 1 : -1; int sy = y1 >= y0 ? 1 : -1; if (dy <= dx) { int d = (dy << 1) - dx; int d1 = dy << 1; int d2 = (dy - dx) << 1; putpixel(x0, y0, color); for(int x = x0 + sx, y = y0, i = 1; i <= dx; i++, x += sx) { if ( d >0) { d += d2; y += sy; } else d += d1; putpixel(x, y, color); } } else { int d = (dx << 1) - dy; int d1 = dx << 1; int d2 = (dx - dy) << 1; putpixel(x0, y0, color); for(int y = y0 + sy, x = x0, i = 1; i <= dy; i++, y += sy) { if ( d >0) { d += d2; x += sx; } else d += d1; putpixel(x, y, color); } } }
Посилання
- "Алгоритм малювання ліній Брезенхейма" [ 25 лютого 2021 у Wayback Machine.], Колін Фленегана (англ.)
Див. також
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Algoritm Brezenhejma algoritm yakij viznachaye yaki tochki v n vimirnomu rastri mayut buti nakresleni dlya formuvannya blizkogo nablizhennya dlya pryamoyi liniyi mizh dvoma zadanimi tochkami Vin zagalno vikoristovuyetsya dlya malyuvannya linij na ekrani cherez te sho vikoristovuye tilki cilochiselnu sumu vidnimannya ta bitovi operaciyi vsi ci operaciyi duzhe deshevi v standartnij arhitekturi komp yuteriv Ce odin z pershih algoritmiv rozroblenih v galuzi komp yuternoyi grafiki Neznachno rozshirenij pochatkovij algoritm takozh obroblyaye malyuvannya kil Hocha algoritm Vu takozh chasto vikoristovuyetsya v suchasnij komp yuternij grafici cherez pidtrimku zgladzhuvannya algoritm Brezenhejma zalishayetsya vzhivanim zavdyaki jogo shvidkisti i prostoti Algoritm vikoristovuyetsya v grafobudivnikah i grafichnih procesorah suchasnih videokart Takozh jogo mozhna znajti v bagatoh programnih grafichnih bibliotekah Cherez svoyu prostotu algoritm chasto realizuyetsya abo yak vbudovana programa abo yak aparatne zabezpechennya suchasnih videokart Poznachka Brezenhejm vikoristovuyetsya sogodni dlya cilogo simejstva algoritmiv sho rozshiryuyut abo modifikuyut pochatkovij algoritm Brezenhejma AlgoritmIlyustraciya rezultatu roboti algoritmu Brezenhejma 0 0 v verhnomu livomu kuti Budemo sliduvati zagalnoprijnyatij domovlenosti sho koordinati rostut vniz i pravoruch a takozh sho mi vikoristovuyemo centri pikseliv sho mayut cilochiselni koordinati Kincevimi tochkami vidrizka ye pikseli z koordinatami x 0 y 0 displaystyle x 0 y 0 ta x 1 y 1 displaystyle x 1 y 1 de persha koordinata za gorizontallyu druga za vertikallyu Spochatku algoritm bude rozglyanutij dlya oktanta v yakomu vidrizok spryamovanij pravoruch i donizu x 0 x 1 y 0 y 1 displaystyle x 0 leqslant x 1 land y 0 leqslant y 1 i jogo gorizontalna proyekciya x 1 x 0 displaystyle x 1 x 0 dovsha za vertikalnu y 1 y 0 displaystyle y 1 y 0 liniya maye kutovij koeficiyent za modulem menshe 1 i bilshe nizh 0 V comu oktanti dlya kozhnogo stovpcya x mizh x 0 displaystyle x 0 ta x 1 displaystyle x 1 isnuye lishe odin ryadok y obchislenij za dopomogoyu algoritmu z pikselem na liniyi todi yak kozhnij ryadok mizh y 0 displaystyle y 0 ta y 1 displaystyle y 1 mozhe mistiti dekilka pikseliv liniyi Algoritm Brezenhejma obiraye cile y takim chinom shob centr pikselya buv najblizhchim do idealnogo drobovogo y dlya togo zh x y mozhe zalishitisya tim samim abo buti zbilshenim na 1 Zagalne rivnyannya liniyi cherez dvi tochki take y y 0 y 1 y 0 x x 0 x 1 x 0 displaystyle frac y y 0 y 1 y 0 frac x x 0 x 1 x 0 Tomu sho mi znayemo stovpec x ryadok y otrimuyetsya shlyahom okruglennya nastupnogo rezultatu y y 1 y 0 x 1 x 0 x x 0 y 0 displaystyle y frac y 1 y 0 x 1 x 0 x x 0 y 0 abo y k x b displaystyle y kx b de kutovij koeficiyent k y 1 y 0 x 1 x 0 displaystyle k y 1 y 0 x 1 x 0 zalezhit tilki vid koordinat tochok i mozhe buti obchislenij zazdalegid i idealnij y dlya vidpovidnogo cilogo x mozhe buti obchislenij pochinayuchi vid y 0 displaystyle y 0 dodayuchi kutovij koeficiyent raz za razom a b y 0 k x 0 displaystyle b y 0 kx 0 Na praktici cherez te sho kutovij koeficiyent za modulem menshij nizh 1 i bilshij nizh 0 mi na kozhnomu kroci abo zbilshuyemo y na 1 abo zalishayemo poperednye znachennya zberigayuchi drobovu chastinu v dodatkovij zminnij c Todi c i k x i b k x i b displaystyle c i kx i b kx i b Todi yaksho c i lt 0 5 displaystyle c i lt 0 5 poklademo y i k x i b displaystyle y i kx i b inakshe y i k x i b 1 displaystyle y i kx i b 1 Zauvazhimo sho c 0 0 displaystyle c 0 0 cherez te sho tochka x 0 y 0 displaystyle x 0 y 0 nalezhit pryamij y k x b displaystyle y kx b V nastupnomu psevdokodi plot x y malyuye tochku i abs povertaye absolyutnu velichinu function line x0 x1 y0 y1 int deltax x1 x0 int deltay y1 y0 real c 0 real k deltay deltax Pripuskayemo sho deltax 0 pryama ne vertikalna zauvazhimo sho ce dilennya maye buti zrobleno u sposib sho zberigaye drobovu chastinu int y y0 for x from x0 to x1 plot x y c c k if abs c 0 5 then y y 1 c c 1 0 Porivnyuvati z nulem zruchnishe nizh z 0 5 tomu vvedemo novu dopomizhnu velichinu d i 2 c i 1 displaystyle d i 2c i 1 zauvazhimo sho d 1 2 k 1 displaystyle d 1 2k 1 tomu sho c 1 k displaystyle c 1 k void line int x0 int y0 int x1 int y1 int color double k double y1 y0 x1 x0 double d 2 k 1 int y y0 putpixel x0 y0 color for int x x0 1 x lt x1 x if d gt 0 d 2 k 2 y else d 2 k putpixel x y color Popri te sho vhidni dani cilochiselni i vsi operaciyi zdijsnyuyutsya na cilochiselnij gratci algoritm vikoristovuye operaciyi z dijsnimi chislami Shob pozbutisya neobhidnosti yih vikoristannya zauvazhimo sho vsi dijsni chisla prisutni v algoritmi ye chislami vidu p D x p Z displaystyle frac p Delta x p in Z Tomu mozhlivo domnozhiti d i displaystyle d i ta k displaystyle k na D x x 1 x 0 displaystyle Delta x x 1 x 0 i otrimati v rezultati tilki cili chisla Tim samim otrimayemo algoritm Brezenhejma najprostishij algoritm Brezenhejma 0 lt y1 y0 lt x1 x0 void line int x0 int x1 int y0 int y1 int color int dx x1 x0 int dy y1 y0 int d dy lt lt 1 dx int d1 dy lt lt 1 int d2 dy dx lt lt 1 putpixel x0 y0 color for int x x0 1 y y0 x lt x1 x if d gt 0 d d2 y 1 else d d1 putpixel x y color Takozh navedemo uzagalnenij algoritm yakij vrahovuye mozhlivi napryamki vidrizka a takozh spivvidnoshennya D x displaystyle Delta x do D y displaystyle Delta y void segment int x0 int y0 int x1 int y1 int color int dx abs x1 x0 int dy abs y1 y0 int sx x1 gt x0 1 1 int sy y1 gt y0 1 1 if dy lt dx int d dy lt lt 1 dx int d1 dy lt lt 1 int d2 dy dx lt lt 1 putpixel x0 y0 color for int x x0 sx y y0 i 1 i lt dx i x sx if d gt 0 d d2 y sy else d d1 putpixel x y color else int d dx lt lt 1 dy int d1 dx lt lt 1 int d2 dx dy lt lt 1 putpixel x0 y0 color for int y y0 sy x x0 i 1 i lt dy i y sy if d gt 0 d d2 x sx else d d1 putpixel x y color Posilannya Algoritm malyuvannya linij Brezenhejma 25 lyutogo 2021 u Wayback Machine Kolin Flenegana angl Div takozhAlgoritmi pobudovi vidrizka Algoritm Vu Algoritm DDA liniyi