Как проще всего соединить набор полигонов и нарисовать получившийся контур с помощью Eyeshot? Пока мне удалось получить только заполненные области, но меня интересует слияние контуров.
Соедините простые полигоны и нарисуйте получившиеся контуры в Eyeshot
Ответы (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
Спасибо @Franck. Знаете ли вы, нужен ли код, подобный тому, что в моем ответе, для объединения всех регионов или в Eyeshot уже что-то реализовано?
- person stenio; 22.05.2018
@stenio лично часто использует
Region.Union
, и я использую ту же линию, что описана выше, чтобы получить окончательный контур. Я создаю Region
с помощью конструктора ICurve
, указывающего все вершины многоугольника.
- person Franck; 22.05.2018
но если у вас есть, скажем, 10 полигонов для соединения, как вы справитесь с тем фактом, что
Region.Union
возвращает массив вместо одной области?
- person stenio; 22.05.2018
@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
Я только что узнал, что
PolyRegion2D.Union
не соединяется с многоугольником в форме буквы C с I, чтобы сформировать квадрат с отверстием, но приведенный выше код предполагает такое поведение.
- person stenio; 22.05.2018
Это была ошибка, которая должна была быть исправлена в последней ночной сборке.
- person stenio; 26.05.2018
Ошибка была исправлена в сборке 11.0.642. Теперь приведенный выше код правильно объединяет все полигоны в наименьший набор несвязанных полигонов.
- person stenio; 28.05.2018