Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML 2.X] Narzędzie Fill - czyli wypełnianie danego obszaru kolorem

Ostatnio zmodyfikowano 2025-09-11 23:48
Autor Wiadomość
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.
C/C++
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.
P-182998
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 kod
C/C++
void 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 );
}
P-182999
1 « 2 »
Poprzednia strona Strona 2 z 2