2016-06-07 11 views
1

у меня есть один System.Windows.Media.PathGeometry так: 1 И я хотел бы разделить геометрию, так что каждая серая форма находится в новом объекте геометрии , Я попытался выполнить итерацию над FigureColletion PathGeometry и поместить каждую фигуру в новую геометрию, но результат не так, как я ожидал, потому что одна фигура описывает только один край формы, а не сама фигура. Это означает, что некоторые цифры применяются аддитивной и некоторой субтрактивной: 2 Чтобы разбить геометрию правильно, я должен выяснить, какие PathFigures применяются аддитивной и какой субтрактивный. В свойствах PathFigure нет свойства, которое дает мне информацию о том, как оно применяется. У кого-нибудь есть идея, как решить эту проблему?Правильно разделить System.Windows.Media.PathGeometry

Заранее спасибо.

+0

- PathFigures обязательно непересекающиеся? cos, если они пересекаются, тогда вещи становятся более сложными –

+0

Нет, они никогда не пересекаются. Я анализирую все геометрии, прежде чем применять эту операцию. Если есть пересечения, пересекающиеся геометрии будут объединены (через Geometry.Combine (...), а затем PathGeometry.GetOutlinedPath (...)). Функция GetOutlinedPath должна предотвращать пересекающиеся фигуры. – Timo

ответ

0

Если, как вы сказали, что PathFigure «s не пересекаются, т.е. сдерживание является полным, то следствием является то, что если PathFigure А содержит В, то AABB границы А также содержит, что Б.

К сожалению, я не думаю, что у PathFigure есть такое свойство, поэтому одним из способов его преодоления было бы, вероятно, создать отдельные новые объекты PathGeometry из каждого PathFigure внутри свойства .Figures и сохранить их в массиве. Затем отсортируйте этот массив, используя свойство .Bounds.Contains, то есть это: https://msdn.microsoft.com/en-us/library/ms557978(v=vs.110).aspx, вместо операции сравнения в обычной процедуре сортировки.

Теперь у вас есть «матрешка» список PathGeometry-х, начиная с крайним одного, выберите каждые последующие пары и объединит их (.Combine, как вы сказали). Если массив имеет нечетное число элементов, то есть один слева в конце, то это должно быть на рисунке 4.

2

В настоящее время я пытаюсь сделать то же самое, так что вот мой план, а также некоторые мыслительного процесса.

Во-первых, преобразуйте все в PathGeometries. Метод FillContains(Geometry geometry) - это то, что я хочу использовать, чтобы увидеть, что внутри чего. Проблема с .Bounds.Contains заключается в том, что если у вас есть форма C с точкой посередине, точка будет содержаться в ограничивающем прямоугольнике, но не в форме.

Затем создайте структуру данных дерева. Если PathGeometry A содержит PathGeometry B, A будет предком B в дереве. Другой ответ здесь предполагает использование списка, но это не сработает. Остальная часть этого параграфа истолковывает почему. Предположим, что есть два PathFigures, и ни один из них не находится внутри другого: после сортировки списка мы предположили бы, что он находится внутри другого. Мы можем объяснить это без лишней дополнительной работы, но теперь предположим, что есть две PathFigures, окруженные третьей PathFigure (например, число 8): после сортировки мы получаем только одно отверстие, чтобы быть частью 8. Мы можем, возможно, учитывать это также. Последняя проблема: предположим, что A содержит B и C содержит D, но они помещаются в список в порядке {A, C, B, D}: некоторые алгоритмы сортировки (например, BubbleSort) оставят их в этом порядке, потому что нет формы содержит своего соседа. Списки здесь слишком запутаны.

Итак, для нашего дерева, какой корневой узел? Корневой узел будет тем, что содержит все. Если вы хотите создать такую ​​вещь, вы можете взять Союз всех ваших PathGeometries и использовать .Bounds. Могут быть странные случаи, когда это не работает, но это не важно.

Как будет выглядеть наше дерево? Я буду использовать цифры цифр из вашего примера. Нажмите here, чтобы увидеть дерево.

Как мы можем сделать дерево? Я думаю, что это псевдокод легче понять, чем я пытаюсь описать его:

TreeNode.AddNode(PathGeometry geomToAdd) 
{ 
    bool containedByChild = false 
    foreach (TreeNode current in this.Children) 
    { 
     if (current.FillContains(geomToAdd) 
     { 
      containedByChild = true 
      current.AddNode(geomToAdd) 
     } 
    } 
    if (!containedByChild) 
     this.Children.Add(geomToAdd) 
} 

В отличие от бинарного дерева, у нас есть список детей, вместо фиксированного числа детей. Листом в дереве является любой узел с пустым списком детей. Поскольку корневой узел должен содержать все, вы можете просто вызвать этот метод в корне, не требуя определения PathGeometry для root.

Как мы превращаем дерево в наши PathGeometries? Начните с детей root. Это аддитивные PathFigures, а их дети являются субтрактивными PathFigures. Используя .Combine() с GeometryCombineMode.Exclude, вы можете вычесть внуков root из детей root. Затем удалите всех детей из корня и превратите правнуков корня в новый список детей и повторите.

Надеюсь, это ясно. Если это не так, пожалуйста, дайте мне знать, как улучшить ответ.