Двухмерная графика

Последнее обновление: 1.11.2015

Одним из способов построения двухмерной графики в окне - это использование фигур. Фигуры фактически являются обычными элементами как например кнопка или текстовое поле. К фигурам относят такие элементы как Polygon (Многоугольник), Ellipse (представляет собой эллипс), Rectangle (прямоугольник), Line (обычная линия), Polyline - включает несколько линий. Все они наследуются от класса Shape, который определяет ряд общих свойств:

  • Fill заполняет фон фигуры с помощью кисти - аналогичен свойству Background у прочих элементов

  • Stroke задает кисть, которая отрисовывает границу фигуры - аналогичен свойству BorderBrush у прочих элементов

  • StrokeThikness задает толщину границы фигуры - аналогичен свойству BorderThikness у прочих элементов

  • StrokeStartLineCap и StrokeEndLineCap задают для незамкнутых фигур (Line) контур в начале и в конце линии соответственно

  • StrokeDashArray задает границу фигуры в виде штриховки, создавая эффект пунктира

  • StrokeDashOffset задает расстояние до начала штриха

  • StrokeDashCap задает форму штрихов

  • Stretch устанавливает способ заполнения внешнего контейнера

  • GeometryTransform применяет преобразования к объекту Geometry

Ну и как обычные элементы управления они поддерживают традиционные свойства типа Width и Height, а также события, например, Сlick.

Линия (Line) задается с помощью двух координат по оси Х и двух координат по оси У:

<Line Stroke="Red" X1="10" X2="210" Y1="50" Y2="50" />

Элемент Polyline задается с помощью нескольких точек:

<Polyline Points="10,10 50,50 120,10 10,10" Stroke="Red" />

Элемент Polygon (Многоугольник) задается также как и Polyline с помощью нескольких точек, однако при этом первая и последняя точка соединяются между собой, образуя замкнутую линию:

<Polygon Points="10,80 50,50 120,80" Stroke="Red" StrokeThickness="3" StrokeDashArray="1 1 5" />

Элементы Ellipse и Rectangle задаются с помощью свойств Width и Height:

	<Rectangle Width="60" Height="40" Fill="Beige"  />
	<Ellipse Width="30" Height="30" Fill="Red"  />
	

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

            Ellipse el = new Ellipse();
            el.Width = 50;
            el.Height = 50;
            el.VerticalAlignment = VerticalAlignment.Top;
            el.Fill = new SolidColorBrush(Colors.Green);
            el.Stroke = new SolidColorBrush(Colors.Red);
            el.StrokeThickness = 3;
            LayoutRoot.Children.Add(el);

Нарисуем, к примеру, координатную плоскость:

            Line vertL =new Line();
            vertL.X1 = 10;
            vertL.Y1 = 150;
            vertL.X2 = 10;
            vertL.Y2 = 10;
            vertL.Stroke = new SolidColorBrush(Colors.Black);
            LayoutRoot.Children.Add(vertL);
            Line horL =new Line();
            horL.X1 = 10;
            horL.X2 = 150;
            horL.Y1 = 150;
            horL.Y2 = 150;
            horL.Stroke =  new SolidColorBrush(Colors.Black);
            LayoutRoot.Children.Add(horL);
            for(byte i = 2;i< 15;i++)
            {
                Line a =new Line();
                a.X1 = i * 10;
                a.X2 = i * 10;
                a.Y1 = 155;
                a.Y2 = 145;
                a.Stroke =  new SolidColorBrush(Colors.Black);
                LayoutRoot.Children.Add(a);
            }
            for(byte i = 2;i< 15;i++)
            {
                Line a =new Line();
                a.X1 = 5;
                a.X2 = 15;
                a.Y1 = i * 10;
                a.Y2 = i * 10;
                a.Stroke = new SolidColorBrush(Colors.Black);
                LayoutRoot.Children.Add(a);
            }
            Polyline vertArr =new Polyline();
            vertArr.Points = new PointCollection();
            vertArr.Points.Add(new Point(5, 15));
            vertArr.Points.Add(new Point(10, 10));
            vertArr.Points.Add(new Point(15, 15));
            vertArr.Stroke = new SolidColorBrush(Colors.Black);
            LayoutRoot.Children.Add(vertArr);
            Polyline horArr =new Polyline();
            horArr.Points = new PointCollection();
            horArr.Points.Add(new Point(145, 145));
            horArr.Points.Add(new Point(150, 150));
            horArr.Points.Add(new Point(145, 155));
            horArr.Stroke = new SolidColorBrush(Colors.Black);
            LayoutRoot.Children.Add(horArr);

Фигуры удобны для создания самых простейших рисунков, дизайна, однако что-то более сложное и комплексное с их помощью сделать труднее. Поэтому для этих целей применяется клас Path. Он также, как и фигуры, наследуется от класса Shape, но представляет собой совокупность объединенных фигур. Класс Path имеет свойство Data, которое определяет объект Geometry - геометрический объект для отрисовки. Этот объект задает фигуру или совукупность фигур для отрисовки.

Класс Geometry - абстрактный, поэтому в качестве объекта используется один из производных классов:

  • LineGeometry представляет линию, эквивалент фигуры Line

  • RectangleGeometry представляет прямоугольник, эквивалент фигуры Rectangle

  • EllipseGeometry представляет эллипс, эквивалент фигуры Ellipse

  • PathGeometry представляет путь, образующий сложную геометрическую фигуру из простейших фигур

  • GeometryGroup создает фигуру, состоящую из нескольких объектов Geometry

Пример использования объектов Geometry:

<Path Stroke="Red" Fill="LightBlue">
            <Path.Data>
                <GeometryGroup FillRule="EvenOdd">
                    <LineGeometry StartPoint="10,10" EndPoint="220,10" />
                    <EllipseGeometry Center="100,100" RadiusX="50" RadiusY="40" />
                    <RectangleGeometry Rect="120,100 80,20" RadiusX="5" RadiusY="5" />
                </GeometryGroup>
            </Path.Data>
</Path>

В данном случае свойство объекта GeometryGroup FillRule равно EvenOdd (значение по умолчанию), что позволяет создавать прозрачные перекрывающие поверхности. Если же установить FillRule="Nonzero", то перекрывающиеся поверхности геометрий будут окрашены также, как и остальные части пути.

Общим свойством для всех геометрий является свойство Transform, которое позволяет задавать трансформацию для данной геометрии (в данном случае мы осуществляем поворот):

<RectangleGeometry Rect="10,10 80,20" RadiusX="5" RadiusY="5">
                <RectangleGeometry.Transform>
                        <RotateTransform Angle="45" CenterX="20" CenterY="20" />
                </RectangleGeometry.Transform>
</RectangleGeometry>

PathGeometry содержит один или несколько компонентов PathFigure. Объект PathFigure в свою очередь формируется из сегментов. Все сегменты наследуются от класса PathSegment и бывают нескольких видов:

  • LineSegment задает отрезок прямой линии между двумя точками

  • ArcSegment задает дугу

  • BezierSegment задает кривую Безье

  • QuadraticBezierSegment задает квадратичную кривую Безье

  • PolyLineSegment задает сегмент из нескольких линий

  • PolyBezierSegment задает сегмент из нескольких кривых Безье

  • PolyQuadraticBezierSegment задает сегмент из нескольких квадратичных кривых Безье

Эти сегменты составляют свойство Segment объекта PathFigure. Кроме того, PathFigure имеет еще несколько важных свойств:

  • StartPoint - точка начала первой фигуры

  • IsClosed - если значение равно true, то первая и последняя точки (если они не совпадают) соединяются

  • IsFilled - если значение равно true, то площадь внутри пути окрашивается кистью, заданной свойством Fill у объекта Path

Пример использования:

     <Path Stroke="Red">
            <Path.Data>
                <PathGeometry>
                    <PathFigure StartPoint="10,100">
                        
                        <BezierSegment Point1="30,120" Point2="30,140" Point3="10 160" />
                        <LineSegment Point="40,100" />
                        <LineSegment Point="40,160" />
                        <LineSegment Point="60,100" />
                        <BezierSegment Point1="40,120" Point2="40 140" Point3="60,160" />
                    </PathFigure>
                    <PathFigure StartPoint="20,130">
                        <LineSegment Point="50,130" />
                    </PathFigure>
                    <PathFigure StartPoint="20,130">
                        <LineSegment Point="50,130" />
                    </PathFigure>
                    <PathFigure StartPoint="100,100">
                        <PolyLineSegment Points="70,100 70,130" />
                        <PolyLineSegment Points="90,130 70,130 70,160,100,160" />
                    </PathFigure>
                    <PathFigure StartPoint="110,100">
                        <PolyLineSegment Points="110,160 110,130 140,130 140,100 140,100 140,165" />
                    </PathFigure>
                    <PathFigure StartPoint="180,100" IsClosed="True">
                        <ArcSegment Point="180,130" Size="70,20" SweepDirection="Counterclockwise" />
                        <PolyLineSegment Points="160,160  180,130 180,160" />
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>

Если переписать пример с координатной плоскостью с использованием объекта PathGeometry, то получится

	  PathGeometry pathGeom =new PathGeometry();
            Path p =new Path();

            LineSegment vertLS =new LineSegment();
            PathFigure vertPF =new PathFigure();
            vertPF.StartPoint = new Point(10, 150);
            vertLS.Point = new Point(10, 10);
            vertPF.Segments.Add(vertLS);
            pathGeom.Figures.Add(vertPF);

            LineSegment horLS =new LineSegment();
            PathFigure horPF =new PathFigure();
            horPF.StartPoint = new Point(10, 150);
            horLS.Point = new Point(150, 150);
            horPF.Segments.Add(horLS);
            pathGeom.Figures.Add(horPF);


            for(byte i = 2;i<15;i++)
            {
                PathFigure pf =new PathFigure();
                pf.StartPoint = new Point(i * 10, 155);
                LineSegment a =new LineSegment();
                a.Point = new Point(i * 10, 145);
                pf.Segments.Add(a);
                pathGeom.Figures.Add(pf);
            }

            for(byte i = 2;i<15;i++)
            {
                PathFigure pf =new PathFigure();
                pf.StartPoint = new Point(5, i * 10);
                LineSegment a =new LineSegment();
                a.Point = new Point(15, i * 10);
                pf.Segments.Add(a);
                pathGeom.Figures.Add(pf);
            }

            PolyLineSegment vertArr =new PolyLineSegment();
            vertArr.Points = new PointCollection();
            vertArr.Points.Add(new Point(10, 10));
            vertArr.Points.Add(new Point(15, 15));
            PathFigure vertArrF =new PathFigure();
            vertArrF.StartPoint = new Point(5, 15);
            vertArrF.Segments.Add(vertArr);
            pathGeom.Figures.Add(vertArrF);

            PolyLineSegment horArr =new PolyLineSegment();
            horArr.Points = new PointCollection();
            horArr.Points.Add(new Point(150, 150));
            horArr.Points.Add(new Point(145, 155));
            PathFigure horArrF =new PathFigure();
            horArrF.StartPoint = new Point(145, 145);
            horArrF.Segments.Add(horArr);
            pathGeom.Figures.Add(horArrF);

            p.Data = pathGeom;
            p.Stroke = new SolidColorBrush(Colors.Black);

            LayoutRoot.Children.Add(p);

Также принят упрощенный вариант записи фигур. Например, следующее описание фигуры

<Path Stroke="Red">
    <Path.Data>
        <PathGeometry>
			<PathFigure StartPoint="20,170">
				<LineSegment Point="50,170" />
			</PathFigure>
		</PathGeometry>
    </Path.Data>
</Path>

можно написать следубщим образом

<Path Data="M 20,170 L 50,170 Z" Stroke="Red" />

Что в данном случае означате сокращенная запись?

M x,y

Создает новый объект PathFigure и указывает на его начальную точку

Z

Завершает фигуру и устанавливает свойство IsClosed в true. Если же не требуется завершать фигуру, то вместо Z употребляется буква M

L x,y

Создает объект LineSegment до указанной точки

A raduisX, radiusY, degrees, isLargArc, IaClockwize, x,y

Создает новый объект ArcSegment с соответствующими параметрами

С x1,y1,x2,y2,x,y

Создает новый объект BezierSegment по указанным точкам

Q x1,y1, x,y

Создает новый объект QuadraticBezierSegment по указанным точкам

S x1,y1, x,y

Создает новый объект BezierSegment по указанным точкам

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850