Skip to content

Commit

Permalink
Add getter and setter for miter limit with simple tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kimci86 committed Oct 28, 2023
1 parent d90ea64 commit 812ee1d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
29 changes: 29 additions & 0 deletions include/SFML/Graphics/Shape.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,24 @@ class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
////////////////////////////////////////////////////////////
void setOutlineThickness(float thickness);

////////////////////////////////////////////////////////////
/// \brief Set the limit on the ratio between miter length and outline thickness
///
/// The edges of the shape's outline around sharp angles can meet
/// well beyond the outline thickness. When the ratio between the
/// miter length (distance between the outline's tip and the shape's
/// corner) and the outline thickness exceeds the given limit, then
/// the join is converted from a miter to a bevel.
/// The miter limit must be greater than or equal to 1.
/// By default, the miter limit is 4.
///
/// \param miterLimit New miter limit
///
/// \see getMiterLimit
///
////////////////////////////////////////////////////////////
void setMiterLimit(float miterLimit);

////////////////////////////////////////////////////////////
/// \brief Get the source texture of the shape
///
Expand Down Expand Up @@ -181,6 +199,16 @@ class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
////////////////////////////////////////////////////////////
float getOutlineThickness() const;

////////////////////////////////////////////////////////////
/// \brief Get the limit on the ratio between miter length and outline thickness
///
/// \return Limit on the ratio between miter length and outline thickness
///
/// \see setMiterLimit
///
////////////////////////////////////////////////////////////
float getMiterLimit() const;

////////////////////////////////////////////////////////////
/// \brief Get the total number of points of the shape
///
Expand Down Expand Up @@ -314,6 +342,7 @@ class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
Color m_fillColor{Color::White}; //!< Fill color
Color m_outlineColor{Color::White}; //!< Outline color
float m_outlineThickness{}; //!< Thickness of the shape's outline
float m_miterLimit{4.f}; //!< Limit on the ratio between miter length and outline thickness
VertexArray m_vertices{PrimitiveType::TriangleFan}; //!< Vertex array containing the fill geometry
VertexArray m_outlineVertices{PrimitiveType::TriangleStrip}; //!< Vertex array containing the outline geometry
FloatRect m_insideBounds; //!< Bounding rectangle of the inside (fill)
Expand Down
28 changes: 22 additions & 6 deletions src/SFML/Graphics/Shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include <algorithm>

#include <cassert>
#include <cmath>

namespace
Expand Down Expand Up @@ -123,7 +124,7 @@ const Color& Shape::getOutlineColor() const
void Shape::setOutlineThickness(float thickness)
{
m_outlineThickness = thickness;
update(); // recompute everything because the whole shape must be offset
updateOutline();
}


Expand All @@ -134,6 +135,22 @@ float Shape::getOutlineThickness() const
}


////////////////////////////////////////////////////////////
void Shape::setMiterLimit(float miterLimit)
{
assert(1.f <= miterLimit && "Miter limit must be greater than or equal to 1");
m_miterLimit = miterLimit;
updateOutline();
}


////////////////////////////////////////////////////////////
float Shape::getMiterLimit() const
{
return m_miterLimit;
}


////////////////////////////////////////////////////////////
Vector2f Shape::getGeometricCenter() const
{
Expand Down Expand Up @@ -290,8 +307,8 @@ void Shape::updateTexCoords()
////////////////////////////////////////////////////////////
void Shape::updateOutline()
{
// Return if there is no outline
if (m_outlineThickness == 0.f)
// Return if there is no outline or no vertices
if (m_outlineThickness == 0.f || m_vertices.getVertexCount() < 2)
{
m_outlineVertices.clear();
m_bounds = m_insideBounds;
Expand All @@ -303,9 +320,8 @@ void Shape::updateOutline()
// We will add two more vertices each time we need a bevel.

// Parameters to compute bevels
const float miterLimit = 4.f;
const float minExtension = 1.f;
const float maxExtension = std::sqrt(miterLimit * miterLimit - 1.f);
const float maxExtension = std::sqrt(m_miterLimit * m_miterLimit - 1.f);

// Determine if points are defined clockwise or counterclockwise. This will impact normals computation.
const bool flipNormals = [this, count]()
Expand Down Expand Up @@ -333,7 +349,7 @@ void Shape::updateOutline()

// Decide whether to add a bevel or not
const float factor = 1.f + n1.dot(n2);
const float squaredLengthRatio = miterLimit * miterLimit * factor / 2.f;
const float squaredLengthRatio = m_miterLimit * m_miterLimit * factor / 2.f;
const bool isConvexCorner = 0.f <= d1.dot(n2) * m_outlineThickness;
const bool needsBevel = factor == 0.f || (squaredLengthRatio < 1.f && isConvexCorner);

Expand Down
8 changes: 8 additions & 0 deletions test/Graphics/Shape.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ TEST_CASE("[Graphics] sf::Shape")
CHECK(triangleShape.getFillColor() == sf::Color::White);
CHECK(triangleShape.getOutlineColor() == sf::Color::White);
CHECK(triangleShape.getOutlineThickness() == 0.0f);
CHECK(triangleShape.getMiterLimit() == 4.0f);
CHECK(triangleShape.getLocalBounds() == sf::FloatRect());
CHECK(triangleShape.getGlobalBounds() == sf::FloatRect());
}
Expand Down Expand Up @@ -88,6 +89,13 @@ TEST_CASE("[Graphics] sf::Shape")
CHECK(triangleShape.getOutlineThickness() == 3.14f);
}

SECTION("Set/get miter limit")
{
TriangleShape triangleShape({});
triangleShape.setMiterLimit(6.28f);
CHECK(triangleShape.getMiterLimit() == 6.28f);
}

SECTION("Virtual functions: getPoint, getPointCount, getGeometricCenter")
{
const TriangleShape triangleShape({2, 2});
Expand Down

0 comments on commit 812ee1d

Please sign in to comment.