Соедините простые полигоны и нарисуйте получившиеся контуры в Eyeshot

Как проще всего соединить набор полигонов и нарисовать получившийся контур с помощью Eyeshot? Пока мне удалось получить только заполненные области, но меня интересует слияние контуров.


person stenio    schedule 18.05.2018    source источник


Ответы (2)


Поскольку у вас есть область, очень легко получить из нее контур.

// if you know the region is a simple region (not containing full circles) get the curves
List<ICurve> curves = (region.ContourList.FirstOrDefault() as CompositeCurve).CurveList;

ICurve - это линия и дуга, насколько я знаю. Итак, вы можете протестировать:

bool isLine = curves[0] is Line
bool isArc = curves[0] is Arc

Все кривые в списке упорядочены, чтобы вы могли легко изменить область. Кроме того, если region.ContourList содержат более 1 контура, это означает, что в вашем регионе есть дыры. Первый элемент всегда будет основным контуром, а все последующие элементы также будут контуром, но с отверстиями.

Контурная кривая дана против часовой стрелки, а внутренняя - по часовой стрелке.

person Franck    schedule 22.05.2018
comment
Спасибо @Franck. Знаете ли вы, нужен ли код, подобный тому, что в моем ответе, для объединения всех регионов или в Eyeshot уже что-то реализовано? - person stenio; 22.05.2018
comment
@stenio лично часто использует Region.Union, и я использую ту же линию, что описана выше, чтобы получить окончательный контур. Я создаю Region с помощью конструктора ICurve, указывающего все вершины многоугольника. - person Franck; 22.05.2018
comment
но если у вас есть, скажем, 10 полигонов для соединения, как вы справитесь с тем фактом, что Region.Union возвращает массив вместо одной области? - person stenio; 22.05.2018
comment
@stenio, если регион 1 пересекает регион 2, результат Union вернет массив с 1 регионом. Если область 1 и область 2 не пересекаются, массив вернет пустое значение или будет содержать 2 или более элементов. Логика того, как правильно объединять регионы, — это вопрос сам по себе, на который у меня тоже есть ответ. - person Franck; 22.05.2018

Я пришел к этому решению. Чтобы отобразить полигоны, просто выполните итерацию по объединенным областям, выполните итерацию по ContourList и создайте LinearPaths.

private List<PolyRegion2D> Joiner(IEnumerable<Polygon2D> polygons) {
        // The resulting polygons are unconnected
        List<PolyRegion2D> res = new List<PolyRegion2D>();

        // Put every polygon in a region to do the unions.
        LinkedList<PolyRegion2D> polygonRegions = new LinkedList<PolyRegion2D>();
        foreach (Polygon2D polygon in polygons) {
            polygonRegions.AddLast(new PolyRegion2D(new Polygon2D[]{polygon}));
        }

        while (polygonRegions.Count > 0) {
            PolyRegion2D first = polygonRegions.First.Value;
            polygonRegions.RemoveFirst();
            PolyRegion2D union;
            LinkedListNode<PolyRegion2D> connected = FindConnected(first, polygonRegions, out union);
            if (connected == null) {
                // Unconnected polygon
                res.Add(first);
            } else {
                // Intersection found
                polygonRegions.Remove(connected);
                polygonRegions.AddFirst(union);
            }
        }

        return res;
    }

    private LinkedListNode<PolyRegion2D> FindConnected(PolyRegion2D poly, LinkedList<PolyRegion2D> polys, out PolyRegion2D union) {
        LinkedListNode<PolyRegion2D> node = polys.First;
        while(node != null){
            PolyRegion2D[] union_ = PolyRegion2D.Union(poly, node.Value);
            if (union_.Length == 1) {
                union = union_[0];
                return node;
            }
            node = node.Next;
        }
        union = null;
        return null;
    }
person stenio    schedule 21.05.2018
comment
Я только что узнал, что PolyRegion2D.Union не соединяется с многоугольником в форме буквы C с I, чтобы сформировать квадрат с отверстием, но приведенный выше код предполагает такое поведение. - person stenio; 22.05.2018
comment
Это была ошибка, которая должна была быть исправлена ​​в последней ночной сборке. - person stenio; 26.05.2018
comment
Ошибка была исправлена ​​в сборке 11.0.642. Теперь приведенный выше код правильно объединяет все полигоны в наименьший набор несвязанных полигонов. - person stenio; 28.05.2018