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

[SFML 3.0.2] Implementacja lasso jak w Paint - Assertion failed: right != 0 && "Vector2::operator/ cannot divide by 0"

Ostatnio zmodyfikowano wczoraj o godz. 18:32
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2026-01-26 16:11:56
Jeszcze dorzucam optymalizację dla punktów - gdy są współliniowe to usuwa punkt środkowy w celu ograniczenia liczby punktów. Algorytm nieznacznie przyśpiesza :-) Ale i tak działa mega powoli. Zastanawiam się czy nie lepiej punkty zastąpić liniami jak myślicie? Jakoś się da to przyśpieszyć, bo w GIMPIE nie działa tak powoli Lasso ...

C/C++
void Lasso::addPoint( sf::Vector2i point ) {
   
point -= _outlineOffset;
   
shiftOriginIfNeeded( point );
   
   
if( _points.empty() ) {
       
_points.push_back( point );
       
return;
   
}
   
   
if( _points.back() == point ) return;
   
   
// Jeśli są co najmniej dwa punkty, sprawdzamy współliniowość
   
while( _points.size() >= 2 ) {
       
sf::Vector2i & a = _points[ _points.size() - 2 ];
       
sf::Vector2i & b = _points[ _points.size() - 1 ];
       
sf::Vector2i & c = point;
       
       
// cross product – jeśli zero, punkty są współliniowe
       
int det =( b.x - a.x ) *( c.y - a.y ) -( b.y - a.y ) *( c.x - a.x );
       
if( det == 0 ) {
           
_points.pop_back();
       
}
       
else {
           
break;
       
}
    }
   
   
_points.push_back( point );
}
P-183876
DejaVu
» 2026-01-26 16:37:15
Zbuduj w release a jak to będzie niewystarczające to wtedy można dopiero myśleć nad lepszym algorytmem. Możesz np robić przeliczenia co 100ms albo gdy realnie kursor znajdzie się nad innym/nowym pixelem jeżeli liczone jest to w każdej klatce.
P-183877
DejaVu
» 2026-01-26 16:40:17
Poza tym temat optymalizacji to osobny wątek moim zdaniem.
P-183878
tBane
Temat założony przez niniejszego użytkownika
» 2026-01-26 17:21:46
Mhm, racja pomyliłem temat - myślałem, że to mój zbiorczy do Lasso :-/
Budowałem w Release i lagowało strasznie przy zaznaczeniu w przybliżeniu 150x150. Kopiowałem obraz co zmianę zaznaczenia i dlatego lagowało oraz generowałem maskę co klatkę. Razem działało to powoli i było trudne do namierzenia.
Done :-)
P-183879
tBane
Temat założony przez niniejszego użytkownika
» 2026-01-26 18:16:36
Zauważyłem dziwną rzecz a mianowicie, gdy zaznacza się obszar w sposób okrężny to gdy powielimy zaznaczenie okrężne parzystą liczbę razy to nie zaznacza obrazu wewnętrz.
P-183880
tBane
Temat założony przez niniejszego użytkownika
» 2026-01-26 18:32:49
Naprawione. Przy okazji zauważyłem, że moja optymalizacja dla punktów nie sprawdza się przy dokładnym zaznaczaniu pojedynczych pikseli w małych obrazach więc przywróciłem ją do stanu poprzedniego.

C/C++
void Lasso::addPoint( sf::Vector2i point ) {
   
point -= _outlineOffset;
   
shiftOriginIfNeeded( point );
   
   
if( _points.empty() ) {
       
_points.push_back( point );
       
return;
   
}
   
   
if( _points.back() == point ) return;
   
   
_points.push_back( point );
}

bool Lasso::pointOnSegment( sf::Vector2i p, sf::Vector2i a, sf::Vector2i b )
{
   
int cross = 1LL *( b.x - a.x ) *( p.y - a.y ) - 1LL *( b.y - a.y ) *( p.x - a.x );
   
   
if( cross != 0 )
       
 return false;
   
   
int minx = std::min( a.x, b.x );
   
int maxx = std::max( a.x, b.x );
   
int miny = std::min( a.y, b.y );
   
int maxy = std::max( a.y, b.y );
   
   
return( p.x >= minx && p.x <= maxx && p.y >= miny && p.y <= maxy );
}

bool Lasso::isPointInPolygon( sf::Vector2i p, std::vector < sf::Vector2i > & poly )
{
   
if( poly.size() < 3 ) return false;
   
   
int j = poly.size() - 1;
   
float epsilon = 1e-6f;
   
   
for( int i = 0; i < poly.size(); ++i ) {
       
// Sprawdzamy, czy punkt leży dokładnie na krawędzi
       
if( pointOnSegment( p, poly[ i ], poly[( i + 1 ) % poly.size() ] ) ) {
           
return true;
       
}
       
       
// Ray casting z poprawką na precyzję float
       
if((( poly[ i ].y > p.y ) !=( poly[ j ].y > p.y ) ) &&
        (
p.x <( poly[ j ].x - poly[ i ].x ) *( p.y - poly[ i ].y ) /( poly[ j ].y - poly[ i ].y ) + poly[ i ].x + epsilon ) ) {
           
return true;
       
}
       
j = i;
   
}
   
return false;
}
P-183881
1 2 3 4 5 « 6 »
Poprzednia strona Strona 6 z 6