0 / 0 / 0
Регистрация: 29.05.2011
Сообщений: 11
1
TASM

Алгоритм построения окружности

04.01.2012, 15:35. Показов 6273. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите с помощью какого алгоритма можно построить окружность на TASM!

Добавлено через 1 час 34 минуты
есть вот этот кусок программы , но я в нём не могу ничего толком понять(( HEEELP !!!
Assembler
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
;AL - radius
;CL - color
;BX - X
;DX - Y
draw_circle proc
            mov  xofs,bx
            mov  yofs,dx
 
            xor  ah,ah
            mov  tmp,ax
            
            
            ;Вычисляем координаты точки
            finit ; инициализируем сопроцессор, флаги и 
;регистры st обнуляются
            fild tmp ; загружаем из памяти в вершину стека 
;ST(0) целое tmp
            fadd step ; складываем содержимое st(0)
            fld st(0) 
            fmul st(0),st(0)
            
            fild  tmp ; в st(0) = tmp
            fchs ; меняем знак
            fsub step 
;-------------------------------------------------------
.next_point:
            fld  st(0) ; заносим в стек fpu
            ;Проверим, не превысили ли диапазон значений х    
            fcom st(3) ; сравнение с st(0)
            fstsw ax ; заносим в ax регистр сост sr
            fwait ; для избежания проблемы синхронизации 
                    ;сопроцессора
                
    sahf ; переносим содержимое регистра ax в регистр 
                   ;флагов ЦП
            ja .loop_out ; если st(0) > tmp
            
            fist rx ; заносим в rx содержимое st(0)
        
            fmul st(0),st(0) 
            fsub st(0),st(2) ; вычтем из st(0) 
            fabs ; берем модуль st(0), в st(0) 
            fsqrt ; квадратный корень st(0)
            
            fistp ry ; заносим в ry содержимое st(0)
            
            mov  ax,rx
            add  ax,xofs
            mov  dx,ry
            add  dx,yofs
            call put_pixel
            
            mov  ax,rx
            add  ax,xofs
            xor  dx,dx
            sub  dx,ry
            add  dx,yofs
            call put_pixel
            
            fadd step
            jmp  .next_point
;-------------------------------------------------------            
.loop_out:      
            ;Очистим стек FPU
            fistp tmp
            fistp tmp
            fistp tmp
            ret
draw_circle endp
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.01.2012, 15:35
Ответы с готовыми решениями:

Алгоритм Брезенхема построения окружности на С++
помогите найти или написать программу алгоритм Брезенхема построения окружности на С++ для Borland...

Реализовать в виде процедуры BrezArc алгоритм построения дуги окружности
Постановка задачи: Реализовать в виде процедуры BrezArc алгоритм построения дуги окружности (при...

Алгоритм устранения непродуктивных нетерминалов, алгоритм построения недостижимых символов
Задание: найдите лишние нетерминалы в следующей грамматике с начальным нетерминалом S и в...

построения графика окружности в C++ builder по заданным ур-ям
Подскажите как построить график окружности,если она,окружность, задается уравнениями? Никогда на...

6
1778 / 756 / 153
Регистрация: 03.06.2009
Сообщений: 5,880
04.01.2012, 15:48 2
http://ru.wikipedia.org/wiki/%... 0.B5.D0.B9
0
0 / 0 / 0
Регистрация: 29.05.2011
Сообщений: 11
04.01.2012, 21:59  [ТС] 3
полезная ссылка ))
но мне бы сам под помочь разобрать - я с работой FPU и со сдвигами ST запутался (
0
11 / 11 / 0
Регистрация: 25.02.2011
Сообщений: 183
06.01.2012, 19:46 4
Окружность по Брезенхэму (под дос)

Assembler
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
dataseg segment para public
 error      dw    ?
 delta      dw    ?
 
 X1         dw    150
 X2         dw    0
 Y1         dw    45
 Y2         dw    5
 
 XX         dw    ?
 YY         dw    ?
 
dataseg ends
 
stackseg segment para stack
    dw 128 dup(0)
stackseg ends
 
 
 
codeseg segment para public
assume cs:codeseg,ds:dataseg,ss:stackseg
start:
 mov     ax, dataseg
 mov     ds, ax
 
                    ;графический режим.
 mov     ah, 00 
 mov     al, 04 
 int     10h
 
 
jmp P1
 
A1:
 
mov     ah,1   
 int     21h
 mov     ax, 4c00h
 int     21h
 ret
 
P1: 
 mov     ax, Y2
 shl     ax, 1
 mov     bx, 2
 sub     bx, ax 
 
 mov     error, 0
D1: 
 mov     ax, Y2
 cmp     ax, 0
 jl      A1  
                  ;Рисование.
 mov     ax, X1
 mov     bx, X2
 add     ax, bx
 mov     XX, ax
 
 mov     ax, Y1
 mov     Bx, Y2
 add     ax, bx
 mov     YY, ax
       
 mov     ah, 0ch
 mov     al, 3
 mov     cx, XX
 mov     dx, YY
 int     10h      ;-----------------1
 
 mov     ax, X1
 mov     bx, X2
 add     ax, bx
 mov     XX, ax
 
 mov     ax, Y1
 mov     Bx, Y2
 sub     ax, bx
 mov     YY, ax
 
 mov     ah, 0ch
 mov     al, 3
 mov     cx, XX
 mov     dx, YY
 int     10h       ;-----------------2
 
 mov     ax, X1
 mov     bx, X2
 sub     ax, bx
 mov     XX, ax
 
 mov     ax, Y1
 mov     Bx, Y2
 add     ax, bx
 mov     YY, ax
 
 mov     ah, 0ch
 mov     al, 3
 mov     cx, XX
 mov     dx, YY
 int     10h      ;------------------3
 
 mov     ax, X1
 mov     bx, X2
 sub     ax, bx
 mov     XX, ax
 
 mov     ax, Y1
 mov     Bx, Y2
 sub     ax, bx
 mov     YY, ax
 
 mov     ah, 0ch
 mov     al, 3
 mov     cx, XX
 mov     dx, YY
 int     10h      ;------------------4
 
 mov     ax, delta
 mov     bx, Y2
 add     ax, bx
 shl     ax, 1
 mov     bx, 1
 sub     ax, bx
 mov     error, ax
 
                  ; Условие.
 mov     ax, delta
 cmp     ax, 0
 jl      B1
C1: 
 mov     ax, delta
 mov     bx, X2
 sub     ax, bx
 shl     ax, 1
 mov     bx, 1
 sub     ax, bx
 mov     error, ax
 
 mov     ax, delta
 cmp     ax, 0
 jg      E1
F1: 
 mov     ax, X2
 inc     ax
 mov     X2, ax
 
 mov     ax, X2
 mov     bx, Y2
 sub     ax, bx
 shl     ax, 1
 mov     bx, delta
 add     ax, bx
 mov     delta, ax
 
 mov     ax, Y2
 dec     ax
 mov     Y2, ax
 jmp     D1     
 
 
B1: 
 mov     ax, error
 cmp     ax, 0
 jg      C1
 
 mov     ax, X2
 inc     ax
 mov     X2, ax
 
 mov     ax, delta
 mov     bx, X2
 shl     bx, 1
 add     bx, 1
 add     ax, bx
 mov     delta, ax
 jmp     D1     
 
E1:
 mov    ax, error
 cmp    ax, 0
 jl     F1    
 
 mov     ax, Y2
 dec     ax
 mov     Y2, ax
 
 mov     ax, 1
 mov     bx, Y2
 shl     bx, 1
 sub     ax, bx
 mov     bx, delta
 add     ax, bx
 jmp     D1
 
codeseg ends
end start
Вложения
Тип файла: rar K.rar (325 байт, 70 просмотров)
0
4149 / 1803 / 213
Регистрация: 06.10.2010
Сообщений: 4,033
07.01.2012, 09:17 5
Основная идея алгоритма Брезенхема.
1) Исходя из теоремы Пифагора выводим уравнение окружности r*r=x*x+y*y.
2) Находим y=sqrt(r*r-x*x)
3) Таким нехитрым путём можно нарисовать 1/8 часть окружности. Остальные 7/8 получаются отражениями и поворотами на 90 градусов.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var
  x,y,_x,_y,r,r2: integer;
begin
x:=100; //x-координата центра
y:=100; //y-координата центра
r:=60;  //радиус
r2:=sqr(r);
r :=round(r*3/4);
_x:=0;
_y:=0;
repeat
  _y:=round(sqrt(r2-sqr(_x)));
  SetPixel(Form1.Canvas.Handle,x+_x,y+_y,0);
  SetPixel(Form1.Canvas.Handle,x-_x,y+_y,0);
  SetPixel(Form1.Canvas.Handle,x-_x,y-_y,0);
  SetPixel(Form1.Canvas.Handle,x+_x,y-_y,0);
  SetPixel(Form1.Canvas.Handle,x+_y,y+_x,0);
  SetPixel(Form1.Canvas.Handle,x-_y,y+_x,0);
  SetPixel(Form1.Canvas.Handle,x-_y,y-_x,0);
  SetPixel(Form1.Canvas.Handle,x+_y,y-_x,0);
  inc(_x);
until _x>r;
0
Ушел с форума
Автор FAQ
15893 / 7467 / 1012
Регистрация: 11.11.2010
Сообщений: 13,449
08.01.2012, 07:04 6
RandLogMad, Ниже программа, которая выводит окружность. С точки зрения программирования достаточно нарисовать 1/8 часть окружности, Как написал murderer,
Остальные 7/8 получаются отражениями и поворотами на 90 градусов.
Функции ЯВУ CIRCLE строят окружности либо, вычисляя синус, либо, двигаясь например по оси X, вычисляют на каждом шаге координату Y по формуле https://www.cyberforum.ru/cgi-bin/latex.cgi?\sqrt{R^{2}-X^{2}}. Для вычисления квадратного корня или функции синуса пришлось бы использовать сопроцессор, но мы нарисуем окружность используя только целочисленную арифметику, да и на экране можно выводить точку только туда, где находится люминофор, а не между люминофорами. Пусть центр окружности находится в точке (0, 0) Y=R=100 и X=0 по формуле Y² равен R²−X². По мере движения по оси X мы должны выяснить, когда нам необходимо уменьшить Y. Это нужно сделать если отклонение от Y будет больше 0,5 величины люминофора, т.е. больше должна засвечиваться соседняя точка. Вычисляем квадрат отклонения: (Y−0,5)²=Y²−Y+0,25. Выражение Y²−Y вычисляется в целых числах, а 0,25 игнорируем. Если разность R²−X² больше чем Y²−Y необходимо уменьшить Y на единицу и опять пересчитать ту величину, когда необходимо будет снова изменить Y и так в цикле. Выводим N точек, где N вычисляется из значения L=2*https://www.cyberforum.ru/cgi-bin/latex.cgi?\pi*R. Так как нужно нарисовать 1/8 окружности N=L/8=https://www.cyberforum.ru/cgi-bin/latex.cgi?\pi*R/4≈157*R/200. При изменении строки radius equ ХХ все остальные константы пересчитаются автоматически
Assembler
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
; masm dos com #
.286 
.model tiny
.code
org 100h
radius equ 99 ;рисуем окружность с радиусом 99
radius2 equ radius*radius ;квадрат радиуса
diametr equ radius*2 ;диаметр окружности
n equ 157*radius/200;количество точек на 1/8 
color equ 10 ;цвет окружности
start:    mov ah,0Fh  ;узнать номер текущего видеорежима
    int 10h
    mov videor,al ;запомним текущий видеорежим
    mov ax,13h;установить видеорежим 320х200х256 
    int 10h
    push 0A000h;установить регистр es на сегмент 
    pop es ; видеопамяти
    xor bp,bp ;будем увеличивать x и y
    mov y,radius-1 ;координаты x=0 и y=r
    call draw_oct1 ;рисуем восьмушку окружности
    mov bp,radius-1 ;координата x=2*r
    mov y,0 ;координата y=0
    call draw_oct2 ;рисуем восьмушку окружности
    neg delta_x ;увеличиваем y и уменьшаем x
    mov y,radius  
    mov bp,diametr ;координаты y=r и x=2*r
    call draw_oct1 ;рисуем восьмушку окружности
    mov bp,radius ;координата x=r
    mov y,0 ;координата y=0
    call draw_oct2 ;рисуем восьмушку окружности
    neg delta_y ;уменьшаем координаты y и x
    mov y,radius ;координата y=r
    mov bp,diametr ;координата x=2*r
    call draw_oct1 ;рисуем восьмушку окружности
    mov bp,radius ;координата x=r
    mov y,diametr ;координата y=2*r
    call draw_oct2 ;рисуем восьмушку окружности
    neg delta_x ; уменьшаем y и увеличиваем x
    xor bp,bp ;координата x=0
    mov y,radius ;координата y=r
    call draw_oct1 ;рисуем восьмушку окружности
    mov bp,radius ;координата x=r
    mov y,diametr ;координата y=2*r
    call draw_oct2 ;рисуем восьмушку окружности
    xor ax,ax  ;ожидание нажатия любой клавиши
    int 16h
    mov ax,word ptr videor;восстановление видеорежима
    int 10h
    ret  ;выход из программы
delta_calc proc;рассчитаем ошибку накопления
    mov bx,ax ;в ax значение координаты x или y 
    dec ax ;вычислим (y+0,5)^2 = y^2+y+0,25
    mul ax ;или (x+0,5)^2 = x^2+x+0,25
    add ax,bx
    mov delta,ax ;и поместим это значение в delta
    retn
delta_calc endp
;процедура прорисовки 1/8 окружности с вычислением 
draw_oct1 proc; координаты x
    imul di,y,320; di=y*320 
    mov ax,bp  
    sub ax,radius ;bp=x ax=r-x
    call delta_calc ;расчет ошибки накопления по x
    mov cx,n
circ1: mov ax,y
    sub ax,radius ;ax=y-r 
    mul ax
    neg ax
    add ax,radius2 ;ax=r^2-y^2
    cmp delta,ax ;сравнить текущий x^2=r^2-y^2 с ошибкой 
    jbe a3 ;накопления, если меньше, увеличиваем или 
    add bp,delta_x;уменьшаем только y, иначе 
    mov ax,bp;увеличиваем или уменьшаем еще и x и 
    sub ax,radius; вычисляем новую ошибку накопления
    call delta_calc
a3:    cmp delta_y,1
    jne a1
    add di,320
    jmp short a2
a1:    sub di,320
a2:    mov byte ptr es:[di][bp],color;выводим точку на 
    mov ax,delta_y; экран
    add y,ax
    loop circ1  ;повторяем цикл
    retn
draw_oct1 endp
;процедура прорисовки 1/8 окружности с вычислением 
draw_oct2 proc; координаты x
    imul di,y,320; di=y*320
    mov ax, y
    sub ax,radius
    call delta_calc
    mov cx,n
circ2:    mov ax,bp
    sub ax,radius
    mul ax
    neg ax
    add ax,radius2 ;ax=r^2-(x-r)^2
    cmp delta,ax
    jbe a5
    mov ax,delta_y
    add y,ax
    mov ax,y
    sub ax,radius
    call delta_calc
    cmp delta_y,1
    jne a4
    add di,320
    jmp short a5
a4:    sub di,320
a5:    add bp,delta_x
    mov byte ptr es:[di][bp],color
    loop circ2
    retn
draw_oct2 endp
videor db 0,0  ;значение текущего видеорежима
delta dw  0 ;ошибка накопления
delta_x dw  1 ;смещение по оси x
delta_y dw  1 ;смещение по оси y
y  dw  0 ;координата y
end start
0
4149 / 1803 / 213
Регистрация: 06.10.2010
Сообщений: 4,033
08.01.2012, 08:39 7
Если заморачиваться с оптимизацией, то можно работать сразу с линейными адресами вместо экранных координат .

Вот что у меня получилось.
data - видеобуффер
width - ширина видеобуффера в пикселях
Код
Delphi
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
43
44
45
46
47
48
49
50
51
52
53
procedure TRaster.Circle(xc,yc,r:word;color: dword);
var
    i1,i2,i3,i4,i5,i6,i7,i8: dword;
    x,y,d:integer;
begin
    d :=r*width;
    yc:=yc*width;
    i1:=yc+xc+d;
    i2:=yc+xc-d;
    i3:=i2;
    i4:=i1;
    i5:=yc+xc+r;
    i6:=i5;
    i7:=yc+xc-r;
    i8:=i7;
    d :=3-r-r;
    x :=0;
    y :=r shl 2;
    while(x<=y) do
    begin
        dword(data[i1]):=color;
        dword(data[i2]):=color;
        dword(data[i3]):=color;
        dword(data[i4]):=color;
        dword(data[i5]):=color;
        dword(data[i6]):=color;
        dword(data[i7]):=color;
        dword(data[i8]):=color;
        if d>=0 then
        begin
            y :=y-4;
            d :=d-y;
            i1:=i1-width;
            i2:=i2+width;
            i3:=i3+width;
            i4:=i4-width;
            i5:=i5-1;
            i6:=i6-1;
            i7:=i7+1;
            i8:=i8+1;
        end;
        d :=d+x+6;
        x :=x+4;
        i1:=i1+1;
        i2:=i2+1;
        i3:=i3-1;
        i4:=i4-1;
        i5:=i5+width;
        i6:=i6-width;
        i7:=i7-width;
        i8:=i8+width;
    end;
end;
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.01.2012, 08:39
Помогаю со студенческими работами здесь

Алгоритм построения звезды
Проблема заключается в следующем: Есть фигура, построенная из 4 примитивов(треугольников). При...

Алгоритм построения функции
Строю синусойду по формуле y = b+a*sin(c*x+d) a - амплитуда с - сдвиг фазы b - сдвиг по оси Y...

Алгоритм построения круга
Не могу понять почему рисует только круг. using System; using System.Collections.Generic;...

Алгоритм построения функции
привет, 1. не подскажите где найти алгоритм решения? 2. или готовое решение(исходники) на...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru