Алгоритъмът за рисуване на кръг на Bresenham
Не е лесно да се покаже непрекъсната гладка дъга на екрана на компютъра, тъй като екранът на нашия компютър е направен от пиксели, организирани в матрична форма. Така че, за да начертаем кръг на компютърен екран, винаги трябва да избираме най-близките пиксели от отпечатания пиксел, така че те да могат да образуват дъга. Има два алгоритъма за това:
- Алгоритъм за рисуване на кръг в средата
- Алгоритъм за чертане на кръг на Брезенхам
Вече обсъдихме Алгоритъм за рисуване на кръг в средата в предишната ни публикация. В тази публикация ще обсъдим алгоритъма за чертане на кръг на Bresenham.
И двата алгоритъма използват ключовата характеристика на кръга, че е силно симетричен. Така че за целия кръг от 360 градуса ще го разделим на 8 части, всеки октант от 45 градуса. За да направим това, ще използваме кръговия алгоритъм на Bresenham за изчисляване на местоположението на пикселите в първия октант от 45 градуса. Предполага се, че центърът на кръга е в началото. Така че за всеки пиксел (x y), който изчислява, рисуваме пиксел във всеки от 8-те октанта на кръга, както е показано по-долу:
За един пиксел (xy) всички възможни пиксели в 8 октанта
Сега ще видим как да изчислим следващото пикселно местоположение от предишно известно пикселно местоположение (x y). В алгоритъма на Bresenham във всяка точка (x y) имаме две възможности или да изберем следващия пиксел на изток, т.е. (x+1 y), или на югоизток, т.е. (x+1 y-1).
И това може да бъде решено чрез използване на параметъра за решение d като:
- Ако d > 0, тогава (x+1 y-1) трябва да бъде избран като следващ пиксел, тъй като ще бъде по-близо до дъгата.
- иначе (x+1 y) трябва да бъде избран като следващ пиксел.
Сега, за да начертаем кръга за даден радиус 'r' и център (xc yc). Ще започнем от (0 r) и ще се движим в първия квадрант до x=y (т.е. 45 градуса). Трябва да започнем от изброеното първоначално условие:
d = 3 - (2 * r)
x = 0
y = rСега за всеки пиксел ще извършим следните операции:
- Задайте начални стойности на (xc yc) и (x y).
- Задайте параметъра за решение d на d = 3 – (2 * r).
- Извикайте функцията drawCircle(int xc int yc int x int y).
- Повторете следните стъпки, докато x <= y:
- Ако d < 0 set d = d + (4 * x) + 6.
- В противен случай задайте d = d + 4 * (x – y) + 10 и намалете y с 1.
- Увеличете стойността на x.
- Извикайте функцията drawCircle(int xc int yc int x int y).
функция drawCircle():
CPP// function to draw all other 7 pixels // present at symmetric position drawCircle ( int xc int yc int x int y ) { putpixel ( xc + x yc + y RED ); putpixel ( xc - x yc + y RED ); putpixel ( xc + x yc - y RED ); putpixel ( xc - x yc - y RED ); putpixel ( xc + y yc + x RED ); putpixel ( xc - y yc + x RED ); putpixel ( xc + y yc - x RED ); putpixel ( xc - y yc - x RED ); }По-долу е C реализация на горния подход.
CPP// C-program for circle drawing // using Bresenham’s Algorithm // in computer-graphics #include#include #include // Function to put pixels // at subsequence points void drawCircle ( int xc int yc int x int y ){ putpixel ( xc + x yc + y RED ); putpixel ( xc - x yc + y RED ); putpixel ( xc + x yc - y RED ); putpixel ( xc - x yc - y RED ); putpixel ( xc + y yc + x RED ); putpixel ( xc - y yc + x RED ); putpixel ( xc + y yc - x RED ); putpixel ( xc - y yc - x RED ); } // Function for circle-generation // using Bresenham's algorithm void circleBres ( int xc int yc int r ){ int x = 0 y = r ; int d = 3 - 2 * r ; drawCircle ( xc yc x y ); while ( y >= x ){ // check for decision parameter // and correspondingly // update d y if ( d > 0 ) { y -- ; d = d + 4 * ( x - y ) + 10 ; } else d = d + 4 * x + 6 ; // Increment x after updating decision parameter x ++ ; // Draw the circle using the new coordinates drawCircle ( xc yc x y ); delay ( 50 ); } } int main () { int xc = 50 yc = 50 r = 30 ; int gd = DETECT gm ; initgraph ( & gd & gm '' ); // initialize graph circleBres ( xc yc r ); // function call return 0 ; } Изход:
![]()
Предимства
- Това е прост алгоритъм.
- Може да се приложи лесно
- Изцяло се основава на уравнението на кръга, т.е. x 2 +y 2 =r 2
Недостатъци
- Има проблем с точността при генериране на точки.
- Този алгоритъм не е подходящ за сложни и високо графични изображения.