Форум программистов, компьютерный форум, киберфорум
Turbo Pascal
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
135 / 135 / 29
Регистрация: 18.10.2011
Сообщений: 306

Алгоритм Брезенхэма для окружности

18.10.2011, 15:11. Показов 3030. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужно нарисовать картинку используя векторную геометрическую модель. Я нарисовал ее, используя стандартные процедуры Graph (line,circle,rectangle). Следующая часть - передвижение этой картинки по экрану. На экране есть некоторое фоновое изображение, по верх которого нужно двигать картинку. Все вроде бы хорошо. Добавляем приращение к координатам, передвигаем картинку. Для того, что бы подтирать след за картинкой и не затирать фоновое делаем вывод с использованием операции xor. Загвоздка в том, что Circle не поддерживает вывод с использованием xor, следовательно нужно писать собственную подпрограмму для вывода окружностей. Отлично. Берем алгоритм Брезенхема, пишем подпрограмму. И снова вроде бы все работает, но теперь проблемы с пропорциями окружности в некоторых видео-режимах, связанные с неквадратичностью пикселя. Стандартная процедура Circle выводит окружность с учетом неквадратичности пикселя.
Как мне нужно модифицировать эту подпрограмму, что бы результат ее работы был схож со стандартной Circle ?


Пробовал сделать так:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
....
GetAspectRatio(Xasp,Yasp);
koef:=longint(Xasp)/longint(Yasp);
...
 if (y <> 0) then begin
  line(x1+x,round((y1+y)*koef),x1+x,round((y1+y)*koef));
  line(x1-x,round((y1-y)*koef),x1-x,round((y1-y)*koef));
 end;
 if (x <> 0) then begin
  line(x1-x,round((y1+y)*koef),x1-x,round((y1+y)*koef));
  line(x1+x,round((y1-y)*koef),x1+x,round((y1-y)*koef));
 end;
...
"окружность" приняла более округлую форму, но по краям почему-то появились разрывы линии =( , скорее всего разрывы из-за xor вывода, печалька вообщем.

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
procedure bvCircle(x1,y1,r:integer);
var x,y,e,d:integer;
begin
x:=0;
y:=r;
d:=2-2*r;
e:=0;
while (y >= 0) do begin
 if (y <> 0) then begin
  line(x1+x,y1+y,x1+x,y1+y);
  line(x1-x,y1-y,x1-x,y1-y);
 end;
 if (x <> 0) then begin
  line(x1-x,y1+y,x1-x,y1+y);
  line(x1+x,y1-y,x1+x,y1-y);
 end;
 e:=2*(d+y)-1;
 if ((d < 0) and (e <= 0)) then begin
  inc(x);
  d:= d+(2*x+1);
  continue;
 end;
 e:=2*(d-x)-1;
 if ((d > 0) and (e > 0)) then begin
  dec(y);
  d:=d+(1-2*y);
  continue;
 end;
 inc(x);
 d:=d+(2*(x-y));
 dec(y);
end;
end;
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.10.2011, 15:11
Ответы с готовыми решениями:

Непонятен принцип работы алгоритма Брезенхэма для растровой развёртки окружности
Вот пример с википедии,непонятны следующие моменты(а конкретно на чём основан выбор переменных(значений) в выражениях и что конкретно...

Алгоритм Брезенхэма
Здравствуйте. Помогите пожалуйста разобраться с алгоритмом Брезенхэма. Кому не сложно поставте пожалуйста комментарии подробные к...

Алгоритм Брезенхэма
Добрый вечер! пожалуйста помогите разобрать построение прямой через заданные две точки с координатами x1,y1 и x2,y2.

6
135 / 135 / 29
Регистрация: 18.10.2011
Сообщений: 306
20.10.2011, 22:57  [ТС]
Следующим фиксом избавляемся от разрыва линии по бокам.
Но теперь проблема в режиме 640*200 точек для адаптеров ega и vga. Окружность растягивается до эллипса по вертикали =( Зато теперь работает идентично стандартной процедуре Circle.
Вопрос: Как бы теперь поправить этот дефект при разрешении 640*200 ?
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
....
GetAspectRatio(Xasp,Yasp);
koef:=longint(Xasp)/longint(Yasp);
...
 if (y <> 0) then begin
  line(x1+x,y1+round(y*koef),x1+x,y1+round(y*koef));
  line(x1-x,y1-round(y*koef),x1-x,y1-round(y*koef));
 end;
 if (x <> 0) then begin
  line(x1-x,y1+round(y*koef),x1-x,y1+round(y*koef));
  line(x1+x,y1-round(y*koef),x1+x,y1-round(y*koef));
 end;
...
0
Почетный модератор
 Аватар для Puporev
64315 / 47611 / 32743
Регистрация: 18.05.2008
Сообщений: 115,167
21.10.2011, 11:40
Цитата Сообщение от forgergg Посмотреть сообщение
Окружность растягивается до эллипса по вертикали
Может ввести еще коэффициент сжатия по оси Y?
Pascal
1
ky:=getmaxY/getmaxX;
0
135 / 135 / 29
Регистрация: 18.10.2011
Сообщений: 306
21.10.2011, 13:01  [ТС]
И куда его подцепить ? Коэффициент сжатия по Y и так через аспект находится.
0
Почетный модератор
 Аватар для Puporev
64315 / 47611 / 32743
Регистрация: 18.05.2008
Сообщений: 115,167
21.10.2011, 13:04
Pascal
1
y1+round(y*koef*ky);
0
135 / 135 / 29
Регистрация: 18.10.2011
Сообщений: 306
21.10.2011, 15:03  [ТС]
Цитата Сообщение от Puporev Посмотреть сообщение
Pascal
1
y1+round(y*koef*ky);
Так тоже не годится, пережимает окружность до эллипса, вытянутого по горизонтали.
Вообще, самый первый вариант отлично работал, за исключение разрыва линии. Линия разрывалась потому, что несколько раз в одну и туже точку выводил, а раз используется xor, то точка затерается.
Все было бы отлично, если бы мне потом не надо было картинку перемещать =(
Pascal
1
round(y1+y*koef);
0
135 / 135 / 29
Регистрация: 18.10.2011
Сообщений: 306
24.10.2011, 15:17  [ТС]
fuck yeah /
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
procedure bvCircle(x1,y1,r:integer);
 
    procedure put_circle(x,y,oldx,oldy:integer;koef:real);
    begin
         if(y <> 0) then begin
        line(x1+x,y1+round(y*koef),x1+x,y1+round(y*koef));
                line(x1-x,y1-round(y*koef),x1-x,y1-round(y*koef));
         end;
         if(x <> 0) then begin
                line(x1-x,y1+round(y*koef),x1-x,y1+round(y*koef));
                line(x1+x,y1-round(y*koef),x1+x,y1-round(y*koef));
         end;
    end;
 
var x,y,oldx,oldy,e,d,count:integer;
Xasp,Yasp:word;
koef:real;
begin
GetAspectRatio(Xasp,Yasp);
koef:=longint(xasp)/longint(yasp);
x:=0;
y:=r;
oldx:=-1;
oldy:=oldx;
d:=3-2*r;
while(x<y) do begin
 
    put_circle(x,y,oldx,oldy,koef);
  if not((y=oldy) and (round(x*koef)=round(oldx*koef))) then
    put_circle(y,x,oldy,oldx,koef);
 
  oldx:=x;
  oldy:=y;
    if (d < 0) then d:=d+4*x+6
    else begin
        d:=d+4*(x-y)+10;
                dec(y);
    end;
  inc(x);
end;
if(x = y) then put_circle(x,y,oldx,oldy,koef);
end;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.10.2011, 15:17
Помогаю со студенческими работами здесь

Алгоритм Брезенхэма
Ребят, кто знает где можно найти хорошее чтиво(ссылку) по Теме: &quot;построение окружности и отрезка (по Брезенхему)&quot; Именно нужна не...

Алгоритм Брезенхэма
У кого есть программа, которая реализует алгоритм Брезенхема

Алгоритм Брезенхэма
Разбираюсь с принципом использования Алгоритма Брезенхэма, при написании программы на С++ возникают ошибки, не могу понять по какой причине...

Нарисовать линию (алгоритм Брезенхэма)
Второй раз работаю с делфи и потребовалась ваша помощь. Помогите разобраться в коде программы(и дописать его). по рисованию линии из...

Резиновая линия (Алгоритм Брезенхэма)
Ребят, вообщем проблема такая. имеется задача реализовать построение резиновой линии при помощи алгоритма Брезенхэма. открываем фото...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru