对 C# 中的 Clipper 感到困惑 [英] Confused on Clipper in C#

查看:17
本文介绍了对 C# 中的 Clipper 感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Unity 中创建一个 2D 游戏,该游戏已按程序放置图块.我想使用 Angus Johnson 的 Clipper 库(特别是联合函数)来简化碰撞几何体,但我遇到了库返回空解的问题,我不知道为什么.

I'm creating a 2D game in Unity which has procedurally placed tiles. I want to simplify the collision geometry using Angus Johnson's Clipper library (specifically the union function), but I'm running into an issue with the library returning empty solutions and I'm not sure why.

作为参考,这里是我用来测试的多边形碰撞器.

For reference, here are the Polygon Colliders I've been using to test.

这是我用来组合几何的函数的简化版本:

And here is a simplified version of the function I'm using to combine the geometry:

    List<List<Vector2>> unitedPolygons = new List<List<Vector2>>();
    Clipper clipper = new Clipper();
    Paths solution = new Paths();
    ClipperOffset offset = new ClipperOffset();

    //Use a scaling factor for floats and convert the Polygon Colliders' points to Clipper's desired format
    int scalingFactor = 10000;
    for (int i = 0; i < polygons.Count; i++)
    {
        Path allPolygonsPath = new Path(polygons[i].points.Length);

        for (int j = 0; j < polygons[i].points.Length; j++)
        {
            allPolygonsPath.Add(new IntPoint(Mathf.Floor(polygons[i].points[j].x * scalingFactor), Mathf.Floor(polygons[i].points[j].y * scalingFactor)));
        }
        bool succeeded = clipper.AddPath(allPolygonsPath, PolyType.ptSubject, true);
    }

    //Execute the union
    bool success = clipper.Execute(ClipType.ctUnion, solution);
    Debug.Log("Polygons after union: " + solution.Count);

    //Offset the polygons
    offset.AddPaths(solution, JoinType.jtMiter, EndType.etClosedPolygon);
    offset.Execute(ref solution, 5f);

    //Convert back to a format Unity can use
    foreach (Path path in solution)
    {
        List<Vector2> unitedPolygon = new List<Vector2>();
        foreach (IntPoint point in path)
        {
            unitedPolygon.Add(new Vector2(point.X / (float)scalingFactor, point.Y / (float)scalingFactor));
        }
        unitedPolygons.Add(unitedPolygon);
    }

    return unitedPolygons;

我通过调试发现第一个 Execute(对于联合)返回一个空的解决方案.我发现Clipper"类中的BuildResult"函数确实在运行,并且m_PolyOuts"中有数据,但该列表中OutRec"的Pts"属性都为空.我不知道这是在哪里发生的,或者它们是否曾经被摆在首位.

What I've discovered through debugging is that the first Execute (for the union) is returning an empty solution. I've figured out that the "BuildResult" function in the "Clipper" class is indeed running, and "m_PolyOuts" has data in it, but the "Pts" property of the "OutRec"s in that list are all null. I can't figure out where this happens or if they were ever set in the first place.

我确信这是正确的行为,我只是错误地使用了库,但我找不到任何文档或示例来解释我需要更改什么才能使联合成功.

I'm convinced this is proper behavior and I'm just using the library wrong, but I can't find any documentation or examples explaining what I need to change to make the union succeed.

谢谢.

我已经缩小了范围.在 Clipper 类中的ExecuteInteral"期间,在运行FixupOutPolygon"函数之前,Pts"列表不为空.之后,所有列表都为空.JoinCommonEdges"也使一些列表为空,但不是全部.

I've narrowed it down a bit more. During "ExecuteInteral" in the Clipper class, the "Pts" lists aren't null until the "FixupOutPolygon" function is run. After that, all of the lists are null. "JoinCommonEdges" also makes a couple of the lists null, but not all of them.

推荐答案

我也一直在从事自己的游戏项目,并偶然发现了与 Clipper 类似的问题.在这种情况下对我有用的不是写这个:

I've been working on my own game project as well and stumbled upon similar problem with Clipper. What worked for me in this case was instead of writing this:

clipper.Execute(ClipType.ctUnion, solution);

...我为 Execute 方法指定了 PolyFillType:

... I specified PolyFillType for Execute method:

clipper.Execute(ClipType.ctUnion, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

我不确定为什么它对我有用,但我认为这是因为某些路径可以共享公共边,因此使用默认的 pftEvenOdd 填充规则,它会被删除.

I'm not sure why it worked for me but I think it's due to the fact that some Paths can share common edges so with the default pftEvenOdd filling rule it gets cut out.

这篇关于对 C# 中的 Clipper 感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆