tBane Temat założony przez niniejszego użytkownika |
[SFML 2.X] Grid - pozycjonowanie linii oraz wierzchołków » 2025-04-04 23:42:51 Witam. Mam problem z rysowaniem grida. Renderuje go nierówno. Nie wiem co jest tego powodem. Zerknie ktoś na kod? Obecnie tak działa program: Sprajt: float screenWidth = 1280; float screenHeight = 720;
sf::RenderWindow * window = new sf::RenderWindow( sf::VideoMode( int( screenWidth ), int( screenHeight ) ), "THE BAD GRID" );
void drawThickLine( sf::Vector2f start, sf::Vector2f end, float thickness, sf::Color color ) { sf::Vector2f direction = end - start; sf::Vector2f unitDirection = direction / std::sqrt( direction.x * direction.x + direction.y * direction.y ); sf::Vector2f normal( - unitDirection.y, unitDirection.x ); sf::Vector2f offset =( thickness / 2.f ) * normal; sf::Vertex vertices[ 4 ]; vertices[ 0 ].position = start + offset; vertices[ 1 ].position = end + offset; vertices[ 2 ].position = end - offset; vertices[ 3 ].position = start - offset; for( int i = 0; i < 4; ++i ) { vertices[ i ].color = color; } window->draw( vertices, 4, sf::Quads ); }
void render() { float cx = 129; float cy = 213; float scale = 2.0f; sf::Texture texture; texture.loadFromFile( "tree9.png" ); window->clear( sf::Color::Black ); sf::Sprite spr; spr.setTexture( texture ); spr.setOrigin( cx, cy ); spr.setScale( scale, scale ); spr.setPosition( 0, 0 ); window->draw( spr ); sf::FloatRect spr_rect = spr.getGlobalBounds(); sf::Vector2f start, end; for( short x = - spr_rect.width / 2; x <= spr_rect.width / 2; x += 16 ) { start.x = x; start.y = spr_rect.top; end.x = x; end.y = spr_rect.top + spr_rect.height; drawThickLine( start, end, 2, sf::Color( 64, 64, 64 ) ); } for( short y = spr_rect.top; y <= spr_rect.top + spr_rect.height; y += 16 ) { start.x = spr_rect.left; start.y = y; end.x = spr_rect.left + spr_rect.width; end.y = y; drawThickLine( start, end, 2, sf::Color( 64, 64, 64 ) ); window->display(); } }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-04-04 23:56:19 Teraz będzie równo renderować grid, ale nadal nierówno renderuje punkty sf::CircleShape. Później wrzucę kod całego programu. sf::FloatRect bounds = spr.getGlobalBounds();
float gridSize = 16.0f;
for( float x = bounds.left; x <= bounds.left + bounds.width; x += gridSize ) { sf::Vector2f start( x, bounds.top ); sf::Vector2f end( x, bounds.top + bounds.height ); drawThickLine( start, end, 1.0f, sf::Color( 64, 64, 64 ) ); }
for( float y = bounds.top; y <= bounds.top + bounds.height; y += gridSize ) { sf::Vector2f start( bounds.left, y ); sf::Vector2f end( bounds.left + bounds.width, y ); drawThickLine( start, end, 1.0f, sf::Color( 64, 64, 64 ) ); }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-04-05 06:19:05 SterowanieLPM - dodaj punkst PPM - usuń punkt ProblemNierówno rozmieszczone punkty na siatce .. Ale ważne jest to, że wierzchołki vertices powinny być 2x mniejsze niż globalne współrzędne, gdyż później przenoszę te współrzędne do innego programu o skali 1.0f (obecny program ma skalę 2.0f) ScreenshotSprajt DrzewaKodvoid drawThickLine( sf::RenderWindow * window, sf::Vector2f start, sf::Vector2f end, float thickness, sf::Color color ) { sf::Vector2f direction = end - start; sf::Vector2f unitDirection = direction / std::sqrt( direction.x * direction.x + direction.y * direction.y ); sf::Vector2f normal( - unitDirection.y, unitDirection.x ); sf::Vector2f offset =( thickness / 2.f ) * normal; sf::Vertex vertices[ 4 ]; vertices[ 0 ].position = start + offset; vertices[ 1 ].position = end + offset; vertices[ 2 ].position = end - offset; vertices[ 3 ].position = start - offset; for( int i = 0; i < 4; ++i ) { vertices[ i ].color = color; } window->draw( vertices, 4, sf::Quads ); }
void test_grid() { float screenWidth = 1280; float screenHeight = 720; sf::RenderWindow * window = new sf::RenderWindow( sf::VideoMode( screenWidth, screenHeight ), "test grid" ); sf::Texture texture; texture.loadFromFile( "tree9.png" ); float tree_height = 185; float cx = 129; float cy = 213; std::vector < sf::Vector2f > vertices; while( window->isOpen() ) { sf::Vector2i mousePosition = sf::Mouse::getPosition( * window ); sf::Vector2f worldMousePosition = window->mapPixelToCoords( mousePosition ); 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 position; position.x =( int( worldMousePosition.x ) / 16 ) * 16; position.y =( int( worldMousePosition.y ) / 16 ) * 16; bool pointExists = false; for( auto & v: mesh_to_edit_vertices ) { if( abs( v.x - position.x ) < 16.0f && abs( v.y - position.y ) < 16.0f ) pointExists = true; } if( !pointExists ) { sf::Vector2f p = sf::Vector2f( position.x / 2, position.y / 2 ); vertices.push_back( p ); std::cout << "added point " << position.x << ", " << position.y << "\n"; } } else if( event.mouseButton.button == sf::Mouse::Right ) { sf::Vector2f position; position.x =( int( worldMousePosition.x ) / 16 ) * 16; position.y =( int( worldMousePosition.y ) / 16 ) * 16; sf::Vector2f p = sf::Vector2f( position.x / 2, position.y / 2 ); auto v = std::find( vertices.begin(), vertices.end(), p ); if( v != vertices.end() ) { vertices.erase( v ); std::cout << "delete point " << position.x << ", " << position.y << "\n"; } } } } sf::View view; view.setSize( sf::Vector2f( screenWidth, screenHeight ) ); view.setCenter( sf::Vector2f( 0, - tree_height ) ); window->setView( view ); float scale = 2.0f; window->clear( sf::Color::Black ); sf::Sprite spr; spr.setTexture( texture ); spr.setOrigin( cx, cy ); spr.setScale( scale, scale ); spr.setPosition( 0, 0 ); window->draw( spr ); sf::FloatRect bounds = spr.getGlobalBounds(); float gridSize = 16.0f; for( float x = bounds.left; x <= bounds.left + bounds.width; x += gridSize ) { sf::Vector2f start( x, bounds.top ); sf::Vector2f end( x, bounds.top + bounds.height ); drawThickLine( window, start, end, 1.0f, sf::Color( 64, 64, 64 ) ); } for( float y = bounds.top; y <= bounds.top + bounds.height; y += gridSize ) { sf::Vector2f start( bounds.left, y ); sf::Vector2f end( bounds.left + bounds.width, y ); drawThickLine( window, start, end, 1.0f, sf::Color( 64, 64, 64 ) ); } for( auto & v: vertices ) { sf::CircleShape point( 4.0f ); point.setFillColor( sf::Color::Blue ); point.setOrigin( 4.0f, 4.0f ); point.setScale( 1.0f, 1.0f ); point.setPosition( v.x * scale, v.y * scale ); window->draw( point ); } sf::CircleShape cursor( 4.0f ); cursor.setFillColor( sf::Color::Magenta ); cursor.setOrigin( 4.0f, 4.0f ); cursor.setScale( 1.0f, 1.0f ); sf::Vector2f pos( int( worldMousePosition.x ) / 16 * 16, int( worldMousePosition.y ) / 16 * 16 ); cursor.setPosition( pos ); window->display(); } }
|
|
nanoant20 |
» 2025-04-05 12:03:39 może program jest technicznie poprawny, ale warto przyjrzeć się i sprawdzić dokładność obliczeń: jest: for( float x = bounds.left; x <= bounds.left + bounds.width; x += gridSize ) do iteracji używasz typu float co może prowadzić do błędów zaokrągleń. Dla pewności dodałbym epsilon const float epsilon = 0.0001f; for( float x = bounds.left; std::abs( x -( bounds.left + bounds.width ) ) > epsilon; x += gridSize )
if( abs( v.x - position.x ) < 16.0f && abs( v.y - position.y ) < 16.0f )
if( fabs( v.x - position.x ) < 16.0f + epsilon ...
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-04-05 17:10:17 Dla zmiennych cx, cy, tree_height podzielnych przez 16 program działa poprawnie. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-04-05 18:11:10 Ok. Zrobione ale ... już zrozumiałem swój błąd. Nie da się wyrównać siatki tak jak chciałem. void drawThickLine( sf::RenderWindow * window, sf::Vector2f start, sf::Vector2f end, float thickness, sf::Color color ) { sf::Vector2f direction = end - start; sf::Vector2f unitDirection = direction / std::sqrt( direction.x * direction.x + direction.y * direction.y ); sf::Vector2f normal( - unitDirection.y, unitDirection.x ); sf::Vector2f offset =( thickness / 2.f ) * normal; sf::Vertex vertices[ 4 ]; vertices[ 0 ].position = start + offset; vertices[ 1 ].position = end + offset; vertices[ 2 ].position = end - offset; vertices[ 3 ].position = start - offset; for( int i = 0; i < 4; ++i ) { vertices[ i ].color = color; } window->draw( vertices, 4, sf::Quads ); }
void test_grid() { float screenWidth = 1280; float screenHeight = 720; sf::RenderWindow * window = new sf::RenderWindow( sf::VideoMode( screenWidth, screenHeight ), "test grid" ); sf::Texture texture; texture.loadFromFile( "assets/natures/tree9.png" ); float tree_height = 185 / 16 * 16; float cx = 129 / 16 * 16; float cy = 213 / 16 * 16; std::vector < sf::Vector2f > vertices; while( window->isOpen() ) { sf::Vector2i mousePosition = sf::Mouse::getPosition( * window ); sf::Vector2f worldMousePosition = window->mapPixelToCoords( mousePosition ); 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 position; position.x =( int( worldMousePosition.x ) / 16 ) * 16; position.y =( int( worldMousePosition.y ) / 16 ) * 16; bool pointExists = false; for( auto & v: mesh_to_edit_vertices ) { if( abs( v.x - position.x ) < 16 && abs( v.y - position.y ) < 16 ) pointExists = true; } if( !pointExists ) { sf::Vector2f p = sf::Vector2f( position.x / 2, position.y / 2 ); vertices.push_back( p ); std::cout << "added point " << position.x << ", " << position.y << "\n"; } } else if( event.mouseButton.button == sf::Mouse::Right ) { sf::Vector2f position; position.x =( int( worldMousePosition.x ) / 16 ) * 16; position.y =( int( worldMousePosition.y ) / 16 ) * 16; sf::Vector2f p = sf::Vector2f( position.x / 2, position.y / 2 ); auto v = std::find( vertices.begin(), vertices.end(), p ); if( v != vertices.end() ) { vertices.erase( v ); std::cout << "delete point " << position.x << ", " << position.y << "\n"; } } } } sf::View view; view.setSize( sf::Vector2f( screenWidth, screenHeight ) ); view.setCenter( sf::Vector2f( 0, - tree_height ) ); window->setView( view ); float scale = 2.0f; window->clear( sf::Color::Black ); sf::Sprite spr; spr.setTexture( texture ); spr.setOrigin( cx, cy ); spr.setScale( scale, scale ); spr.setPosition( 0, 0 ); window->draw( spr ); sf::FloatRect bounds = spr.getGlobalBounds(); float gridSize = 16.0f; sf::Vector2u tex_size = texture.getSize(); for( float x = bounds.left; x <= bounds.left + bounds.width; x += gridSize ) { sf::Vector2f start( x, bounds.top ); sf::Vector2f end( x, bounds.top + bounds.height ); drawThickLine( window, start, end, 1.0f, sf::Color( 64, 64, 64 ) ); } for( float y = bounds.top; y <= bounds.top + bounds.height; y += gridSize ) { sf::Vector2f start( bounds.left, y ); sf::Vector2f end( bounds.left + bounds.width, y ); drawThickLine( window, start, end, 1.0f, sf::Color( 64, 64, 64 ) ); } for( auto & v: vertices ) { sf::CircleShape point( 4.0f ); point.setFillColor( sf::Color::Blue ); point.setOrigin( 4.0f, 4.0f ); point.setPosition( v.x * scale, v.y * scale ); window->draw( point ); } sf::CircleShape cursor( 4.0f ); cursor.setFillColor( sf::Color::Magenta ); cursor.setOrigin( 4.0f, 4.0f ); cursor.setScale( 1.0f, 1.0f ); sf::Vector2f pos( int( worldMousePosition.x ) / 16 * 16, int( worldMousePosition.y ) / 16 * 16 ); cursor.setPosition( pos ); window->draw( cursor ); window->display(); } }
|
|
« 1 » |