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

Zaznaczanie eliptycznego obszaru przy pomocy lewego przycisku myszy

Ostatnio zmodyfikowano 2024-09-17 22:30
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
Zaznaczanie eliptycznego obszaru przy pomocy lewego przycisku myszy
» 2024-09-17 17:56:26
Witam.
Potrzebuję tak przerobić funkcję, by generowała elipsę w zadanym przedziale.
Elipsa powinna być generowana tak jak podane rozmiary pędzla, albo przynajmniej tak, by elipsa wyglądała jak elipsa a nie "przycięty fragment elipsy", bo tak wychodzi z wzoru
C/C++
// Środek elipsy
float centerX =( start_x + end_x ) / 2.0f;
float centerY =( start_y + end_y ) / 2.0f;

// Półosie elipsy
float a = width / 2.0f;
float b = height / 2.0f;

for( int y = start_y; y < end_y; y++ ) {
   
for( int x = start_x; x < end_x; x++ ) {
       
// Obliczanie pozycji w stosunku do środka
       
float dx =( x - centerX ) / a;
       
float dy =( y - centerY ) / b;
       
       
// Sprawdzenie, czy punkt znajduje się wewnątrz elipsy
       
if( dx * dx + dy * dy <= 1 ) {
           
int xx = x * int( tileSide );
           
int yy = y * int( tileSide );
           

Tu kod funkcji dla prostokąta, która muszę przerobić:
C/C++
if( tool == toolType::Rectangle ) {
   
   
if( selection_state == true ) {
       
       
int start_x = std::min( ceil( startWorldMousePosition.x / tileSide ), ceil( worldMousePosition.x / tileSide ) );
       
int start_y = std::min( ceil( startWorldMousePosition.y / tileSide ), ceil( worldMousePosition.y / tileSide ) );
       
int end_x = std::max( ceil( startWorldMousePosition.x / tileSide ), ceil( worldMousePosition.x / tileSide ) );
       
int end_y = std::max( ceil( startWorldMousePosition.y / tileSide ), ceil( worldMousePosition.y / tileSide ) );
       
       
cout << "start: " << start_x << ", " << start_y << "\n";
       
cout << "end: " << end_x << ", " << end_y << "\n";
       
cout << "\n\n";
       
       
for( int y = start_y; y < end_y; y++ )
           
 for( int x = start_x; x < end_x; x++ ) {
           
int xx = x * int( tileSide );
           
int yy = y * int( tileSide );
           
           
if( prefabToPaint->type == gameObjectType::Terrain ) {
               
TerrainPrefab * ter = new TerrainPrefab( prefabToPaint->name, dynamic_cast < TerrainPrefab * >( prefabToPaint )->ttype );
               
ter->position = sf::Vector2f( xx + 8, yy + 8 );
               
ter->collider->shape->setFillColor( sf::Color( 129, 48, 48, 128 ) );
               
ter->collider->shape->setPosition( sf::Vector2f( xx, yy ) );
               
prefabsToPaint.push_back( ter );
           
}
           
           
if( prefabToPaint->type == gameObjectType::Floor ) {
               
FloorPrefab * flo = new FloorPrefab( prefabToPaint->name, dynamic_cast < FloorPrefab * >( prefabToPaint )->ftype );
               
flo->position = sf::Vector2f( xx + 8, yy + 8 );
               
flo->collider->shape->setFillColor( sf::Color( 128, 48, 48, 128 ) );
               
flo->collider->shape->setPosition( sf::Vector2f( xx, yy ) );
               
prefabsToPaint.push_back( flo );
           
}
        }
       
    }
}

std::vector<std::vector<std::vector<bool>>> brushes = {

    // 0 - 1x1
    {
        {1}
    },

    // 1 - 3x3
    {
        {0, 1, 0},
        {1, 1, 1},
        {0, 1, 0}
    },

    // 2 - 5x5
    {
        {0, 1, 1, 1, 0},
        {1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1},
        {0, 1, 1, 1, 0}
    },
   
    // 3 - 7x7
    {
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 1, 1, 1, 1, 0},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {0, 1, 1, 1, 1, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    },

    // 4 - 9x9
    {
        {0, 0, 0, 1, 1, 1, 0, 0, 0},
        {0, 0, 1, 1, 1, 1, 1, 0, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 0},
        {1, 1, 1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1, 1, 1},
        {0, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 0, 1, 1, 1, 1, 1, 0, 0},
        {0, 0, 0, 1, 1, 1, 0, 0, 0}
    },

    // 5 - 11x11
    {
        {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
        {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
        {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
        {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
        {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},

    }
};
P-181601
tBane
Temat założony przez niniejszego użytkownika
» 2024-09-17 19:31:48
Na chwilę obecną mam taki kod. Elipsa jest generowana ale wygląda to dziwnie.

C/C++
void testElipseSelectingFunction() {
   
// local mouse position
   
sf::Vector2i mousePosition;
   
sf::Vector2i startMousePosition;
   
   
// global mouse position
   
sf::Vector2f worldMousePosition;
   
sf::Vector2f startWorldMousePosition;
   
   
float tileSide = 16.0f;
   
// rects (parts) use to draw ellipse
   
std::vector < sf::RectangleShape > rects;
   
   
bool selection_state = false;
   
   
sf::RenderWindow * window = new sf::RenderWindow( sf::VideoMode( 1280, 720 ), "RECT" );
   
   
while( window->isOpen() ) {
       
       
mousePosition = sf::Mouse::getPosition( * window ); // Pobierz aktualną pozycję myszy względem bieżącego okna
       
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 ) {
                   
                   
startMousePosition = sf::Mouse::getPosition( * window );
                   
startWorldMousePosition = window->mapPixelToCoords( startMousePosition );
                   
selection_state = true;
               
}
               
            }
           
           
if( event.type == sf::Event::MouseButtonReleased ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
selection_state = false;
                   
// action
               
}
            }
        }
       
       
if( selection_state == true ) {
           
           
rects.clear();
           
           
int start_x = std::min( ceil( startWorldMousePosition.x / tileSide ), ceil( worldMousePosition.x / tileSide ) );
           
int start_y = std::min( ceil( startWorldMousePosition.y / tileSide ), ceil( worldMousePosition.y / tileSide ) );
           
int end_x = std::max( ceil( startWorldMousePosition.x / tileSide ), ceil( worldMousePosition.x / tileSide ) );
           
int end_y = std::max( ceil( startWorldMousePosition.y / tileSide ), ceil( worldMousePosition.y / tileSide ) );
           
           
cout << "selected area: \n";
           
cout << "start: " << start_x << ", " << start_y << "\n";
           
cout << "end: " << end_x << ", " << end_y << "\n";
           
cout << "\n\n";
           
           
int width = end_x - start_x;
           
int height = end_y - start_y;
           
           
// Środek pędzla
           
float centerX =( start_x + end_x ) / 2.0f;
           
float centerY =( start_y + end_y ) / 2.0f;
           
           
// Półosie elipsy
           
float a = width / 2.0f;
           
float b = height / 2.0f;
           
           
// Generowanie elipsy w oparciu o pędzel
           
for( int y = start_y; y < end_y; ++y ) {
               
for( int x = start_x; x < end_x; ++x ) {
                   
// Obliczanie pozycji w stosunku do środka
                   
float dx =( x - centerX ) / a;
                   
float dy =( y - centerY ) / b;
                   
                   
// Sprawdź, czy pędzel na tej pozycji ma wartość 1
                   
if( dx * dx + dy * dy <= 1 ) {
                       
int xx = x * int( tileSide );
                       
int yy = y * int( tileSide );
                       
                       
sf::RectangleShape rect = sf::RectangleShape( sf::Vector2f( tileSide, tileSide ) );
                       
rect.setFillColor( sf::Color::Red );
                       
rect.setPosition( xx, yy );
                       
rects.push_back( rect );
                   
}
                }
            }
           
        }
       
       
window->clear();
       
if( selection_state == true ) {
           
for( auto & rect: rects ) {
               
window->draw( rect );
           
}
        }
       
window->display();
   
}
   
   
delete window;
}
P-181603
pekfos
» 2024-09-17 21:24:00
A jak to ma wyglądać?
P-181604
tBane
Temat założony przez niniejszego użytkownika
» 2024-09-17 21:31:53
Mniej więcej tak jak w Miscrosoft Paint. Bez dziwnych krawędzi takich jak na obrazku.

Krawędzie elips w MS Paint
Krawędzie elips w MS Paint
Krawędzie elips w moim programie
Krawędzie elips w moim programie
P-181605
pekfos
» 2024-09-17 22:16:09
Spróbuj tak
C/C++
// Sprawdź, czy pędzel na tej pozycji ma wartość 1
if( dx * dx + dy * dy <= 0.995 ) {
P-181606
tBane
Temat założony przez niniejszego użytkownika
» 2024-09-17 22:30:34
Nie sądziłem, że to będzie tak proste :D Dzięki za pomoc :-)
P-181607
« 1 »
  Strona 1 z 1