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

Author Topic: LineStrip VertexArray and ConvexShape problem  (Read 4409 times)

0 Members and 1 Guest are viewing this topic.

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
LineStrip VertexArray and ConvexShape problem
« on: February 01, 2024, 01:01:32 pm »
https://drive.google.com/file/d/1NQ3TmGzIDqNzuf2F6pHVJbfp4BtOjAMj/view?usp=sharing 
Hello, as you can see in the png file, I am creating a shape using 21 points with vertexarray as linestrip, and drawing it on the screen. The shape comes out exactly as I want when using linestrip, but when I apply the same points with convexShape, the shape doesn't come out as I expect. What could be the reason for this? Am I making a mistake somewhere? Here is my code.

int main()
{
    sf::RenderWindow window(sf::VideoMode(1366, 768), "testing",sf::Style::Default, sf::ContextSettings(0, 0, 8));

    std::vector<sf::Vector2f> points = style.getPoints();

    points.emplace_back(0, 0);
    points.emplace_back(0.851345, 9.18748);
    points.emplace_back(3.37638, 18.0621);
    points.emplace_back(7.48914, 26.3216);
    points.emplace_back(13.0495, 33.6848);
    points.emplace_back(19.8683, 39.9009);
    points.emplace_back(27.7131, 44.7582);
    points.emplace_back(36.3168, 48.0913);
    points.emplace_back(45.3866, 49.7867);
    points.emplace_back(54.6134, 49.7867);
    points.emplace_back(63.6831, 48.0913);
    points.emplace_back(72.2869, 44.7582);
    points.emplace_back(80.1317, 39.9009);
    points.emplace_back(86.9504, 33.6848);
    points.emplace_back(92.5109, 26.3216);
    points.emplace_back(96.6236, 18.0621);
    points.emplace_back(99.1487, 9.18748);
    points.emplace_back(100, 0);
    points.emplace_back(100, 100);
    points.emplace_back(0, 100);
    points.emplace_back(0, 0);

    sf::VertexArray va;
    va.setPrimitiveType(sf::PrimitiveType::LineStrip);
    va.resize(points.size());

    for (std::size_t i = 0; i < va.getVertexCount(); i++)
    {
        va[i].position = points[i];
    }

    sf::Transform ts1;
    ts1.translate(100, 200);

    sf::ConvexShape shape;
    shape.setPointCount(points.size());

    for (std::size_t i = 0; i < shape.getPointCount(); i++)
    {
        shape.setPoint(i, points[i]);
    }

    shape.setPosition(300, 200);

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

       
        window.clear();

        window.draw(va, ts1);
        window.draw(shape);
       
        window.display();
    }

    return 0;
   
}
« Last Edit: February 01, 2024, 02:39:51 pm by eXpl0it3r »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: LineStrip VertexArray and ConvexShape problem
« Reply #1 on: February 01, 2024, 02:40:35 pm »
The image isn't accessible.

Did you make sure that the shape is convex and not concave?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #2 on: February 01, 2024, 02:46:19 pm »
I forgot to make the link public, it should be accessible now.
https://drive.google.com/file/d/1NQ3TmGzIDqNzuf2F6pHVJbfp4BtOjAMj/view?usp=sharing

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #3 on: February 01, 2024, 02:52:18 pm »
What I'm trying to do here is to draw an inward-curved arc on the top edge of a square, but it seems I can't achieve this using convex shape. Is there another way to do this?

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #4 on: February 01, 2024, 11:15:34 pm »
ConvexShape needs shapes to be convex. That means no inward angles like the curved top part. Your shape is concave, which is harder to draw filled.

Why concave doesn't work is Shapes (like ConvexShape) use a triangle fan from the centre. To reach the top corners from the centre, it has to draw over the top of the curved parts, resulting in the triangle shape instead of the curve.

There's no built in way to do concave shapes in SFML (that I know of), you'll need to generate a triangle mesh using an algorithm like "ear clipping" (it can turn concave into triangles that don't overlap). But implementing that can be tricky.

Or depending on how you intend to use it, maybe do something like draw a white rectangle then a black circle over the top.

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #5 on: February 02, 2024, 09:35:51 am »
Why doesn't SFML provide support for drawing both concave and convex shapes in a single entity, like a complex shape, instead of using convex shape? Is this related to the ear clipping algorithm you mentioned? It might be challenging for me to implement, and frankly, I don't have such an intention. Do you know of any other library that provides this support, and should I share this situation in the feature request section of SFML, or is there another appropriate channel for such requests

fallahn

  • Hero Member
  • *****
  • Posts: 507
  • Buns.
    • View Profile
    • Trederia
Re: LineStrip VertexArray and ConvexShape problem
« Reply #6 on: February 02, 2024, 10:54:32 am »
SelbaWard looks like it supports this: https://github.com/Hapaxia/SelbaWard/wiki/Polygon

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #7 on: February 03, 2024, 12:57:33 pm »
I took the code from GitHub and tried it, but while there is no issue with the points used in the GitHub example, I encountered a runtime error when using the points in my own code. Does anyone have a better suggestion or solution for this?

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #8 on: February 03, 2024, 01:09:21 pm »
What I'm trying to do is allowing the user to input corner information as a percentage, and then I scale these percentage points using setSize() by multiplying each point with a scalar value. I want to draw inner and outer arcs between these scaled corners based on user preferences. Additionally, I'm rounding each corner both inward and outward, and I've handled all of this using trigonometric calculations. Everything is actually working fine; the only issue arises when drawing inner concave arcs. The problem occurs as the apex of the arc approaches the center of the shape. Interestingly, this problem is specific to inner concave arcs. Moreover, when I tried the code from GitHub, I encountered a runtime error. I wanted to provide more details, but I believe you've already understood the situation. :)

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: LineStrip VertexArray and ConvexShape problem
« Reply #9 on: February 03, 2024, 05:39:00 pm »
I encountered a runtime error. I wanted to provide more details, but I believe you've already understood the situation. :)
What was the runtime error? Did you catch it and output the message?

What I'm trying to do is allowing the user to input corner information as a percentage, and then I scale these percentage points using setSize() by multiplying each point with a scalar value. I want to draw inner and outer arcs between these scaled corners based on user preferences. Additionally, I'm rounding each corner both inward and outward, and I've handled all of this using trigonometric calculations. Everything is actually working fine; the only issue arises when drawing inner concave arcs. The problem occurs as the apex of the arc approaches the center of the shape. Interestingly, this problem is specific to inner concave arcs. Moreover, when I tried the code from GitHub, I encountered a runtime error. I wanted to provide more details, but I believe you've already understood the situation. :)

You can also create this exact shape with triangles quite simply yourself. You can split it into vertical pieces (vertical stripes where the top is at an angle). So, the bottom line would have as many points on that line as the curve has. This makes it a lot closer to a graph display (I'm actually currently working on some graph stuff at the moment and the bar graph is pretty much ready and would solve this, I reckon, so look out for that soon!). Basically, you can use separate triangles or a triangle strip (if careful) for that.

Another method would be to create triangles between each point of the curve, the previous point of the curve and a bottom corner (the closest bottom corner). You may need a triangle to fill the bottom corners and the central point of the curve.


EDIT:
Now, you can try Zuhyou. Use the Line (graph) and switch on area and switch off line. Then, you just set the values of the top part to form the curve. Basically, you're settings the values to create the line of the top. Note that Zuhyou's Line uses fixed steps between each value.
« Last Edit: February 04, 2024, 01:09:41 pm by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #10 on: February 09, 2024, 02:58:54 pm »
I solved this problem using the scan line algorithm, and everything is progressing as it should now. However, I encountered some minor issues. I tried drawing a few shapes of the same color, and while the shapes were drawn correctly, there was a difference in color tones. For example, I applied white color to both shapes, and while one shape appeared as it should, the other shape appeared as a darker shade of white. I realized that this was due to antialiasing. I had set the value to 4, and when I changed it back to 0, I got rid of this color tone difference, but then I encountered rough edges, of course. Is the scan line algorithm insufficient? I'm exploring other techniques for this, but the scan line seemed to be the easiest for me. What I'm curious about is, can I eliminate this problem with different polygon filling techniques?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: LineStrip VertexArray and ConvexShape problem
« Reply #11 on: February 12, 2024, 09:04:50 pm »
It's important to realise that Selba Ward's Polygon can do this shape automatically, by the way (both triangulation methods work):

However, the order of vertices are VERY important. They absolutely must be in a consistent order around around the perimeter and in an anti-clockwise/counter-clockwise direction. It's best not to duplicate vertices too.
(if they are in the wrong order, you can tell Polygon to reverse their order: reverseVertices)
NOTE: I added the wireframe in the example to show how Polygon triangulated it but it's wasn't a part of the actual Polygon. However, a recent Polygon update allows these wireframes automatically.
« Last Edit: February 12, 2024, 10:28:00 pm by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #12 on: February 13, 2024, 04:35:38 pm »
Yes, as you mentioned, it worked when I tried it counterclockwise. However, I don't understand why I can't send the points clockwise. Also, since there is no outline and texture mapping, I had to do it myself, and since I'm not very familiar with the ear clipping method, I used the scanline algorithm, which seemed easier for me. The ear clipping algorithm creates shapes using triangles. So, is it possible to create all complex shapes using triangles? Currently, everything is progressing smoothly with the scanline, but I encounter some minor issues such as the lines appearing when changing the size of the screen along the y-axis and a slight color tone shift that I mentioned earlier. Besides these two issues, when I send points both clockwise and counterclockwise, it works, and since I've also managed the outline and texture mapping parts, I feel a bit relieved. Is it possible to configure Polygon to work both clockwise and counterclockwise? If possible, I would like to use the relevant code part of the algorithm in my own code. :)

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: LineStrip VertexArray and ConvexShape problem
« Reply #13 on: February 13, 2024, 06:21:38 pm »
Polygon requires anti-clockwise due to the calculations testing angles based on inside/outside. It could be adjusted to work with clockwise by swapping angles and sides but the ability to do both is extra calculations for both ways. However, Polygon can reverse them for you so you can provide them as clockwise and reverse them.
Maybe a future update would have the ability to do both by traversing the points in both directions.
Polygon's next update will have colour and texture; that's already ready but I'm looking into other methods and mesh refinement as well as other improvements.
An outline was considered for polygon but since it exports its positions, this can be generated super-easy, especially with Spline (also Selba Ward), which takes those exported positions directly.

With your implementation, remember that resizing the window doesn't automatically resize the view. Maybe that is involved.
https://www.sfml-dev.org/tutorials/2.6/graphics-view.php#showing-more-when-the-window-is-resized

I can't really say why your tone is shifting. I wonder if it may be because it's on a different part of the display and the angle of viewing is different...

And yes, every complex shape can be represented by triangles.
If you have any vertex array shape (not the points or lines primitives) then you can easily extract its triangles:
https://github.com/SFML/SFML/wiki/Source%3A-Triangles-Extractor
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #14 on: February 14, 2024, 02:47:37 pm »
Yes, I'm aware of your spline feature, but I tend to think more about polygons when considering these features. Currently, I needed a polygon for my own GUI library, and since SelbaWard didn't fully meet my requirements, I created my own class. Now, I understand why there were two issues. Normally, when drawing scanline lines, I was shifting them by 1 pixel, but the scaling along the y-axis was messing it up. The reason was that I was drawing the corners with sf::Lines, and when scaling, the line size probably remained 1 pixel. So, instead of using lines to be filled during the drawing stage, I used sf::RectangleShape, and both issues were resolved. The difference is that when you create triangles, the scaling is probably automatically handled in pixels, but I had issues since I used 1-pixel sf::Lines. It seems it would be more appropriate to write the code in OpenGL for better performance anyway. Also, you mentioned that all complex shapes can be created with triangles, so I did a test. I set the points of the polygon to resemble a shape reminiscent of a butterfly, meaning imagine a 4-sided polygon with the second and fourth sides intersecting. Your code doesn't seem to handle such cases, or maybe you've addressed this separately. I'm still a novice in these matters. :)

I must say that SelbaWard is really good, but still, the polygon part didn't fully meet my needs. For example, the sent corner points are the essence of the polygon, and I needed features like rounding these corners inward and outward, as well as making the edges go by drawing arcs instead of straight lines between the corners. You probably understand what I mean; it's just that my requirements didn't quite align with the library's features. ;)

 

anything