memononen / nanovg

Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.
zlib License
5.15k stars 770 forks source link

Draw fill problems for complex polygons #653

Open bizehao opened 1 year ago

bizehao commented 1 year ago

I used the following code to draw a fill five-pointed star, and I don't know why the fill color is protruding

                nvgBeginPath(vg);
        struct Point {
            float x;
            float y;
        };
        Point _points[5] = {};
        float r = 100;
        for (int i = 0; i < 5; i++) {
            float du = 72 * (i + 1) * M_PI / 180;
            _points[i] = Point{ r * std::cos(du) + 200, r * std::sin(du) + 200 };
        }

        nvgMoveTo(vg, _points[0].x, _points[0].y);
        nvgLineTo(vg, _points[2].x, _points[2].y);
        nvgLineTo(vg, _points[4].x, _points[4].y);
        nvgLineTo(vg, _points[1].x, _points[1].y);
        nvgLineTo(vg, _points[3].x, _points[3].y);

        nvgClosePath(vg);
        //nvgPathWinding(vg, NVG_CW); //it is fill Normal after adding this
        nvgFillColor(vg, nvgRGBA(169, 192, 50, 255));
        nvgFill(vg);

        nvgStrokeWidth(vg, 3);
        nvgStrokeColor(vg, nvgRGBA(169, 86, 250, 255));
        nvgStroke(vg);

image

When I added nvgPathWinding(vg, NVG_CW); After this, he is filling up normally and why?

image

I checked the docs and said that nanovg's fill mode is even-odd filling rule , so I don't understand Thank you for this library Very good to use Hope to get an answer.

ColdPaleLight commented 8 months ago

nanovg has some flaws when calculating whether a polygon is convex. The reason for this issue is that nanovg considers the star to be a convex polygon, so it uses the drawing method of convex polygons instead of stencil-then-cover, resulting in incorrect drawing results.

The key to fixing the issue is to improve the algorithm of convex polygons. For example, add some new ways to determine whether it is convex, like skia: https://github.com/google/skia/blob/chrome/m120/src/core/SkPath.cpp#L2152-L2191

bizehao commented 8 months ago

nanovg has some flaws when calculating whether a polygon is convex. The reason for this issue is that nanovg considers the star to be a convex polygon, so it uses the drawing method of convex polygons instead of stencil-then-cover, resulting in incorrect drawing results.

The key to fixing the issue is to improve the algorithm of convex polygons. For example, add some new ways to determine whether it is convex, like skia: https://github.com/google/skia/blob/chrome/m120/src/core/SkPath.cpp#L2152-L2191

Thank you for your answer, I tried it and added it to nanovg, thank you very much!