Программирование >>  Вывод графики 

1 2 3 [ 4 ] 5 6 7 ... 19


Left и Right. Они описывают, соответственно, вертикальные координаты верхней и нижней границы прямоугольной области, а также горизонтальные координаты левой и правой ее граней.

Далее нам нужно решить, как проверять необходимость рисования. Это несложно. Вспомним, что у нас прямоугольник и эллипс целиком помещаются внутри прямоугольника, который распространяется от точки (0,0) до точки (80,130) клиентской области. В действительности даже до точки (82,132), так как мы знаем, что линии могут выйти на пиксель или два за границу. Поэтому нам нужно проверить, входит ли левый верхний угол области отсечения в пределы этого прямоугольника. Если это так, потребуется выполнить перерисовку. Если нет - можно не беспокоиться.

Код, делающий это, будет выглядеть следующим образом:

protected override void OnPaint( PaintEventArgs e )

base.OnPaint(e); Graphics dc = e.Graphics;

if (e.ClipRectangle.Top < l32 && e.ClipRectangle.Left < 82)

Pen bluePen = new Pen(Color.Blue, 3); dc.DrawRectangle(bluePen, 0,0,50,50); Pen redPen = new Pen(Color.Red, 2); dc.DrawEllipse(redPen, 0, 50, 80, 60);

Обратите внимание - то, что отображается, ничуть не изменилось. Однако производительность увеличена за счет раннего обнаружения тех случаев, когда ничего перерисовывать не нужно. Отметим также, что в данном примере используется довольно грубая проверка того, что должно быть перерисовано. Более тонкий подход должен был бы отдельно проверять необходимость перерисовки прямоугольника и эллипса. Однако пока этого достаточно. Можно усложнить проверки в коде OnPaint(), что увеличит производительность, но при этом собственно код OnPaint() усложнится. Почти всегда имеет смысл вставить какую-то проверку, потому что вы, как автор кода, понимаете гораздо больше в том, что нужно перерисовать, чем это понимает экземпляр Graphics, который слепо исполняет команды рисования.

Измерение координат и областей

В предыдущем примере мы столкнулись с базовой структурой Rectangle, используемой для представления координат прямоугольников. GDI+ в действительности применяет несколько подобных структур для представления координат или областей.

В табл. 33.2 перечислены структуры, определенные в пространстве имен

System.Drawing.

Таблица 33.2. Структуры, определенные в пространстве имен System.Drawing Структура Основные общедоступные свойства

Point X, Y

PointF X, Y

Size Width, Height

SizeF Width, Height

Rectangle Left, Right, Top, Bottom, Width, Height, X, Y, Location, Size

RectangleF Left, Right, Top, Bottom, Width, Height, X, Y, Location, Size



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

Point и PointF

Point - концептуально самая простая структура. Математически она эквивалентна двумерному вектору. Она содержит два общедоступных свойства, представляющих перемещение в горизонтальном и вертикальном направлениях от некоторой начальной позиции (возможно, на экране), как показано на рис. 33.3.

Точка A

20 единиц X

10 единиц

Точка B

Рис. 33.3. Структура Point

Чтобы попасть из точки A в точку B, мы перемещаемся на 20 единиц вправо и на 10 вниз, что отмечено на диаграмме координатами x и у, поскольку так их принято называть. Следующая структура Point в программе может быть представлена так:

Point ab = new Point(20, 10);

Console.WriteLine( Перемещение на {0} вправо, {1} вниз , ab.X, ab.Y);

X и Y - свойства, доступные как для чтения, так и для записи; это значит, что можно устанавливать значения Point следующим образом:

Point ab = new Point();

ab.X = 20; ab.Y = 10;

Console.WriteLine( Перемещение на {0} вправо, {1} вниз , ab.X, ab.Y);

Отметим, что хотя условно горизонтальная и вертикальная координаты обычно называют x и у (прописными буквами), соответствующие свойства Point называются X и Y (заглавными), поскольку в C# принято соглашение называть общедоступные свойства, начиная с заглавных букв.

Структура PointF, по сути, идентична Point, за исключением того, что X и Y имеют тип float вместо int. Структура PointF используется в тех случаях, когда координаты не обязательно являются целыми числами. Определено приведение, позволяющее неявно преобразовывать Point в PointF (напомним, что поскольку Point и PointF - структуры, это приведение включает копирование данных). Обратное преобразование не предусмотрено. Поэтому, чтобы конвертировать PointF в Point, необходимо копировать значения по отдельности либо применять один из трех методов округления: Round() , Truncate() или Celling() :

PointF abFloat = new PointF(2 0.5F, 10.9F); преобразование к Point Point ab = new Point();

ab.X = (int)abFloat.X; ab.Y = (int)abFloat.Y; Point ab1 = Point.Round(abFloat);



Point ab2 = Point.Truncate(abFloat); Point ab3 = Point.Ceiling(abFloat); обратное преобразование к PointF - явное PointF abFloat2 = ab;

У вас может возникнуть вопрос: в каких единицах могут выполняться измерения? По умолчанию GDI+ интерпретирует их как пиксели экрана (или принтера, если он может выводить графику); так методы объекта Graphics видят любые координаты, переданные им в качестве параметров. Например, точка new Point(20,10) описывает точку на экране, отстоящую от начала координат на 20 пикселей по горизонтали и на 10 по вертикали. Обычно пиксели измеряются от левого верхнего угла клиентской области окна, как это было во всех примерах, приведенных до сих пор. Однако так бывает не всегда. Например, может понадобиться рисовать относительно левого верхнего угла всего окна (включая рамки) или даже от левого верхнего угла всего экрана. Но в большинстве случаев, если только в документации не указано иначе, можно предположить, что отсчет пикселей идет от левого верхнего угла клиентской области окна.

Позднее вы узнаете об этом больше, когда мы будем рассматривать прокрутку, которая использует три разных системы координат - мировую (world), страничную (page) и систему координат устройства (device).

Size и SizeF

Подобно Point и PointF, размеры измеряются двумя способами. Структура Size применяется при использовании типов int, SizeF - при использовании float. В остальном Size и SizeF идентичны. В этом разделе внимание будет сосредоточено на структуре Size.

Во многих отношениях структура Size подобна Point. Она имеет два целочисленных свойства, представляющих расстояние по горизонтали и вертикали. Главное отличие в том, что вместо X и Y эти свойства называются Width и Height. Показанную ранее диаграмму можно представить таким кодом:

Size ab = new Size(20,10);

Console.WriteLine( Перемещение на {0} вдоль, {1} вниз , ab.Width, ab.Height);

Несмотря на то что структура Size математически представляет точно ту же вещь, что и Point, концептуально она предназначена для несколько отличающегося применения. Point применяется для описания местоположения чего-либо, а Size - для описания размера этого чего-либо. Однако поскольку Point и Size так тесно связаны, между ними поддерживается преобразование:

Point point = new Point(20, 10);

Size size = (Size) point; Point anotherPoint = (Point) size;

В качестве примера представим прямоугольник, который мы рисовали в предыдущих примерах, с координатами левого верхнего угла (0,0) и размерами (50,50). Размер прямоугольника (50,50) может быть представлен экземпляром Size. Правый нижний угол также имеет координаты (50,50), но он должен быть представлен экземпляром Point . Чтобы увидеть разницу, предположим, что мы нарисовали прямоугольник в другом месте, так что координаты его левого верхнего угла стали (10,10):

dc.DrawRectangle(bluePen, 10,10,50,50);

Теперь координаты нижнего правого угла будут (60,60), но размер не изменится и будет по-прежнему (50,50).

Операция сложения для структур Point и Size перегружена, так что можно добавлять Size к Point и получать в результате Point:



1 2 3 [ 4 ] 5 6 7 ... 19

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.121
При копировании материалов приветствуются ссылки.
Яндекс.Метрика