【问题标题】:Rotate an axis aligned rectangle by a 90 degrees将轴对齐的矩形旋转 90 度
【发布时间】:2015-04-04 19:05:36
【问题描述】:

我有矩形对象 (sf::IntRect) ,其属性:二维平面上的左、上、宽和高。我想围绕点 (0,0) 将它旋转 90 度的倍数(即 90、180 或 270)。因此,我正在编写这样的函数:

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

旋转为 0 (0)、1 (90)、2 (180) 或 3 (270)。

我怎样才能尽可能简单地做到这一点。

【问题讨论】:

  • 你有没有尝试过?
  • 我对 SFML 不熟悉。它可能具有计算上述旋转的变换矩阵的功能。如果没有,它们非常简单。见en.wikipedia.org/wiki/Rotation_matrix。
  • 看sf::Transform。但是你确定要使用 IntRect 吗?
  • 我的问题可能表达得不够清楚。问题不在于旋转点,我在使用旋转矩阵之前已经这样做了。我只是不能简单地重新定义左上角。我确定有一个简单的方程式我可以使用,但我找不到它。 @Hiura 是的,我只是在尝试一些东西,它不是非常面向 SFML 的

标签: c++ rotation 2d sfml


【解决方案1】:

这是在sf::FloatRect 上使用sf::Tranform 的基本解决方案:

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;
}

注意:我使用了 C++14 中的一些技巧,但我相信您可以根据需要将该代码转换为 C++11/C++98。

【讨论】:

    猜你喜欢
    • 2020-09-04
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 2023-03-21
    • 2011-03-22
    • 1970-01-01
    相关资源
    最近更新 更多