1

What is the best way to draw advanced custom shapes with a lot of roundings while using the SFML library in C++?

I know how to draw shapes like rectangles or circles with the SFML library in C++. But if you want to make a custom shape you can make use of a vertex array.

If I want to draw a shape like this for example:
Example of advanced shape
You can start with a point on the top-left to the top-right. But then you have to deal with a lot of bumps. What is the best way to draw this shape?

A function can be created to calculate all the points in the curve, But is it correct to use 1000 points for small shape like this? (especially if you have a lot of these shapes)

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
  • I think you need Bezier coube, may be this can help https://en.sfml-dev.org/forums/index.php?topic=11803.0 – Martin Morterol Apr 23 '19 at 16:42
  • I took a look at the [SFML doc](https://www.sfml-dev.org/tutorials/2.5/graphics-shape.php). See the `EllipseShape ` example. The drawer will iterate a given number of points and ask you for their locations. So you need to compose your drawing as a linestring yourself. – lakeweb Apr 23 '19 at 16:47
  • SFML can do convex shapes like this, but your shape is not convex (it has a dip along its boundary). You'll probably need to compute your own triangle strip mesh to account for the thick outline. [triangle strip wikipedia](https://en.wikipedia.org/wiki/Triangle_strip) [SFML vertex array](https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1VertexArray.php) – alter_igel Apr 23 '19 at 16:57
  • This isn't specific to SFML; it's about drawing curvy shapes in general. The approach you can take is largely dependent on the constraints of your application. It *might* be correct to use 1000 points, and it might be not. Should it scale indefinitely? Should it be fast or precise? Without knowing all those details, it's impossible to answer this with one, definitive, "best" answer. I vote to close this as "too broad" in the current form. – Bartek Banachewicz Apr 24 '19 at 09:36
  • You can generate [Bézier curves](https://github.com/SFML/SFML/wiki/Source%3A-cubic-bezier-curve) to create your [custom shapes with `sf::VertexArray`](https://www.sfml-dev.org/tutorials/2.5/graphics-vertex-array.php) – alseether Apr 26 '19 at 06:28

1 Answers1

0

Here's something that I made for you. This might sound silly, but what it does is, you can draw your shapes outline, then click the right mouse button to convert the rectangles positions (X,Y) into points which a convex shape will take and create itself into a nice shape.

//This is not necessary, but it helps if you going to move the camera.
    Vector2i pixelPos = Mouse::getPosition(*Twin);
    Vector2f worldPos = Twin->mapPixelToCoords(pixelPos);

    // declare the variables
    RectangleShape* brush;
    vector<RectangleShape> brushV;
    ConvexShape yourShape;
    vector<Vector2f> pos;
    brush = new RectangleShape;

    // the brush, which creates rectangles
    if (Mouse::isButtonPressed(Mouse::Left))
    {
        brushV.push_back(*brush);
        brushV[brushV.size() - 1].setSize(Vector2f(10, 10));
        brushV[brushV.size() - 1].setPosition(Vector2f(worldPos));
        pos.push_back(worldPos);
    }

    // creates the whole shape which you drew
    if (Mouse::isButtonPressed(Mouse::Right))
    {
        yourShape.setPointCount(pos.size());
        for (int i = 0; i < pos.size(); i++)
        {
            yourShape.setPoint(i, pos[i]);
        }
        brushV.clear();
    }

    // render
    for (int i = 0; i < brushV.size(); i++)
    {
        window->draw(brushV[i]);
    }
    window->draw(yourShape);

If the edges look rough you can try using antialiased.

sf::ContextSettings settings;
settings.antialiasingLevel = 8;
Jakebix
  • 63
  • 8