tBane Temat założony przez niniejszego użytkownika |
[C++ SFML 3.0] Punkty na obwodzie kształtu składającego się z kwadratów » 2026-07-07 17:44:40 Cześć. Piszę program w C++ SFML 3.0. Potrzebuję uzyskać listę punktów obwodu kształtu. Kształt składa sie z kwadratów opisanych przez std::vector<sf::IntRect> _rects. Pomozecie ? :-)  std::vector < sf::IntRect > rects; std::vector < bool > filled;
int side = 16; int countX = 16; int countY = 16;
for( int y = 0; y < countY; y += 1 ) { for( int x = 0; y < countX; x += 1 ) { rects.push_back( sf::IntRect( sf::Vector2i( countX * side, countY * side ), sf::Vector2i( side, side ) ) ); filled.emplace_back( rand() % 2 == 0 ); } }
std::vector < sf::Vector2i > points = getPoints( rects, filled );
for( int i = 0; i < rects.size(); i += 1 ) { sf::RectangleShape rectShape( sf::Vector2f( rects[ i ].size ) ); rectShape.setFillColor(( filled[ i ] ) ? sf::Color::Green : sf::Color::Black ); rectShape.setPosition( sf::Vector2f( rects[ i ].position ) ); Main::render_window->draw( rectShape ); }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-07-07 18:04:01 A może by tak sortować punkty po y,x i jeżeli dodaje się kwadrat i zawiera już istniejące punkty to te punkty kasować? Ale jak potem uporządkować punkty, żeby można było z ich pomoca utworzyć sf::ConvexShape? |
|
skovv |
» 2026-07-09 20:17:01 kształt masz na myśli ten zielony zestaw kwadracików? Punkty mają być tylko po zewnętrznej stronie(4 punkty "po rogach") czy po każdej linii od skrętu? Ja bym zrobił tak że "sprawdzasz" wszystkie kratki tego obiektu, sprawdzał czy jest np ostatnim bloczkiem z lewej i góry(więc narożnym) więc na tym rogu daje krope. itp |
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-07-13 20:37:39 Problem polega na tym, że mam budynki ze ścianami zdefiniowanymi std::vector < int > _walls; i chciałbym teraz wygenerować dach na podstawie tych wartości. Oczywiście gdy pole jest >-1 to jest ściana. Pokażę na przykładzie obrazków co chcę zrobić. Pierwszy obrazek przedstawia wygenerowany budynek "otwarty", zaś drugi przedstawia budynek z dachem (sf::ConvexShape) i ten dach próbuję wygenerować. Poza tym jak uważacie ma to sens w grze czy to słabe rozwiązanie?   |
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-07-26 16:16:16 Dobra mam :-)  void Building::generateRoofMask() { std::shared_ptr < BuildingPrefab > bp = std::dynamic_pointer_cast < BuildingPrefab >( _prefab.lock() ); if( !bp ) return; int w = bp->_wallsSize.x; int h = bp->_wallsSize.y; std::vector < bool > solid( w * h, false ); for( int y = 0; y < h; y++ ) { for( int x = 0; x < w; x++ ) { if( bp->_walls[ y * w + x ] > - 1 ) solid[ y * w + x ] = true; } } int fw = w + 2; int fh = h + 2; std::vector < bool > outside( fw * fh, false ); std::queue < sf::Vector2i > q; q.push( sf::Vector2i( 0, 0 ) ); outside[ 0 ] = true; const int dx[ 4 ] = { 1, - 1, 0, 0 }; const int dy[ 4 ] = { 0, 0, 1, - 1 }; while( !q.empty() ) { sf::Vector2i p = q.front(); q.pop(); for( int dir = 0; dir < 4; dir++ ) { int nx = p.x + dx[ dir ]; int ny = p.y + dy[ dir ]; if( nx < 0 || ny < 0 || nx >= fw || ny >= fh ) continue; if( outside[ ny * fw + nx ] ) continue; int ox = nx - 1; int oy = ny - 1; bool blocked = false; if( ox >= 0 && oy >= 0 && ox < w && oy < h ) blocked = solid[ oy * w + ox ]; if( blocked ) continue; outside[ ny * fw + nx ] = true; q.push( sf::Vector2i( nx, ny ) ); } } _roof.assign( w * h, false ); for( int y = 0; y < h; y++ ) { for( int x = 0; x < w; x++ ) { bool isOutside = outside[( y + 1 ) * fw +( x + 1 ) ]; if( !isOutside ) _roof[ y * w + x ] = true; } } }
void Building::generateRoofVertexArray( float scale ) { _roofVertexArray.clear(); _roofVertexArray.setPrimitiveType( sf::PrimitiveType::Triangles ); std::shared_ptr < BuildingPrefab > bp = std::dynamic_pointer_cast < BuildingPrefab >( _prefab.lock() ); if( !bp ) return; int w = bp->_wallsSize.x; int h = bp->_wallsSize.y; int offset = 64; for( int y = 0; y < h; y++ ) { for( int x = 0; x < w; x++ ) { if( !_roof[ y * w + x ] ) continue; float px = float( _position.x ) + float( x ) * 32.f * scale; float py = float( _position.y ) + float( y ) * 32.f * scale; sf::Color c( 128, 0, 0 ); _roofVertexArray.append( sf::Vertex( sf::Vector2f( px, py - offset ), c ) ); _roofVertexArray.append( sf::Vertex( sf::Vector2f( px +( 32.f * scale ), py - offset ), c ) ); _roofVertexArray.append( sf::Vertex( sf::Vector2f( px +( 32.f * scale ), py - offset +( 32.f * scale ) ), c ) ); _roofVertexArray.append( sf::Vertex( sf::Vector2f( px, py - offset ), c ) ); _roofVertexArray.append( sf::Vertex( sf::Vector2f( px +( 32.f * scale ), py - offset +( 32.f * scale ) ), c ) ); _roofVertexArray.append( sf::Vertex( sf::Vector2f( px, py - offset +( 32.f * scale ) ), c ) ); } } }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-08-11 17:24:04 I jeszcze algorytm dzielący kształt składający sie z prostokątów na większe prostokąty :-) std::vector < std::vector < bool >> mask;
std::shared_ptr < BuildingPrefab > bp = std::dynamic_pointer_cast < BuildingPrefab >( _prefab.lock() );
if( !bp ) return;
for( auto & row: bp->_floor ) mask.push_back( std::vector < bool >( row.size(), false ) );
for( int y = 0; y < bp->_floor.size(); y += 1 ) { for( int x = 0; x < bp->_floor[ 0 ].size(); x += 1 ) { if( bp->_floor[ y ][ x ] > 0 ) mask[ y ][ x ] = true; } }
for( int y = 0; y < bp->_walls.size(); y += 1 ) { for( int x = 0; x < bp->_walls[ 0 ].size(); x += 1 ) { if( bp->_walls[ y ][ x ] > - 1 ) { mask[ y * 2 ][ x * 2 ] = true; mask[ y * 2 ][ x * 2 + 1 ] = true; mask[ y * 2 + 1 ][ x * 2 ] = true; mask[ y * 2 + 1 ][ x * 2 + 1 ] = true; } } }
for( int y = 0; y < mask.size(); y += 1 ) { for( int x = 0; x < mask[ 0 ].size(); x += 1 ) { std::wcout <<( mask[ y ][ x ] ? L"1": L"0" ); } std::wcout << std::endl; }
std::vector < sf::IntRect > rects;
for( int y = 0; y < mask.size(); y += 1 ) { for( int x = 0; x < mask[ y ].size(); x += 1 ) { if( !mask[ y ][ x ] ) continue; int width = 0; while( x + width < mask[ y ].size() && mask[ y ][ x + width ] ) { width += 1; } int height = 0; while( y + height < mask.size() ) { bool fullRow = true; for( int xx = x; xx < x + width; xx++ ) { if( !mask[ y + height ][ xx ] ) { fullRow = false; break; } } if( !fullRow ) break; height += 1; } rects.push_back( sf::IntRect( sf::Vector2i( x, y ), sf::Vector2i( width, height ) ) ); for( int yy = y; yy < y + height; yy++ ) { for( int xx = x; xx < x + width; xx++ ) { mask[ yy ][ xx ] = false; } } } }
for( auto & rect: rects ) { std::wcout << L"Rect: " << rect.position.x << L"," << rect.position.y << L" - " << rect.size.x << L"x" << rect.size.y << std::endl; } [ cpp ] |
|
| « 1 » |