Кіріспе
Компьютерлік графикада түс немесе текстура қосу алгоритмі. Топан су арнау, сондай-ақ тұқым арнау деп аталатын бұл алгоритм, көп өлшемді массивтегі белгілі бір түйінге байланысты, сәйкес келетін қасиеттері бар аймақты анықтап, өзгертеді. Ол бояу бағдарламаларындағы "шелек" құралы арқылы байланысты, ұқсас түсті аймақтарды басқа түспен толтыруға, сондай-ақ Go және Minesweeper сияқты ойындарда қандай элементтерді тазалау керектігін анықтауға қолданылады. Шекара арнау деп аталатын түрінде де сол алгоритмдер қолданылады, бірақ ол белгілі бір қасиеті жоқ, берілген түйінге байланысты аймақ ретінде анықталады. Топан су арнау толтырылған көпбұрыштарды салуға қолайлы емес екенін ескеріңіз, себебі ол өткір бұрыштардағы кейбір пиксельдерді жіберіп алады. Оның орнына, Жұп-тақ ережесі мен Нөлдік ережесін қараңыз.
Flood fill, also called seed fill, is a flooding algorithm that determines and alters the area connected to a given node in a multi dimensional array with some matching attribute. It is used in the "bucket" fill tool of paint programs to fill connected, similarly colored areas with a different color, and in games such as Go and Minesweeper for determining which pieces are cleared. A variant called boundary fill uses the same algorithms but is defined as the area connected to a given node that does not have a particular attribute. Note that flood filling is not suitable for drawing filled polygons, as it will miss some pixels in more acute corners. Instead, see Even odd rule and Nonzero rule.
Алгоритмнің параметрлері
Дәстүрлі топан су толтыру алгоритмі үш параметрді қабылдайды: бастапқы түйін, мақсатты түс және алмастыру түсі. Алгоритм массивтегі бастапқы түйінге мақсатты түс арқылы байланысқан барлық түйіндерді іздейді және оларды алмастыру түсіне өзгертеді. Шекараны толтыру үшін мақсатты түс орнына шекара түсі беріледі. Алгоритмді жалпылау үшін, келесі сипаттамаларда екі процедура қолжетімді болады. Біреуі – Inside, ол толтырылмаған және түсі бойынша толтырылатын аймақ ішінде болатын нүктелер үшін true мәнін қайтарады, екіншісі – Set, ол пикселді/түйінді толтырады. Set шақырылған кез келген түйін енді Inside-те болмауы керек. Түйіндер бұрыштарынан жанасқанда байланысқан деп есептесек, екі нұсқасы бар: сегіз және төрт бағытты.
Қосымша оңтайландырулар
Қатарға/кезекке қосу алдында әрбір түйіндің пикселдік түсін тексеріп, орнатыңыз, соның арқасында қатардың/кезектің көлемін азайтыңыз. Шығыс/батыс бағыттары үшін цикл қолданыңыз, сол бағытта жоғарыдағы/төмендегі пиксельдерді кезекке қосыңыз (бұл аралықты толтыру алгоритмдеріне ұқсас болады). Ретсіз процессорларға көбірек параллельдеу мүмкіндігін беру үшін, қосымша стектермен/кезектермен кодтың екі немесе одан да көп көшірмесін біріктіріңіз. Ең тиімді нәтиже үшін, әртүрлі келу ретімен бірнеше жіпті пайдаланыңыз (сол арқылы олар бір аймақта тоқтап қалмайды).
Артықшылықтар
Өте қарапайым алгоритм, оны қатесіз жасау оңай.
Кемшіліктер
Жадыны көп пайдаланады, әсіресе стек қолданғанда. Толыққан пикселдердің көп бөлігін барлығы төрт рет тексереді. Үлгімен толтыруға қолайлы емес, себебі пикселдік тест нәтижелерінің өзгеруі қажет. Кезекке қою түрі үшін жадқа жылдам қол жеткізуге мүмкіндік бермейді. Көп пикселдік сөздерді немесе биттік жазықтықтарды оңай оңтайландыруға болмайды.
Артықшылықтар
Пикселдік рекурсивті алгоритмнен 2-ден 8 есеге дейін жылдам. Деректерге қолжеткізу үлгісі кэш және биттік жазықтар үшін қолайлы. Жеке пикселдерді орнатудың орнына көлденең сызық салу мүмкіндігі бар.
Кемшіліктер
Ол бұрын толтырған пикселдерді қайта қарастырады. (Танымал алгоритм үшін пикселдердің көпшілігі 3 рет сканерленеді. Ал соңғы сканерлеу кезінде, тек толтырылған аймақтағы тесіктерге ғана қосымша сканерлеу жасалады.) Үлгімен толтыруға қолайсыз, себебі пикселдерді тексеру нәтижелерінің өзгеруі қажет.
Үлгі толтыруды қолдау құралын қосу
Спан мен пикселге негізделген алгоритмдерге үлгімен толтыру мүмкіндігін қосудың екі кең таралған жолы бар: бірегей түсті қарапайым толтыру ретінде пайдаланып, кейін оны үлгімен алмастыру, немесе қандай пикселдерге барылғанын (2D логикалық массивте немесе аймақтар түрінде) есте сақтап, осы арқылы пикселдердің енді толтырылмайтынын белгілеу. Мұндай пикселдер үшін Inside функциясы false мәнін қайтаруы тиіс.
Графикалық теориялық толтыру
Кейбір теоретиктер проблеманы шешу үшін нақты графтар теориясын қолданды, пиксельдер аралықтарын немесе олардың жиынтығын түйіндер ретінде қарастырып, олардың байланысын зерттеді. Алғаш рет жарияланған графтар теориясының алгоритмі жоғарыдағы аралықты толтыру сияқты жұмыс істеді, бірақ аралықтарды қайталап толтыруды анықтау мүмкіндігі болды. Алайда, ол кейбір толтыруларды аяқтамайтын қателерге ие болды. Кейін түзетілген алгоритм графтар теориясының ұқсас негізінде жарияланды; алайда, ол бағдарламалық интерфейсті қиындата отырып, ықтимал циклдарды уақытша тоқтату үшін суретті өзгертеді. Басқа бір алгоритм, кейін жарияланған, шекараның кескіндегі барлық басқа элементтерден ерекше болуына тәуелді болды, сондықтан көптеген жағдайларда қолдануға қолайлы емес; сонымен қатар, оған есеп жүргізу үшін пикселге қосымша бит қажет.
Артықшылықтар
Үлгілерді толтыруға қолайлы, себебі толтырылған пикселдерді қайта тексермейді. Қарапайым толтырулар үшін бастапқы аралық алгоритмінен екі есе жылдам. Паттернге қолжетімділік кэш және биттік жазылымға ыңғайлы.
Кемшіліктер
Тұрақты түрде, аралық кезектегі әрбір "алдыңғы" бөлікпен салыстырылуы керек, бұл күрделі тапсырыстарды едәуір баяулатады. Граф теориясы мен пиксельдік кеңістік арасындағы жиі ауысу түсінуді қиындатады. Код жеткілікті күрделі, бұл қателердің пайда болу ықтималдығын арттырады.
Жүгіру арқылы толтыру (Тұрақты жады әдісі)
Бұл әдіс төрт аймақты байланыстыру үшін жадыны іс жүзінде пайдаланбайды. Ол суретші рөліндегі алгоритмді көзге елестетіп, өзін бұрышқа тіремей аймақты бояуға тырысады. Бұл лабиринттерді шешудің де бір жолы. Негізгі шекараны құрайтын төрт пикселге қарап, қандай әрекет жасау керектігі анықталады. Суретші бірнеше жағдайдың бірінде болуы мүмкін:
Барлық төрт шекаралық пиксел толтырылған. Шекаралық пиксельдердің үшеуі толтырылған. Шекаралық пиксельдердің екеуі толтырылған. Бір шекаралық пиксел толтырылған. Шекаралық пикселдердің бірі де толтырылмаған. Жол немесе шекараны бағыттап өту қажет болғанда, оң қол ережесі қолданылады. Суретші оң қолын қабырғаға (аймақтың шекарасына) қойып, қолын шешірмей аймақтың шетімен жүреді. 1-ші жағдайда суретші өзі тұрған пикселді бояп (толтырып), алгоритмді тоқтатады. 2-ші жағдайда аумақтан шығатын жол бар. Суретші өзі тұрған пикселді бояп, ашық жолға қарай жылжиды. 3-ші жағдайда екі шекаралық пиксел жолды анықтайды. Егер ағымдағы пикселді боясақ, ол жолдың екінші жағына өтуге кедерілдіруі мүмкін. Біз қайда екенімізді және қай бағытта қозғалып жатқанымызды білу үшін «белгі» қою қажет, сонда ғана дәл сол пикселге қайта оралу мүмкіндігін анықтай аламыз. Егер мұндай «белгі» қойылса, бұрынғы белгі сақталады және оң қол ережесі бойынша келесі пикселге өтіледі. Алғашқы 2 пикселдік шекарада жолдың қайдан басталғанын және суретшінің қозғалыс бағытын есте сақтау үшін белгі қолданылады. Егер белгі қайтадан кездесіп, суретші сол бағытта қозғалса, онда белгі қойылған пикселді бояу және сол бағытта жалғастыру қауіпсіз екенін біледі. Себебі белгінің екінші жағындағы пиксельдерге (біреуі белгісіз жолмен) қол жеткізіп, болашақта бояуға болады. Белгі кейін пайдалану үшін алынып тасталады. Егер суретші белгіге тап болса, бірақ басқа бағытта қозғалса, цикл пайда болған деген сөз. Бұл циклді жою қажет. Белгі алынып, суретші бұрын белгі көрсеткен бағытта сол қол ережесін қолдана отырып (оң қол ережесіне ұқсас, бірақ суретшінің сол қолымен) қозғалады. Бұл үш немесе одан көп ашық шекаралық пиксельдері бар қиылысқан жерге дейін жалғасады. Осы екі пикселдік шекараны тапқаннан кейін, пиксел боялады. Бұл циклді бұзады және алгоритмді жалғастыруға мүмкіндік береді. 4-ші жағдайда 8 көршілес бұрыштың толтырылғандығы тексерілуі керек. Егер біреуі немесе екеуі де толтырылса, онда көптеген жолдардың қиылысы пайда болады және оны толтыру мүмкін емес. Егер екеуі де бос болса, ағымдағы пикселді бояп, оң қол ережесі бойынша қозғалуға болады. Алгоритм жадты уақытқа айырбастайды. Қарапайым пішіндер үшін өте тиімді. Бірақ пішін күрделі және көптеген ерекшеліктері болса, алгоритм барлық пикселдерді бояуға болатынына көз жеткізу үшін аймақтың шеттерін іздеуге көп уақыт жұмсайды. Бұл алгоритм алғаш рет 1981 жылы Vicom Systems, Inc. компаниясы шығарған Vicom Image Processing жүйесінде коммерциялық түрде қолжетімді болды. 1994 жылы жүріп-тұру алгоритмі жарияланды. Классикалық рекурсивті топан су алгоритмі де Vicom жүйесінде қолжетімді болды.
Артықшылықтар
Тұрақты жадты пайдалану.
Кемшіліктер
Кіру үлгісі кэш немесе биттік жазылымға қолайлы емес. Циклдарды жабу алдында көп уақытты оларды аралап шығуға жұмсау мүмкін.
Векторлық іске асырулар
Inkscape-тің 0.46 нұсқасында, кәдімгі растрлік операцияларға ұқсас нәтиже беретін және осылай жұмыс істейтін, бояу құймасы (bucket fill) құралы енгізілді: кенеп суреттеледі, таңдалған аймаққа су тасқынымен толтыру операциясы қолданылады, содан кейін нәтиже векторлық контурға түрлендіріледі. Бұл шекаралық шарттар қағидасын пайдаланады.