Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: ConvexShape::getGlobalBounds() Problem  (Read 2460 times)

0 Members and 1 Guest are viewing this topic.

Syndog

  • Newbie
  • *
  • Posts: 9
    • View Profile
ConvexShape::getGlobalBounds() Problem
« on: November 23, 2013, 10:20:25 pm »
Hello, SFML gurus.  :)

I've been kicking around with the ConvexShape class today, and came across something curious.  When I make a call to the ConvexShape::getGlobalBounds() method, it returns a FloatRect whose position and/or size seems to be flawed as the shape rotates.

Here's a simple program to demonstrate...

#include <SFML/Graphics.hpp>

using namespace sf;

int main() {
   RenderWindow window(VideoMode(800, 600), "Bounding Box Demo");

   ConvexShape arrow(4);
   arrow.setPosition(400.0f, 300.0f);
   arrow.setFillColor(Color::Blue);
   arrow.setOutlineColor(Color::Blue);
   arrow.setOutlineThickness(1.0f);
   arrow.setPoint(0, Vector2f(0, -20));
   arrow.setPoint(1, Vector2f(30, 60));
   arrow.setPoint(2, Vector2f(0, 40));
   arrow.setPoint(3, Vector2f(-30, 60));

   Vertex pivotPoint[1];
   pivotPoint[0].position.x = 400.0f;
   pivotPoint[0].position.y = 300.0f;
   pivotPoint[0].color = Color::Yellow;

   FloatRect bounds;
   RectangleShape boundingBox;

   Event event;

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

      window.clear(Color::Black);

      arrow.rotate(0.01f);

      bounds = arrow.getGlobalBounds();
      boundingBox.setPosition(Vector2f(bounds.left, bounds.top));
      boundingBox.setSize(Vector2f(bounds.width, bounds.height));

      window.draw(boundingBox, RenderStates::Default);
      window.draw(arrow, RenderStates::Default);
      window.draw(pivotPoint, 1, sf::PrimitiveType::Points, RenderStates::Default);

      window.display();
   }

   return 0;
}
 

If the arrow is rotated in any of the cardinal compass directions (0, 90, 180, 270 degrees) , the bounding box matches the vertices flawlessly.  However, as the arrow rotates, the bounding box grows increasingly inaccurate as it approaches the diagonal directions (45, 135, 225, 315 degrees), leaving a sizable gap around the arrow's tip, while remaining true to the two ends of the arrow's tail...








I've tried running this using SFML 2.1, plus the latest source snapshot downloaded from the downloads page, and the same behavior persists.  I'm wondering if there's a problem with the ConvexShape::getGlobalBounds() method, or if perhaps I'm just misunderstanding what it's intended to provide.

Any insight would be greatly appreciated!

- Syn
Your Kung Fu is no match for my Feng Shui!

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: ConvexShape::getGlobalBounds() Problem
« Reply #1 on: November 23, 2013, 10:32:54 pm »
That's normal because of way sf::Rect is translated and aligned to axes.
Back to C++ gamedev with SFML in May 2023

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: ConvexShape::getGlobalBounds() Problem
« Reply #2 on: November 23, 2013, 10:35:31 pm »
Additionally, your shape is not convex. The fact that it seems to work nevertheless is a side effect of the current implementation; that may change at any time.

If you need concave shapes, have a look at thor::ConcaveShape.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Syndog

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: ConvexShape::getGlobalBounds() Problem
« Reply #3 on: November 23, 2013, 10:42:36 pm »
@FRex - Ahhh, understood.  Well, that makes it arguably less useful, but at least the behavior is explained.  Thanks for the illustration, it's most helpful!

@Nexus - In regards to the shape being concave, I refer you to the Shapes tutorial...

http://www.sfml-dev.org/tutorials/2.1/graphics-shape.php
Quote
Officially, sf::ConvexShape can only create convex shapes. But in fact, its requirements are a little more relaxed. In fact, the only technical constraint that your shape must follow, is that if you draw a line from its center of gravity to any of its point, you mustn't cross an edge. With this relaxed definition, you can for example draw stars.

The arrow's shape meets this criterion.
Your Kung Fu is no match for my Feng Shui!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: ConvexShape::getGlobalBounds() Problem
« Reply #4 on: November 24, 2013, 10:41:57 am »
Ah you're right. I remembered a discussion where Laurent stated this would be an implementation detail and shouldn't be considered a feature. Apparently he changed his opinion meanwhile ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything