Мини-язык описания геометрии

54

Примеры геометрии, продемонстрированные до сих пор, были сравнительно короткими, состоящими из нескольких точек. Более сложная геометрия концептуально описывается так же, но может потребовать сотен сегментов. Определение каждой линии, дуги и кривой в сложном пути чрезвычайно многословно, да и не нужно — в конце концов, весьма вероятно, что такие сложные пути будут генерироваться инструментом графического дизайна, а не писаться вручную, так что ясность разметки не так важна.

Памятуя об этом, создатели WPF предусмотрели более краткий альтернативный синтаксис, который позволяет представлять детализированные фигуры с меньшим объемом кода разметки. Этот синтаксис часто называют мини-языком геометрии (а иногда мини-языком путей, поскольку он применяется к элементам Path).

Выражения мини-языка представляют собой довольно длинные строки, содержащие серии команд. Эти команды читаются преобразователем типа, создающим соответствующую геометрию. Каждая команда — это одна буква, за которой необязательно следуют несколько порций числовой информации (вроде координат X и Y), разделенных пробелами. Каждая команда также отделяется пробелом от предыдущей. Например, в одной из предыдущих статей был описан базовый треугольник в виде замкнутого пути из двух прямолинейных сегментов. Вот какая разметка для этого понадобилась:

<Path Stroke="Blue">
   <Path.Data>
      <PathGeometry>
         <PathFigure IsClosed="True" StartPoint="10,100">
            <LineSegment Point="100, 100" />
            <LineSegment Point = "100, 50" />
         </PathFigure>
      </PathGeometry>
   </Path.Data>
</Path>

Чтобы продублировать эту фигуру с применением мини-языка, придется написать следующее:

<Path Stroke="Blue" Data="M 10,100 L 100,100 L 100,50 Z"/>

Этот путь использует последовательность из четырех команд. Первая команда (М) создает PathFigure и устанавливает начальную точку в (10, 100). Следующие две команды (L) создают прямолинейные сегменты. Заключительная команда (Z) завершает PathFigure и устанавливает свойство IsClosed в true. Команды в этой строке необязательны, как и пробелы между командами и их параметрами, однако должен присутствовать как минимум один пробел между соседними параметрами и командами. Это значит, что синтаксис может быть дополнительно сокращен до следующей менее читабельной формы:

<Path Stroke="Blue" Data="M10 100 L100 100 L100 50 Z"/>

При создании геометрии с применением мини-языка в действительности создается объект StreamGeometry, а не PathGeometry. В результате модифицировать эту геометрию позже в коде нельзя. Если это неприемлемо, можно создать PathGeometry явно, но использовать тот же синтаксис, что и при определении коллекции объектов PathFigure:

<Path Stroke="Blue">
   <Path.Data>
      <PathGeometry Figures="M 10,100 L 100,100 L 100,50 Z" />
   </Path.Data>
</Path>

Мини-язык геометрии очень легко выучить. В нем определен весьма небольшой набор команд, которые перечислены в таблице. Параметры выделены курсивом:

Команды мини-языка геометрий
Команда Описание
F значение Устанавливает свойство Geometry.FillRule. Используйте 0 для EvenOdd или 1 для NonZero. Эта команда должна располагаться в начале строки (если решено ее применять)
M х,у Создает новый объект PathFigure для геометрии и устанавливает его начальную точку. Эта команда должна использоваться перед любой другой за исключением F. Однако можно также использовать ее внутри последовательности рисования, чтобы переместить начало координатной системы (M означает "move" (переместить))
L х,у Создает сегмент LineSegment до указанной точки
Н х Создает горизонтальный сегмент LineSegment, используя указанное значение X и сохраняя неизменным Y
V у Создает вертикальный сегмент LineSegment, используя указанное значение Y и сохраняя неизменным X
A radiusX, radiusY degrees isLargeArc, isClockwise x,y Создает сегмент ArcSegment до указанной точки. Понадобится указать радиусы эллипса, описывающего дугу, угол дуги в градусах и булевские флаги, устанавливающие ранее описанные свойства IsLargeArc и SweepDirection
С x1,y1,x2,y2,x,y Создает сегмент BezierSegment до указанной точки, используя опорные точки в (x1,y1) и (х2,у2)
Q x1, y1 x,y Создает сегмент QuadraticBezierSegment до указанной точки, с одной опорной точкой (x1,y1)
S x2, y2, x, у Создает гладкий сегмент BezierSegment до указанной точки, с одной опорной точкой (x1,y1)
Z Завершает текущую фигуру PathFigure и устанавливает свойство IsClosed в true. Если не хотите устанавливать IsClosed в true, то не используйте эту команду. Вместо нее применяйте команду M, если нужно начать новую фигуру PathFigure или завершить строку

Существует еще один трюк, касающийся мини-языка геометрии. Если записать команду в нижнем регистре, то ее параметры будут трактоваться относительно предыдущей точки, а не как абсолютные координаты.

Пройди тесты
Лучший чат для C# программистов