如何在旋转时渲染 AABB

How to render an AABB while rotating

本文关键字:AABB 旋转      更新时间:2023-10-16

你好,我是SFML C++新手。我应该绘制一些矩形并在旋转时渲染它们的 AABB,我想检测为它们设置的尺寸是否与另一个旋转的 AABB 矩形相交。这是我用来检测它们的方法。如果它们在旋转,这样检查就足够了吗?我需要使用分离轴定理之类的东西吗?或者有没有办法不需要使用它,如果它只是一个 AABB 而不是一个 OBB

#define RECT 5
sf::RectangleShape Rect[RECT];
Rect[0].setSize(sf::Vector2f(50.0f, 50.0f));
Rect[1].setSize(sf::Vector2f(50.0f, 100.0f));
Rect[2].setSize(sf::Vector2f(60.0f, 80.0f));
Rect[3].setSize(sf::Vector2f(100.0f, 60.0f));
Rect[4].setSize(sf::Vector2f(30.0f, 250.0f));
sf::Vector2f MinPoint[RECT];
sf::Vector2f MaxPoint[RECT];
for (int x = 0; x < RECT; x++)
{
    //Starting Position
    Rect[x].setOrigin(Rect[x].getSize().x / 2, Rect[x].getSize().y / 2);
    xpos += 150;
    Rect[x].setPosition(xpos, ypos);
    colcount++;
    if (colcount == 3)
    {
        xpos = 0;
        ypos += 200;
        colcount = 0;
    }
    Rect[x].setFillColor(sf::Color::Red);
}

while (window.isOpen())
{
    window.clear(sf::Color::Black);
    //Drawing Shapes
    for (int x = 0; x < RECT; x++)
    {
        window.draw(Rect[x]);
    }
    Rect[0].rotate(90*3.14/180);
    Rect[1].rotate(12 * 3.14 / 180);
    Rect[2].rotate(10 * 3.14 / 180);
    Rect[3].rotate(180 * 3.14 / 180);
    Rect[4].rotate(360 * 3.14 / 180);

    for (int i = 0; i < RECT; i++)
    {
        MinPoint[i].x = Rect[i].getPosition().x - (Rect[i].getSize().x / 2);
        MaxPoint[i].x = Rect[i].getPosition().x + (Rect[i].getSize().x / 2);
        MinPoint[i].y = Rect[i].getPosition().y - (Rect[i].getSize().y / 2);
        MaxPoint[i].y = Rect[i].getPosition().y + (Rect[i].getSize().y / 2);
    }

    //Collision Detection
    for (int i = 0; i < RECT; i++)
    {
        for (int j = i + 1; j < RECT; j++)
        {
            if (i != j)
            {
                if (MaxPoint[i].x >= MinPoint[j].x && MaxPoint[j].x >= MinPoint[i].x && MaxPoint[i].y >= MinPoint[j].y && MaxPoint[j].y >= MinPoint[i].y)
                {
                    Rect[i].setFillColor(sf::Color::Green);
                    Rect[j].setFillColor(sf::Color::Green);
                }
            }
        }
    }
显然,

我需要做的就是制作另一组透明矩形,其轮廓设置为与旋转矩形框相同的位置,然后将它们的大小设置为旋转矩形的 getGlobalBounds。 然后,碰撞检查将放在这些透明边界框下,而不是旋转矩形本身。

#define RECT 5
sf::RectangleShape Rect[RECT];
sf::RectangleShape AABB[RECT];
Rect[0].setSize(sf::Vector2f(50.0f, 50.0f));
Rect[1].setSize(sf::Vector2f(50.0f, 100.0f));
Rect[2].setSize(sf::Vector2f(60.0f, 80.0f));
Rect[3].setSize(sf::Vector2f(100.0f, 60.0f));
Rect[4].setSize(sf::Vector2f(30.0f, 250.0f));
sf::Vector2f MinPoint[RECT];
sf::Vector2f MaxPoint[RECT];
for (int x = 0; x < RECT; x++)
{
    //Starting Position
    Rect[x].setOrigin(Rect[x].getSize().x / 2, Rect[x].getSize().y / 2);
    AABB[x].setOrigin(AABB[x].getSize().x / 2, AABB[x].getSize().y / 2);
    xpos += 150;
    Rect[x].setPosition(xpos, ypos);
    AABB[x].setSize(sf::Vector2f(Rect[x].getGlobalBounds().width, Rect[x].getGlobalBounds().height));
    AABB[x].setPosition(Rect[x].getPosition().x, Rect[x].getPosition().y);
    colcount++;
    if (colcount == 3)
    {
        xpos = 0;
        ypos += 200;
        colcount = 0;
    }
    Rect[x].setFillColor(sf::Color::Red);
    AABB[x].setFillColor(sf::Color::Transparent);
    AABB[x].setOutlineThickness(1);
    AABB[x].setOutlineColor(sf::Color::White);
}

while (window.isOpen())
{
    window.clear(sf::Color::Black);
    //Drawing Shapes
    for (int x = 0; x < RECT; x++)
   {
        window.draw(Rect[x]);
        window.draw(AABB[x]);
   }
    //Rotation
    Rect[0].rotate(1);
    Rect[1].rotate(45);
    Rect[2].rotate(11.25);
    Rect[3].rotate(5.625);
    Rect[4].rotate(22.5);
   for (int i = 0; i < RECT; i++)
   {
        MinPoint[i].x = AABB[i].getPosition().x - (AABB[i].getSize().x / 2);
        MaxPoint[i].x = AABB[i].getPosition().x + (AABB[i].getSize().x / 2);
        MinPoint[i].y = AABB[i].getPosition().y - (AABB[i].getSize().y / 2);
        MaxPoint[i].y = AABB[i].getPosition().y + (AABB[i].getSize().y / 2);
        AABB[i].setOrigin(AABB[i].getSize().x / 2, AABB[i].getSize().y / 2);
        AABB[i].setSize(sf::Vector2f(Rect[i].getGlobalBounds().width, Rect[i].getGlobalBounds().height));
        AABB[i].setPosition(Rect[i].getPosition().x, Rect[i].getPosition().y);
   }

   //Collision Detection
   for (int i = 0; i < RECT; i++)
   {
       for (int j = i + 1; j < RECT; j++)
       {
           if (i != j)
           {
               if (MaxPoint[i].x >= MinPoint[j].x && MaxPoint[j].x >= MinPoint[i].x && MaxPoint[i].y >= MinPoint[j].y && MaxPoint[j].y >= MinPoint[i].y)
               {
                    Rect[i].setFillColor(sf::Color::Green);
                    Rect[j].setFillColor(sf::Color::Green);
                    AABB[i].setOutlineColor(sf::Color::Blue);
                    AABB[j].setOutlineColor(sf::Color::Blue);
               }
           }
       }
   }