Правильно разделить System.Windows.Media.PathGeometry
У меня есть один System.Windows.Media.PathGeometry, как это:И я хотел бы разделить геометрию, чтобы каждая серая фигура была в новом объекте Geometry. Я попытался перебрать FigureColletion PathGeometry и поместить каждую фигуру в новую геометрию, но результат не такой, как я ожидал, потому что одна фигура описывает только один край фигуры, а не саму фигуру. Это означает, что к некоторым фигурам применяются аддитивные, а некоторые к вычитающим
Чтобы правильно разделить геометрию, я должен выяснить, какие PathFigures применяются, а какие вычитают. В типе PathFigure отсутствует свойство, которое дает мне информацию о том, как его применять. У кого-нибудь есть идеи, как решить эту проблему?
Заранее спасибо.
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
, Могут быть странные случаи, когда это не работает, но это не важно.
Как будет выглядеть наше дерево? Я буду использовать цифры цифры из вашего примера. Нажмите здесь, чтобы увидеть дерево.
Как мы делаем дерево? Я думаю, что этот псевдокод легче понять, чем я, пытаясь описать его:
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 для корня.
Как мы превращаем дерево в наши PathGeometries? Начните с детей корня. Это аддитивные PathFigures, а их потомки - вычитающие PathFigures. С помощью .Combine()
с GeometryCombineMode.Exclude
Вы можете вычесть внуков корня из детей корня. Затем удалите всех дочерних элементов из root и включите правнуков root в новый список дочерних элементов и повторите.
Надеюсь, это понятно. Если это не так, пожалуйста, дайте мне знать, как улучшить ответ.
Если, как вы упомянули, PathFigure
не пересекаются, т. е. сдерживание завершено, то если PathFigure
A содержит B, тогда границы AABB для A также содержат границы B.
К сожалению я не думаю PathFigure
имеет такое свойство, поэтому один из способов преодоления этого, вероятно, будет создавать отдельные новые PathGeometry
объекты от каждого PathFigure
внутри .Figures
свойство, и хранить их в массиве. Затем отсортируйте этот массив, используя .Bounds.Contains
свойство, то есть это: https://msdn.microsoft.com/en-us/library/ms557978(v=vs.110).aspx, вместо операции сравнения в обычной процедуре сортировки.
Теперь у вас есть список "Матрешка" PathGeometry
ы, начиная с самой внешней, выбирают каждую последующую пару и берут их объединение (.Combine
как вы сказали). Если массив имеет нечетное количество элементов, то есть один слева в конце, то это должно иметь место на рисунке 4.