[SFML 2.X] Narzędzie Fill - czyli wypełnianie danego obszaru kolorem
Ostatnio zmodyfikowano 2025-09-11 23:48
pekfos |
» 2025-09-11 23:35:36  Czy mój drugi kod rozwiązuje ten problem? Tak, nie ma w niej zbyt głębokiej rekurencji, ani rekurencji w ogóle więc jest to lepsza implementacja. To znaczy czy to rozwiazanie jest optymalne ? Nie jest, ale nie ma to znaczenia dla tak małego obrazu. Byłoby znacznie lepiej gdyby animation->getCurrentLayer() było pobrane raz przed pętlą. Co do zasady jeżeli potrzebujesz wynik funkcji w N miejscach i jest to ten sam wynik funkcji, to wywołaj funkcję raz i zapisz wynik w zmiennej, zamiast kopiować wywołania. Czytając kod widać intencję że chodzi o tą samą wartość i nie musisz polegać na tym że kompilator wyeliminuje nadmiarowe wywołania. No i kod jest krótszy. auto & image = animation->getCurrentLayer()->image; if( image.getPixel( tile.x, tile.y ) == colorToEdit ) { image.setPixel( tile.x, tile.y, newColor ); getCurrentLayer() brzmi jak trywialna operacja, ale nie jest trywialnie zaimplementowana więc w wygenerowanym kodzie w release wciąż jest tworzenie i niszczenie wektora wskaźników które tam jest zastosowane. I to wszystko raz dla każdego rozważanego piksela, drugi raz dla każdego zmienionego piksela - idzie na to wielokrotnie więcej pracy niż na cel tego kodu. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-09-11 23:48:08 Ok. Zrozumiałem - ciągle jeszcze mam z tym problem, że zbyt często odnoszę się do wskaźników w ten sposób i marnuję zasoby :-/ Poprawiony kodvoid fill( sf::Color colorToEdit, sf::Color newColor, sf::Vector2i pixelCoords ) { if( colorToEdit == newColor ) return; sf::IntRect imageRect = sf::IntRect( 0, 0, animation->getCurrentLayer()->image.getSize().x, animation->getCurrentLayer()->image.getSize().y ); sf::Image & image = animation->getCurrentLayer()->image; std::vector < sf::Vector2i > pixels; pixels.push_back( pixelCoords ); while( !pixels.empty() ) { sf::Vector2i t = pixels.back(); pixels.pop_back(); if( !imageRect.contains( t ) ) continue; if( image.getPixel( t.x, t.y ) == colorToEdit ) { image.setPixel( t.x, t.y, newColor ); pixels.push_back( sf::Vector2i( t.x - 1, t.y ) ); pixels.push_back( sf::Vector2i( t.x + 1, t.y ) );; pixels.push_back( sf::Vector2i( t.x, t.y - 1 ) );; pixels.push_back( sf::Vector2i( t.x, t.y + 1 ) );; } } }
void fillPixels( sf::Color color ) { sf::Vector2i tile = worldToTile( worldMousePosition, position, zoom, zoom_delta ); sf::Color colorToEdit = animation->getCurrentLayer()->image.getPixel( tile.x, tile.y ); fill( colorToEdit, color, tile ); }
|
|
1 « 2 » |