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

[SFML 3.0.2] Assertion failed: right != 0 && "Vector2::operator/ cannot divide by 0"

Ostatnio zmodyfikowano dzisiaj: 10h » 15 min
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2025-10-13 19:54:19
Tylko rysować outline, po to żeby było widać jaki kształt się zaznacza.

P-183149
DejaVu
» 2025-10-13 23:12:02
Model lokalny LLM ogarnął to w drugim podejściu, a ChatGPT jest teoretycznie znacznie mocniejszy niż mały model lokalny:
C/C++
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>

// Function to check if a point is inside a polygon using ray casting algorithm
bool isPointInPolygon( const sf::Vector2f & point, const std::vector < sf::Vector2f > & polygon ) {
   
bool inside = false;
   
int j = polygon.size() - 1;
   
for( int i = 0; i < polygon.size(); ++i ) {
       
if((( polygon[ i ].y > point.y ) !=( polygon[ j ].y > point.y ) ) &&
        (
point.x <( polygon[ j ].x - polygon[ i ].x ) *( point.y - polygon[ i ].y ) /( polygon[ j ].y - polygon[ i ].y ) + polygon[ i ].x ) ) {
           
inside = !inside;
       
}
       
j = i;
   
}
   
return inside;
}

// Function to extract a region from a texture based on a polygon (lasso selection)
sf::Image extractRegion( const sf::Texture & texture, const std::vector < sf::Vector2f > & polygon ) {
   
sf::Vector2u size = texture.getSize();
   
sf::Image result;
   
result.create( size.x, size.y, sf::Color::Transparent );
   
   
// Get texture pixels using copyToImage() and then getPixels()
   
sf::Image textureImage = texture.copyToImage();
   
const sf::Uint8 * pixels = textureImage.getPixelsPtr();
   
   
// Iterate over all pixels in the texture
   
for( unsigned int y = 0; y < size.y; ++y ) {
       
for( unsigned int x = 0; x < size.x; ++x ) {
           
sf::Vector2f pixelPos( x, y );
           
if( isPointInPolygon( pixelPos, polygon ) ) {
               
// Calculate pixel index in the raw pixel array
               
size_t index =( y * size.x + x ) * 4; // RGBA
               
sf::Color color( pixels[ index ], pixels[ index + 1 ], pixels[ index + 2 ], pixels[ index + 3 ] );
               
result.setPixel( x, y, color );
           
}
        }
    }
   
   
return result;
}

int main() {
   
// Create main window
   
sf::RenderWindow window( sf::VideoMode( 1200, 600 ), "SFML Lasso Selection" );
   
   
// Load image from file
   
sf::Texture texture;
   
if( !texture.loadFromFile( "D:/image.jpg" ) ) {
       
std::cerr << "Error: Could not load image.jpg" << std::endl;
       
return - 1;
   
}
   
   
sf::Sprite sprite;
   
sprite.setTexture( texture );
   
sprite.setPosition( 10, 10 );
   
   
// Create a second image to display the selected region
   
sf::Image selectedImage;
   
sf::Texture selectedTexture;
   
sf::Sprite selectedSprite;
   
selectedSprite.setPosition( 650, 10 );
   
   
// Vector to store lasso points
   
std::vector < sf::Vector2f > lassoPoints;
   
   
// Variables for mouse interaction
   
bool isDrawing = false;
   
   
// Main loop
   
while( window.isOpen() ) {
       
sf::Event event;
       
while( window.pollEvent( event ) ) {
           
if( event.type == sf::Event::Closed ) {
               
window.close();
           
}
           
           
if( event.type == sf::Event::MouseButtonPressed ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
lassoPoints.clear();
                   
lassoPoints.push_back( sf::Vector2f( event.mouseButton.x, event.mouseButton.y ) );
                   
isDrawing = true;
               
}
            }
           
           
if( event.type == sf::Event::MouseButtonReleased ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
isDrawing = false;
                   
if( lassoPoints.size() > 2 ) {
                       
// Extract selected region
                       
selectedImage = extractRegion( texture, lassoPoints );
                       
selectedTexture.loadFromImage( selectedImage );
                       
selectedSprite.setTexture( selectedTexture );
                   
}
                }
            }
           
           
if( event.type == sf::Event::MouseMoved && isDrawing ) {
               
lassoPoints.push_back( sf::Vector2f( event.mouseMove.x, event.mouseMove.y ) );
           
}
        }
       
       
// Clear window
       
window.clear();
       
       
// Draw original image
       
window.draw( sprite );
       
       
// Draw lasso if drawing
       
if( isDrawing && lassoPoints.size() > 1 ) {
           
sf::ConvexShape lassoLine;
           
lassoLine.setPointCount( lassoPoints.size() );
           
for( size_t i = 0; i < lassoPoints.size(); ++i ) {
               
lassoLine.setPoint( i, lassoPoints[ i ] );
           
}
           
lassoLine.setFillColor( sf::Color( 0, 0, 0, 0 ) );
           
lassoLine.setOutlineColor( sf::Color::Yellow );
           
lassoLine.setOutlineThickness( 2 );
           
window.draw( lassoLine );
       
}
       
       
// Draw selected region if exists
       
if( selectedImage.getSize().x > 0 && selectedImage.getSize().y > 0 ) {
           
window.draw( selectedSprite );
       
}
       
       
// Display window
       
window.display();
   
}
   
   
return 0;
}
P-183151
DejaVu
» 2025-10-13 23:18:27
Tu masz kolejną iterację, aby było pokazane 'jakie zaznaczenie' zrobiono:
C/C++
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>

// Function to check if a point is inside a polygon using ray casting algorithm
bool isPointInPolygon( const sf::Vector2f & point, const std::vector < sf::Vector2f > & polygon ) {
   
bool inside = false;
   
int j = polygon.size() - 1;
   
for( int i = 0; i < polygon.size(); ++i ) {
       
if((( polygon[ i ].y > point.y ) !=( polygon[ j ].y > point.y ) ) &&
        (
point.x <( polygon[ j ].x - polygon[ i ].x ) *( point.y - polygon[ i ].y ) /( polygon[ j ].y - polygon[ i ].y ) + polygon[ i ].x ) ) {
           
inside = !inside;
       
}
       
j = i;
   
}
   
return inside;
}

// Function to extract a region from a texture based on a polygon (lasso selection)
sf::Image extractRegion( const sf::Texture & texture, const std::vector < sf::Vector2f > & polygon ) {
   
sf::Vector2u size = texture.getSize();
   
sf::Image result;
   
result.create( size.x, size.y, sf::Color::Transparent );
   
   
// Get texture pixels using copyToImage() and then getPixelsPtr()
   
sf::Image textureImage = texture.copyToImage();
   
const sf::Uint8 * pixels = textureImage.getPixelsPtr();
   
   
// Iterate over all pixels in the texture
   
for( unsigned int y = 0; y < size.y; ++y ) {
       
for( unsigned int x = 0; x < size.x; ++x ) {
           
sf::Vector2f pixelPos( x, y );
           
if( isPointInPolygon( pixelPos, polygon ) ) {
               
// Calculate pixel index in the raw pixel array
               
size_t index =( y * size.x + x ) * 4; // RGBA
               
sf::Color color( pixels[ index ], pixels[ index + 1 ], pixels[ index + 2 ], pixels[ index + 3 ] );
               
result.setPixel( x, y, color );
           
}
        }
    }
   
   
return result;
}

int main() {
   
// Create main window
   
sf::RenderWindow window( sf::VideoMode( 1200, 600 ), "SFML Lasso Selection" );
   
   
// Load image from file
   
sf::Texture texture;
   
if( !texture.loadFromFile( "D:/image.jpg" ) ) {
       
std::cerr << "Error: Could not load image.jpg" << std::endl;
       
return - 1;
   
}
   
   
sf::Sprite sprite;
   
sprite.setTexture( texture );
   
sprite.setPosition( 10, 10 );
   
   
// Create a second image to display the selected region
   
sf::Image selectedImage;
   
sf::Texture selectedTexture;
   
sf::Sprite selectedSprite;
   
selectedSprite.setPosition( 650, 10 );
   
   
// Vectors to store lasso points
   
std::vector < sf::Vector2f > lassoPoints;
   
std::vector < sf::Vector2f > lastLassoPoints; // Store the last completed lasso for display
   
bool isDrawing = false;
   
bool selectionDone = false;
   
   
// Main loop
   
while( window.isOpen() ) {
       
sf::Event event;
       
while( window.pollEvent( event ) ) {
           
if( event.type == sf::Event::Closed ) {
               
window.close();
           
}
           
           
if( event.type == sf::Event::MouseButtonPressed ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
lassoPoints.clear();
                   
lassoPoints.push_back( sf::Vector2f( event.mouseButton.x, event.mouseButton.y ) );
                   
isDrawing = true;
                   
selectionDone = false;
               
}
            }
           
           
if( event.type == sf::Event::MouseButtonReleased ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
isDrawing = false;
                   
if( lassoPoints.size() > 2 ) {
                       
// Save the lasso for display after release
                       
lastLassoPoints = lassoPoints;
                       
// Extract selected region
                       
selectedImage = extractRegion( texture, lassoPoints );
                       
selectedTexture.loadFromImage( selectedImage );
                       
selectedSprite.setTexture( selectedTexture );
                       
selectionDone = true;
                   
}
                }
            }
           
           
if( event.type == sf::Event::MouseMoved && isDrawing ) {
               
lassoPoints.push_back( sf::Vector2f( event.mouseMove.x, event.mouseMove.y ) );
           
}
        }
       
       
// Clear window
       
window.clear();
       
       
// Draw original image
       
window.draw( sprite );
       
       
// Draw lasso if drawing
       
if( isDrawing && lassoPoints.size() > 1 ) {
           
sf::ConvexShape lassoLine;
           
lassoLine.setPointCount( lassoPoints.size() );
           
for( size_t i = 0; i < lassoPoints.size(); ++i ) {
               
lassoLine.setPoint( i, lassoPoints[ i ] );
           
}
           
lassoLine.setFillColor( sf::Color( 0, 0, 0, 0 ) );
           
lassoLine.setOutlineColor( sf::Color::Yellow );
           
lassoLine.setOutlineThickness( 2 );
           
window.draw( lassoLine );
       
}
       
       
// Draw the last completed lasso (readonly) if exists
       
if( !lastLassoPoints.empty() ) {
           
sf::ConvexShape lastLasso;
           
lastLasso.setPointCount( lastLassoPoints.size() );
           
for( size_t i = 0; i < lastLassoPoints.size(); ++i ) {
               
lastLasso.setPoint( i, lastLassoPoints[ i ] );
           
}
           
lastLasso.setFillColor( sf::Color( 0, 0, 0, 50 ) ); // Semi-transparent fill
           
lastLasso.setOutlineColor( sf::Color::Green );
           
lastLasso.setOutlineThickness( 3 );
           
window.draw( lastLasso );
       
}
       
       
// Draw selected region if exists and selection is complete
       
if( selectionDone && selectedImage.getSize().x > 0 && selectedImage.getSize().y > 0 ) {
           
window.draw( selectedSprite );
       
}
       
       
// Display window
       
window.display();
   
}
   
   
return 0;
}

Innymi słowy: musisz nauczyć się dzielić problem na mniejsze dla LLM-ów i sklejać sobie to w coś większego.
P-183152
tBane
Temat założony przez niniejszego użytkownika
» 2025-10-13 23:31:17
Wrzuciłeś kod pod stary SFML. W nowym SFML 3.0.2 nie ma sf::Image::create ani sf::Uint8 oraz nie można tworzyć domyślnych (pustych) sprajtów ... Poza tym potrzebuje bardzo dokładnego zaznaczania dla obrazów o rozdzielczości 16x16, 32x32, 64x64, 128x128, a nie jestem pewien czy ten kod sprawdzi się w tym przypadku. Jutro spróbuję to ogarnąć, bo dziś już nie siedzę na komputerze.
P-183153
DejaVu
» 2025-10-13 23:37:32
Kod jest w SFML 2.x, ponieważ nie mam SFML 3.x, a tak mogłem przetestować. Niemniej jednak problemem jest algorytmika, a nie biblioteka renderująca.
P-183154
DejaVu
» 2025-10-14 00:22:12
C/C++
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>

// Funkcja do sprawdzania, czy punkt znajduje się w wielokącie
// Używamy algorytmu "ray casting" na poziomie pikseli
// Działa idealnie dla małych obrazów (16x16, 32x32, 64x64, 128x128)
bool isPointInPolygon( const sf::Vector2f & point, const std::vector < sf::Vector2f > & polygon ) {
   
if( polygon.size() < 3 ) return false;
   
   
bool inside = false;
   
int j = polygon.size() - 1;
   
const float epsilon = 1e-6f;
   
   
for( int i = 0; i < polygon.size(); ++i ) {
       
// Sprawdzamy, czy punkt leży dokładnie na krawędzi
       
if( std::abs( polygon[ i ].y - point.y ) < epsilon &&
       
std::abs( polygon[ i ].x - point.x ) < epsilon ) {
           
return true;
       
}
       
       
// Ray casting z poprawką na precyzję float
       
if((( polygon[ i ].y > point.y ) !=( polygon[ j ].y > point.y ) ) &&
        (
point.x <( polygon[ j ].x - polygon[ i ].x ) *( point.y - polygon[ i ].y ) /( polygon[ j ].y - polygon[ i ].y ) + polygon[ i ].x + epsilon ) ) {
           
inside = !inside;
       
}
       
j = i;
   
}
   
return inside;
}
// Funkcja do kopiowania obszaru zaznaczonego lassiem
// Zamiast testować każdy piksel, używamy prostego renderowania linii między punktami
sf::Image extractRegion( const sf::Texture & texture, const std::vector < sf::Vector2f > & polygon ) {
   
sf::Vector2u size = texture.getSize();
   
sf::Image result;
   
result.create( size.x, size.y, sf::Color::Transparent );
   
   
// Pobieramy piksele z tekstu
   
sf::Image textureImage = texture.copyToImage();
   
const sf::Uint8 * pixels = textureImage.getPixelsPtr();
   
   
// Dla każdego piksela sprawdzamy, czy jego środek jest w zaznaczeniu
   
for( unsigned int y = 0; y < size.y; ++y ) {
       
for( unsigned int x = 0; x < size.x; ++x ) {
           
sf::Vector2f pixelCenter( x + 0.5f, y + 0.5f );
           
if( isPointInPolygon( pixelCenter, polygon ) ) {
               
size_t index =( y * size.x + x ) * 4;
               
sf::Color color( pixels[ index ], pixels[ index + 1 ], pixels[ index + 2 ], pixels[ index + 3 ] );
               
result.setPixel( x, y, color );
           
}
        }
    }
   
return result;
}

// Funkcja do rysowania lasso jako linii między punktami
// Parametry:
// - points: wektor punktów tworzących lasso
// - closed: czy lasso ma być zamknięty (połączenie pierwszego i ostatniego punktu)
// - color: kolor linii
// - window: okno do którego rysujemy
void drawLasso( const std::vector < sf::Vector2f > & points, bool closed, const sf::Color & color, sf::RenderWindow & window, float zoomFactor ) {
   
if( points.size() < 2 ) return;
   
   
sf::VertexArray lines( sf::LinesStrip, points.size() +( closed ? 1
       
: 0 ) );
   
   
for( size_t i = 0; i < points.size(); ++i ) {
       
sf::Vector2f scaledPoint = points[ i ] * zoomFactor;
       
lines[ i ].position = scaledPoint;
       
lines[ i ].color = color;
   
}
   
   
// Jeśli lasso ma być zamknięty, dodajemy pierwszy punkt na końcu
   
if( closed && points.size() > 2 ) {
       
lines[ points.size() ].position = points[ 0 ] * zoomFactor;
       
lines[ points.size() ].color = color;
   
}
   
   
window.draw( lines );
}

int main() {
   
sf::RenderWindow window( sf::VideoMode( 1800, 1200 ), "SFML Lasso Selection - Pixel-Perfect for Small Images" );
   
   
sf::Texture texture;
   
if( !texture.loadFromFile( "D:/image.jpg" ) ) {
       
std::cerr << "Error: Could not load image.jpg" << std::endl;
       
return - 1;
   
}
   
   
sf::Sprite sprite;
   
sprite.setTexture( texture );
   
sprite.setPosition( 0, 0 );
   
   
sf::Image selectedImage;
   
sf::Texture selectedTexture;
   
sf::Sprite selectedSprite;
   
selectedSprite.setPosition( 650, 10 );
   
   
const float zoomFactor = 4.0f;
   
sprite.setScale( zoomFactor, zoomFactor );
   
selectedSprite.setScale( zoomFactor, zoomFactor );
   
   
std::vector < sf::Vector2f > lassoPoints;
   
std::vector < sf::Vector2f > lastLassoPoints;
   
bool isDrawing = false;
   
bool selectionDone = false;
   
   
while( window.isOpen() ) {
       
sf::Event event;
       
while( window.pollEvent( event ) ) {
           
if( event.type == sf::Event::Closed ) {
               
window.close();
           
}
           
           
if( event.type == sf::Event::MouseButtonPressed ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
sf::Vector2f mousePos( event.mouseButton.x, event.mouseButton.y );
                   
mousePos /= zoomFactor;
                   
lassoPoints.clear();
                   
lassoPoints.push_back( mousePos );
                   
isDrawing = true;
                   
selectionDone = false;
               
}
            }
           
           
if( event.type == sf::Event::MouseButtonReleased ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
isDrawing = false;
                   
if( lassoPoints.size() > 2 ) {
                       
lastLassoPoints = lassoPoints;
                       
selectedImage = extractRegion( texture, lassoPoints );
                       
selectedTexture.loadFromImage( selectedImage );
                       
selectedSprite.setTexture( selectedTexture );
                       
selectionDone = true;
                   
}
                }
            }
           
           
if( event.type == sf::Event::MouseMoved && isDrawing ) {
               
sf::Vector2f mousePos( event.mouseMove.x, event.mouseMove.y );
               
mousePos /= zoomFactor;
               
lassoPoints.push_back( mousePos );
           
}
        }
       
       
window.clear();
       
       
window.draw( sprite );
       
       
// Rysowanie lassu jako linii między punktami
       
if( isDrawing && lassoPoints.size() > 1 ) {
           
drawLasso( lassoPoints, false, sf::Color::Yellow, window, zoomFactor );
       
}
       
       
// Rysowanie ostatniego zaznaczenia jako linii (readonly)
       
if( !lastLassoPoints.empty() ) {
           
drawLasso( lastLassoPoints, true, sf::Color::Green, window, zoomFactor );
       
}
       
       
if( selectionDone && selectedImage.getSize().x > 0 && selectedImage.getSize().y > 0 ) {
           
window.draw( selectedSprite );
       
}
       
       
window.display();
   
}
   
   
return 0;
}
Tu masz lepiej działającą wersję - z zoomem o jakim piszesz i poprawionym offsetem kopiowania.
P-183155
1 2 3 4 « 5 »
Poprzednia strona Strona 5 z 5