我一直在尝试开发一种算法,根据一个图形是否完全封闭在另一个图形的周长内,对一组封闭的几何图形进行排序,但运气不佳。当完全分析后,我应该得到一个定义层次结构的树结构。
我可以考虑实际的比较,即一个形状是否完全在另一个形状的周长内但我对无组织输入的排序有困难我怀疑解决方案涉及到二叉树结构和递归代码,这是我从来没有强过的。
在生成已排序的层次结构数据之前,几何数据已经过清理,因此开放路径、重叠、部分重叠和自相交等问题不应成为问题。
下面是一组我一直在研究的测试图,可能有助于说明我的问题。
c# - 确定几何形状层次所需的算法-LMLPHP
作为一个人,我可以看到黄色的形状不在蓝色的形状之内,蓝色也不在黄色的形状之内。它们都是绿色的,也就是红色的等等。(向色盲者道歉)
结果树如下:
c# - 确定几何形状层次所需的算法-LMLPHP
我在C区工作,但不认为这与问题有关。
谢谢你
编辑1
一个更简洁的问题可能是“如何生成具有正确顺序的树?”(给定的数据没有特定的顺序)这只是你的基本教科书“二进制搜索树插入”,我可能在想?
编辑2
试图把Norlesh的伪代码转换成C语言并把它绑定到我现有的代码中,我最后得到如下:

        // Return list of shapes contained within container contour but no other
    private List<NPContour> DirectlyContained(NPContour container, List<NPContour> contours)
    {
        List<NPContour> result = new List<NPContour>();

        foreach (NPContour contour in contours)
        {
            if (container.Contains(contour))
            {
                foreach (NPContour other in contours)
                {
                    if (other.Contains(contour))
                        break;
                    result.Add(contour);
                }
            }
        }

        return result;
    }

    // Recursively build tree structure with each node being a list of its children
    private void BuildTree(NPContourTreeNode2 parent, List<NPContour> contours)
    {
        List<NPContour> children = DirectlyContained(parent.Contour, contours);

        if (children.Count > 0)
        {
            // TODO: There's probably a faster or more elegant way to do this but this is clear and good enough for now
            foreach (NPContour child in children)
            {
                contours.Remove(child);
                parent.Children.Add(new NPContourTreeNode2(child));
            }

            foreach (NPContourTreeNode2 child in parent.Children)
            {
                BuildTree(child, contours);
            }
        }
    }

…还有电话号码…
            List<NPContour> contours = new List<NPContour>();
        List<NPContour> _topLevelContours = new List<NPContour>();
        bool contained = false;

        foreach (NPChain chain in _chains)
        {
            if (chain.Closed)
            {
                NPContour newContour = new NPContour(chain);
                contours.Add(newContour);
            }
        }

        //foreach (NPContour contour in contours)
        for (int i = 0; i < contours.Count(); i++)
        {
            contained = false;
            foreach (NPContour container in contours)
            {
                if (container.Contains(contours[i]))
                {
                    contained = true;
                    continue;
                }
            }
            if (contained == false)
            {
                _topLevelContours.Add(contours[i]);
                contours.Remove(contours[i]);
            }
        }

        foreach (NPContour topLevelContour in _topLevelContours)
        {
            NPContourTreeNode2 topLevelNode = new NPContourTreeNode2(topLevelContour);
            BuildTree(topLevelNode, contours);
        }

我想我一定是误解了翻译中的一些东西,因为它不起作用我将继续努力,但我想我会张贴在这里的代码,希望有人可以帮助指出我的错误。
注意,伪代码中存在一个差异,因为buildTree没有返回任何内容,但是在调用代码中,返回值被附加到…好吧,我有点搞不清楚它到底应该去哪里。我对这个例子有了大致的了解,但我想可能有一些重要的地方对我失去了兴趣。
到目前为止,在我的简短调试中,我似乎从下面的示例中得到了不止一个顶级形状(而应该只有一个)和各种子级的倍数(比如55?)。我希望以后能够提供更多的调试信息。

最佳答案

下面是一些伪代码,可以实现您的尝试:
// return true if shape is enclosed completely inside containerfunction contains(container, shape);// return list of shapes contained within container shape but no other.function directlyContained(container, shapes) { result = [] for (shape in shapes) { if (contains(container, shape)) { // check its not further down hierarchy for (other in shapes) { if (contains(other, shape)) { break // not the top level container } result.append(shape) } } } return result;}// recursively build tree structure with each node being a list of its children// - removes members of shapes list as they are claimed.function buildTree(parent, shapes) { children = directlyContained(parent, shapes) if (children.length > 0) { shapes.remove(children); parent.append(children); for (child in children) { // recall on each child buildTree(child, shapes); } }}function findTopLevel(shapes) { result = [] // find the one or more top level shapes that are not contained for shape in shapes { contained = false; for (container in shapes) { if (contains(container, shape)) { contained = true; continue; } } if (contained = false) { scene.append(shape); shapes.remove(shape); } } return result;}shapes = <...>; // list initialized with the unsorted shapesscene = findTopLevel(shapes);shapes.remove(scene);for (top in scene) { buildTree(top, shapes);}

10-08 14:22