Если по быстрым вы имеете в виду быстрое писать, вот простое решение для DOS ,
Он не использует службу DOS, кроме выхода.
Он предназначен для создания COM-файла (необработанный вывод с помощью NASM в порядке, просто переименуйте его с расширением COM).
BITS 16
ORG 100h
push 0a000h ;Video memory graphics segment
pop es
mov ax, 0013h ;[email protected]
int 10h
push 09h ;Blue
push 159 ;cX
push 99 ;cY
push 60 ;Radius
call drawFilledCircle
;Wait for a key
xor ah, ah
int 16h
;Restore text mode
mov ax, 0003h
int 10h
;Return
mov ax, 4c00h
int 21h
;Color
;cX
;cY
;R
drawFilledCircle:
push bp
mov bp, sp
sub sp, 02h
mov cx, WORD [bp+04h] ;R
mov ax, cx
mul ax ;AX = R^2
mov WORD [bp-02h], ax ;[bp-02h] = R^2
mov ax, WORD [bp+06h]
sub ax, cx ;i = cY-R
mov bx, WORD [bp+08h]
sub bx, cx ;j = cX-R
shl cx, 1
mov dx, cx ;DX = Copy of 2R
.advance_v:
push cx
push bx
mov cx, dx
.advance_h:
;Save values
push bx
push ax
push dx
;Compute (i-y) and (j-x)
sub ax, WORD [bp+06h]
sub bx, WORD [bp+08h]
mul ax ;Compute (i-y)^2
push ax
mov ax, bx
mul ax
pop bx ;Compute (j-x)^2 in ax, (i-y)^2 is in bx now
add ax, bx ;(j-x)^2 + (i-y)^2
cmp ax, WORD [bp-02h] ;;(j-x)^2 + (i-y)^2 <= R^2
;Restore values before jump
pop dx
pop ax
pop bx
ja .continue ;Skip pixel if (j-x)^2 + (i-y)^2 > R^2
;Write pixel
push WORD [bp+0ah]
push bx
push ax
call writePx
.continue:
;Advance j
inc bx
loop .advance_h
;Advance i
inc ax
pop bx ;Restore j
pop cx ;Restore counter
loop .advance_v
add sp, 02h
pop bp
ret 08h
;Color
;X
;Y
writePx:
push bp
mov bp, sp
push ax
push bx
mov bx, WORD [bp+04h]
mov ax, bx
shl bx, 6
shl ax, 8
add bx, ax ;320 = 256 + 64
add bx, WORD [bp+06h]
mov ax, WORD [bp+08h]
;TODO: Clip
mov BYTE [es:bx], al
pop bx
pop ax
pop bp
ret 06h
Это просто обычная техника для записи плоских фигур с заданными параметрами, это называется растеризацией.
Учитывая центр С (х, у) и радиус R окружности, алгоритм, как следует
1. For i = y-R to y+R
1.1 For j = x-R to x+R
1.1.1 If (i-y)^2 + (j-x)^2 <= R^2 Then
1.1.1.1 DrawPixel(j, i)
1.1.1 End if
1.1 End For
1. End For
Это не оптимизировано для скорости, при все!
Я действительно создаю несколько процедур для ясности. Также я использую стек много.
ПримечаниеwritePx
не обрезает координаты!
Если вы хотите ускорить то, что вам нужно, чтобы быть более конкретным по вашему требованию.
Например, радиус всегда зафиксирован? Если да, вы можете использовать блок памяти, который кодирует четверть круга, что-то вроде этого
0 0 0 0 0 1 1 1
0 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1
0 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
Где каждый цифры могут быть немного или байт в зависимости от вашей скорости против ограничений памяти.
Затем вы можете скопировать этот блок непосредственно в видеопамять или использовать ее в качестве шаблона (вид технологии цветной клавиши).
Для печати остальных трех четвертей круга просто играть со счетчиками.
Если радиус не фиксирован вы можете увеличить приведенный выше код на
- Встраивание функции называют
- Избегайте использования стека как можно больше
- Не вычислить расстояние в каждый цикл, но вычислять его из предыдущего значения, используя базовое исчисление.
- Вычислите больше одного пикселя за раз и объедините записи.
Нарисуйте контур, а затем заливать заполнить круг. Это не учебный сайт по графическому программированию, поэтому ознакомьтесь с тем, как это сделать, и попытайтесь реализовать их самостоятельно. Если вы столкнулись с конкретной проблемой с кодом, который вы пишете, задайте вопрос об этом. – Michael
Даже проще всего проследить только половину контура круга и зеркально отобразить его по горизонтали. То есть для каждой точки '-x, y' нарисуйте горизонтальную линию от' -x, y' до 'x, y'. – Michael
Идеально для меня означает сглаживание по краям. – stark