2015-04-04 2 views
1

У меня есть объект прямоугольника (sf::IntRect) с атрибутами: слева, сверху, ширине и высоте на 2D-плоскости. Я хочу повернуть его на 90 градусов (это 90, 180 или 270), вокруг точки (0,0). Таким образом, я пишу функцию, как это:Поверните прямоугольник с выровненной осью на 90 градусов

void rotateRect(sf::IntRect& rect, int rot) 
{ 
    //code I need 
} 

вращение либо 0 (0), 1 (90), 2 (180) или 3 (270).

Как я могу достичь этого как можно проще.

+0

Вы пробовали что-нибудь? –

+0

Я не знаком с SFML. Вероятно, он имеет функции для вычисления матриц преобразования для указанных выше вращений. Если нет, они очень просты. См. Http://en.wikipedia.org/wiki/Rotation_matrix. –

+0

Посмотрите на 'sf :: Transform'. Но вы уверены, что хотите использовать ** Int ** Rect? – Hiura

ответ

0

Вот базовое решение с использованием sf::Tranform на sf::FloatRect:

constexpr auto rotationAngle(int rot) { return rot * 90.f; } 

void rotateRect(sf::IntRect& rect, int rot) 
{ 
    auto deg = rotationAngle(rot); 
    auto transform = sf::Transform(); 
    transform.rotate(deg); 

    // Would be better if rect was a FloatRect... 
    auto rectf = sf::FloatRect(rect); 
    rectf = transform.transformRect(rectf); 
    rect = static_cast<sf::IntRect>(rectf); 
} 

Однако, лично я бы немного изменить подпись вашей функции для использования с плавающей точкой прямоугольников и более компактное обозначения:

sf::FloatRect rotateRect(sf::FloatRect const& rect, int rot) 
{ 
    return sf::Transform().rotate(rotationAngle(rot)).transformRect(rect); 
} 

И ниже полный пример, показывающий, как он себя ведет.

#include <SFML/Graphics.hpp> 

constexpr auto rotationAngle(int rot) { return rot * 90.f; } 

sf::FloatRect rotateRect(sf::FloatRect const& rect, int rot) 
{ 
    return sf::Transform().rotate(rotationAngle(rot)).transformRect(rect); 
} 

void updateShape(sf::RectangleShape& shape, sf::FloatRect const& rect) 
{ 
    shape.setPosition(rect.left, rect.top); 
    shape.setSize({ static_cast<float>(rect.width), static_cast<float>(rect.height) }); 
} 

int main(int, char const**) 
{ 
    sf::RenderWindow window(sf::VideoMode(500, 500), "rotate"); 

    auto rect = sf::FloatRect(0, 0, 100, 50); 
    auto shape = sf::RectangleShape(); 
    shape.setFillColor(sf::Color::Red); 
    updateShape(shape, rect); 

    auto view = window.getView(); 
    view.move({ -250, -250 }); 
    window.setView(view); 

    while (window.isOpen()) 
    { 
     sf::Event event; 
     while (window.pollEvent(event)) 
     { 
      if (event.type == sf::Event::Closed) 
       window.close(); 

      if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::R) 
      { 
       rect = rotateRect(rect, 1); 
       updateShape(shape, rect); 
      } 

      if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::N) 
      { 
       rect = sf::FloatRect(50, 50, 100, 50); 
       updateShape(shape, rect); 
      } 

      if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::M) 
      { 
       rect = sf::FloatRect(0, 0, 100, 50); 
       updateShape(shape, rect); 
      } 
     } 

     window.clear(); 
     window.draw(shape); 
     window.display(); 
    } 

    return EXIT_SUCCESS; 
} 

NB: Я использовал несколько трюк из C++ 14, но я уверен, что вы можете преобразовать этот код на C++ 11/C++ 98, если вам нужно.

Смежные вопросы