Floodfill — различия между версиями
Материал из SpeccyWiki
Goblinish (обсуждение | вклад) (Содержимое страницы заменено на «Статья удаленна из-за самоуправства рязанского пидора Димачки Быстров…») |
Maksagor (обсуждение | вклад) (Отмена правки 35915, сделанной участником Goblinish (обс.) причина:наличие личных оскорблений в нецензурной форме) |
||
| Строка 1: | Строка 1: | ||
| − | + | Алгоритм основан на коде(Basic): | |
| + | <code><pre> | ||
| + | 5 REM AUTHOR UNKNOWN | ||
| + | 10 CIRCLE 128,88,80 | ||
| + | 20 LET x=100 : LET y = 100 : REM START POINT | ||
| + | 30 GO SUB 1000 : STOP | ||
| + | |||
| + | 1000 PLOT x,y | ||
| + | 1010 IF NOT POINT(x+1,y) THEN LET x=x+1 : GO SUB 1000 : LET x=x-1 | ||
| + | 1020 IF NOT POINT(x-1,y) THEN LET x=x-1 : GO SUB 1000 : LET x=x+1 | ||
| + | 1030 IF NOT POINT(x,y+1) THEN LET y=y+1 : GO SUB 1000 : LET y=y-1 | ||
| + | 1040 IF NOT POINT(x,y-1) THEN LET y=y-1 : GO SUB 1000 : LET y=y+1 | ||
| + | 1050 RETURN | ||
| + | </pre></code> | ||
| + | |||
| + | Alvin Albrecht в статье "A Fast Well-Behaved Pattern Flood Fill" предложил ускоренный вариант, теперь в экранной области не сканируется каждая точка, а заполняется значением #ff, если байт нулевой. исходники в статье содержат неточности, поэтому приводится дизассемблированный текст. | ||
| + | |||
| + | Входные параметры: hl=YX координаты точки заливки области. | ||
| + | |||
| + | <code><pre> | ||
| + | fill: | ||
| + | ld bc, 64h | ||
| + | call sub_800B | ||
| + | ret | ||
| + | ; =============== S U B R O U T I N E ======================================= | ||
| + | sub_800B: | ||
| + | ld a, h | ||
| + | cp 0C0h | ||
| + | ret nc | ||
| + | dec bc | ||
| + | push bc | ||
| + | call sub_80F9 | ||
| + | ex de, hl | ||
| + | call sub_814B | ||
| + | jr c, loc_801C | ||
| + | pop bc | ||
| + | ret | ||
| + | loc_801C: | ||
| + | ld ix, 0FFFFh | ||
| + | add ix, sp | ||
| + | push hl | ||
| + | push bc | ||
| + | inc sp | ||
| + | xor a | ||
| + | push af | ||
| + | dec sp | ||
| + | ld c, (ix+1) | ||
| + | ld b, (ix+2) | ||
| + | inc bc | ||
| + | ld l, c | ||
| + | ld h, b | ||
| + | add hl, bc | ||
| + | add hl, bc | ||
| + | ld c, l | ||
| + | ld b, h | ||
| + | ld h, a | ||
| + | ld l, a | ||
| + | sbc hl, bc | ||
| + | add hl, sp | ||
| + | ld (hl), a | ||
| + | ld sp, hl | ||
| + | ld a, 80h | ||
| + | push af | ||
| + | inc sp | ||
| + | ld e, l | ||
| + | ld d, h | ||
| + | inc de | ||
| + | dec bc | ||
| + | ldir | ||
| + | push ix | ||
| + | pop bc | ||
| + | ld hl, 0FFFAh | ||
| + | add hl, bc | ||
| + | ex de, hl | ||
| + | ld l, c | ||
| + | ld h, b | ||
| + | loc_8050: | ||
| + | ld a, (hl) | ||
| + | cp 80h | ||
| + | jr c, loc_8059 | ||
| + | push ix | ||
| + | pop hl | ||
| + | ld a, (hl) | ||
| + | loc_8059: | ||
| + | cp 40h | ||
| + | jr c, loc_80B8 | ||
| + | ld b, a | ||
| + | dec hl | ||
| + | ld c, (hl) | ||
| + | dec hl | ||
| + | ld a, (hl) | ||
| + | dec hl | ||
| + | inc (ix+1) | ||
| + | jr nz, loc_806B | ||
| + | inc (ix+2) | ||
| + | loc_806B: | ||
| + | push hl | ||
| + | ld l, c | ||
| + | ld h, b | ||
| + | ld b, a | ||
| + | push hl | ||
| + | call sub_8120 | ||
| + | jr c, loc_807D | ||
| + | push bc | ||
| + | call sub_814B | ||
| + | call c, sub_80D3 | ||
| + | pop bc | ||
| + | loc_807D: | ||
| + | pop hl | ||
| + | push hl | ||
| + | call sub_8135 | ||
| + | jr c, loc_808C | ||
| + | push bc | ||
| + | call sub_814B | ||
| + | call c, sub_80D3 | ||
| + | pop bc | ||
| + | loc_808C: | ||
| + | pop hl | ||
| + | bit 7, b | ||
| + | jr z, loc_80A3 | ||
| + | push hl | ||
| + | ld a, l | ||
| + | dec l | ||
| + | and 1Fh | ||
| + | jr z, loc_80A2 | ||
| + | push bc | ||
| + | ld b, 1 | ||
| + | call sub_814B | ||
| + | call c, sub_80D3 | ||
| + | pop bc | ||
| + | loc_80A2: | ||
| + | pop hl | ||
| + | loc_80A3: | ||
| + | bit 0, b | ||
| + | jr z, loc_80B5 | ||
| + | inc l | ||
| + | ld a, l | ||
| + | and 1Fh | ||
| + | jr z, loc_80B5 | ||
| + | ld b, 80h | ||
| + | call sub_814B | ||
| + | call c, sub_80D3 | ||
| + | loc_80B5: | ||
| + | pop hl | ||
| + | jr loc_8050 | ||
| + | loc_80B8: | ||
| + | dec hl | ||
| + | dec hl | ||
| + | dec hl | ||
| + | ld a, (de) | ||
| + | cp 80h | ||
| + | jr c, loc_80C3 | ||
| + | push ix | ||
| + | pop de | ||
| + | loc_80C3: | ||
| + | xor a | ||
| + | ld (de), a | ||
| + | dec de | ||
| + | dec de | ||
| + | dec de | ||
| + | ld a, (hl) | ||
| + | cp 40h | ||
| + | jr nc, loc_8050 | ||
| + | ld sp, ix | ||
| + | inc sp | ||
| + | inc sp | ||
| + | inc sp | ||
| + | ret | ||
| + | ; =============== S U B R O U T I N E ======================================= | ||
| + | sub_80D3: | ||
| + | push hl | ||
| + | ld l, (ix+1) | ||
| + | ld h, (ix+2) | ||
| + | ld a, h | ||
| + | or l | ||
| + | jr nz, loc_80E0 | ||
| + | pop hl | ||
| + | ret | ||
| + | loc_80E0: | ||
| + | dec hl | ||
| + | ld (ix+1), l | ||
| + | ld (ix+2), h | ||
| + | pop hl | ||
| + | ld a, (de) | ||
| + | cp 80h | ||
| + | jr c, loc_80F0 | ||
| + | push ix | ||
| + | pop de | ||
| + | loc_80F0: | ||
| + | ex de, hl | ||
| + | ld (hl), d | ||
| + | dec hl | ||
| + | ld (hl), e | ||
| + | dec hl | ||
| + | ld (hl), b | ||
| + | dec hl | ||
| + | ex de, hl | ||
| + | ret | ||
| + | ; =============== S U B R O U T I N E ======================================= | ||
| + | sub_80F9: | ||
| + | and 7 | ||
| + | or 40h | ||
| + | ld d, a | ||
| + | ld a, h | ||
| + | rra | ||
| + | rra | ||
| + | rra | ||
| + | and 18h | ||
| + | or d | ||
| + | ld d, a | ||
| + | ld a, l | ||
| + | and 7 | ||
| + | ld b, a | ||
| + | ld a, 80h | ||
| + | jr z, loc_8111 | ||
| + | loc_810E: | ||
| + | rra | ||
| + | djnz loc_810E | ||
| + | loc_8111: | ||
| + | ld b, a | ||
| + | srl l | ||
| + | srl l | ||
| + | srl l | ||
| + | ld a, h | ||
| + | rla | ||
| + | rla | ||
| + | and 0E0h | ||
| + | or l | ||
| + | ld e, a | ||
| + | ret | ||
| + | ; =============== S U B R O U T I N E ======================================= | ||
| + | sub_8120: | ||
| + | ld a, h | ||
| + | dec h | ||
| + | and 7 | ||
| + | ret nz | ||
| + | ld a, 8 | ||
| + | add a, h | ||
| + | ld h, a | ||
| + | ld a, l | ||
| + | sub 20h | ||
| + | ld l, a | ||
| + | ret nc | ||
| + | ld a, h | ||
| + | sub 8 | ||
| + | ld h, a | ||
| + | cp 40h | ||
| + | ret | ||
| + | ; =============== S U B R O U T I N E ======================================= | ||
| + | sub_8135: | ||
| + | inc h | ||
| + | ld a, h | ||
| + | and 7 | ||
| + | ret nz | ||
| + | ld a, h | ||
| + | sub 8 | ||
| + | ld h, a | ||
| + | ld a, l | ||
| + | add a, 20h | ||
| + | ld l, a | ||
| + | ret nc | ||
| + | ld a, h | ||
| + | add a, 8 | ||
| + | ld h, a | ||
| + | cp 58h | ||
| + | ccf | ||
| + | ret | ||
| + | ; =============== S U B R O U T I N E ======================================= | ||
| + | sub_814B: | ||
| + | ld a, b | ||
| + | xor (hl) | ||
| + | and b | ||
| + | ret z | ||
| + | ld b, a | ||
| + | loc_8150: | ||
| + | rra | ||
| + | ld c, a | ||
| + | ld a, b | ||
| + | add a, a | ||
| + | or c | ||
| + | or b | ||
| + | ld c, a | ||
| + | xor (hl) | ||
| + | and c | ||
| + | cp b | ||
| + | ld b, a | ||
| + | jp nz, loc_8150 | ||
| + | or (hl) | ||
| + | ld (hl), a | ||
| + | scf | ||
| + | ret | ||
| + | |||
| + | </pre></code> | ||
| + | ссылки: | ||
| + | http://en.wikipedia.org/wiki/Flood_fill | ||
| + | |||
| + | http://wos.meulie.net/pub/spectrum/games-info/f/FastWell-BehavedPatternFloodFillA.doc | ||
| + | (статья содержит подробную статью о структуре экранной области, приведены исходные тексты Basic.) | ||
| + | http://www.timexsinclair.org/alvin/tidbits/fillprogs.zip | ||
| + | (.TAP-файлы пример программ на Basic, статья ссылается на архив) | ||
| + | [[Категория:Программирование графики]] | ||
Текущая версия на 01:12, 8 августа 2017
Алгоритм основан на коде(Basic):
5 REM AUTHOR UNKNOWN
10 CIRCLE 128,88,80
20 LET x=100 : LET y = 100 : REM START POINT
30 GO SUB 1000 : STOP
1000 PLOT x,y
1010 IF NOT POINT(x+1,y) THEN LET x=x+1 : GO SUB 1000 : LET x=x-1
1020 IF NOT POINT(x-1,y) THEN LET x=x-1 : GO SUB 1000 : LET x=x+1
1030 IF NOT POINT(x,y+1) THEN LET y=y+1 : GO SUB 1000 : LET y=y-1
1040 IF NOT POINT(x,y-1) THEN LET y=y-1 : GO SUB 1000 : LET y=y+1
1050 RETURN
Alvin Albrecht в статье "A Fast Well-Behaved Pattern Flood Fill" предложил ускоренный вариант, теперь в экранной области не сканируется каждая точка, а заполняется значением #ff, если байт нулевой. исходники в статье содержат неточности, поэтому приводится дизассемблированный текст.
Входные параметры: hl=YX координаты точки заливки области.
fill:
ld bc, 64h
call sub_800B
ret
; =============== S U B R O U T I N E =======================================
sub_800B:
ld a, h
cp 0C0h
ret nc
dec bc
push bc
call sub_80F9
ex de, hl
call sub_814B
jr c, loc_801C
pop bc
ret
loc_801C:
ld ix, 0FFFFh
add ix, sp
push hl
push bc
inc sp
xor a
push af
dec sp
ld c, (ix+1)
ld b, (ix+2)
inc bc
ld l, c
ld h, b
add hl, bc
add hl, bc
ld c, l
ld b, h
ld h, a
ld l, a
sbc hl, bc
add hl, sp
ld (hl), a
ld sp, hl
ld a, 80h
push af
inc sp
ld e, l
ld d, h
inc de
dec bc
ldir
push ix
pop bc
ld hl, 0FFFAh
add hl, bc
ex de, hl
ld l, c
ld h, b
loc_8050:
ld a, (hl)
cp 80h
jr c, loc_8059
push ix
pop hl
ld a, (hl)
loc_8059:
cp 40h
jr c, loc_80B8
ld b, a
dec hl
ld c, (hl)
dec hl
ld a, (hl)
dec hl
inc (ix+1)
jr nz, loc_806B
inc (ix+2)
loc_806B:
push hl
ld l, c
ld h, b
ld b, a
push hl
call sub_8120
jr c, loc_807D
push bc
call sub_814B
call c, sub_80D3
pop bc
loc_807D:
pop hl
push hl
call sub_8135
jr c, loc_808C
push bc
call sub_814B
call c, sub_80D3
pop bc
loc_808C:
pop hl
bit 7, b
jr z, loc_80A3
push hl
ld a, l
dec l
and 1Fh
jr z, loc_80A2
push bc
ld b, 1
call sub_814B
call c, sub_80D3
pop bc
loc_80A2:
pop hl
loc_80A3:
bit 0, b
jr z, loc_80B5
inc l
ld a, l
and 1Fh
jr z, loc_80B5
ld b, 80h
call sub_814B
call c, sub_80D3
loc_80B5:
pop hl
jr loc_8050
loc_80B8:
dec hl
dec hl
dec hl
ld a, (de)
cp 80h
jr c, loc_80C3
push ix
pop de
loc_80C3:
xor a
ld (de), a
dec de
dec de
dec de
ld a, (hl)
cp 40h
jr nc, loc_8050
ld sp, ix
inc sp
inc sp
inc sp
ret
; =============== S U B R O U T I N E =======================================
sub_80D3:
push hl
ld l, (ix+1)
ld h, (ix+2)
ld a, h
or l
jr nz, loc_80E0
pop hl
ret
loc_80E0:
dec hl
ld (ix+1), l
ld (ix+2), h
pop hl
ld a, (de)
cp 80h
jr c, loc_80F0
push ix
pop de
loc_80F0:
ex de, hl
ld (hl), d
dec hl
ld (hl), e
dec hl
ld (hl), b
dec hl
ex de, hl
ret
; =============== S U B R O U T I N E =======================================
sub_80F9:
and 7
or 40h
ld d, a
ld a, h
rra
rra
rra
and 18h
or d
ld d, a
ld a, l
and 7
ld b, a
ld a, 80h
jr z, loc_8111
loc_810E:
rra
djnz loc_810E
loc_8111:
ld b, a
srl l
srl l
srl l
ld a, h
rla
rla
and 0E0h
or l
ld e, a
ret
; =============== S U B R O U T I N E =======================================
sub_8120:
ld a, h
dec h
and 7
ret nz
ld a, 8
add a, h
ld h, a
ld a, l
sub 20h
ld l, a
ret nc
ld a, h
sub 8
ld h, a
cp 40h
ret
; =============== S U B R O U T I N E =======================================
sub_8135:
inc h
ld a, h
and 7
ret nz
ld a, h
sub 8
ld h, a
ld a, l
add a, 20h
ld l, a
ret nc
ld a, h
add a, 8
ld h, a
cp 58h
ccf
ret
; =============== S U B R O U T I N E =======================================
sub_814B:
ld a, b
xor (hl)
and b
ret z
ld b, a
loc_8150:
rra
ld c, a
ld a, b
add a, a
or c
or b
ld c, a
xor (hl)
and c
cp b
ld b, a
jp nz, loc_8150
or (hl)
ld (hl), a
scf
ret
ссылки: http://en.wikipedia.org/wiki/Flood_fill
http://wos.meulie.net/pub/spectrum/games-info/f/FastWell-BehavedPatternFloodFillA.doc (статья содержит подробную статью о структуре экранной области, приведены исходные тексты Basic.) http://www.timexsinclair.org/alvin/tidbits/fillprogs.zip (.TAP-файлы пример программ на Basic, статья ссылается на архив)