private: System::Void pictureBox1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {
Rectangle myRect = Rectangle(20,10,200,40);
LinearGradientBrush^ myBrush =
gcnew LinearGradientBrush(myRect,Color::Red,Color::White,0.0f,true);
e->Graphics->FillRectangle(myBrush, myRect);
// изменить цвет
array<Color>^ nc; // nc — NewColor
nc = gcnew array<Color>(2);
nc[0] = Color::Green;
nc[1] = Color::Yellow;
myBrush->LinearColors = nc;
// Так как будем закрашивать область другого размера,
// то надо изменить размер градиентной кисти
array<Point>^ transformArray ={Point(20,60),Point(420,60),Point(20,100)};
Matrix^ myMatrix = gcnew Matrix(myRect,transformArray);
myBrush->MultiplyTransform(myMatrix, MatrixOrder::Prepend);
// рисуем новой кистью
e->Graphics->FillRectangle(myBrush, 20, 60, 400, 40);
// восстановить размер кисти
myBrush->ResetTransform();
// рисуем область такого же размера, как и первую
e->Graphics->FillRectangle(myBrush, 20, 120, 200, 40);
}
Рис. 1. 7 Результат создания и изменения градиентной кисти
Графические примитивы
Любая картинка, чертеж, схема представляет собой совокупность графических примитивов: точек, линий, окружностей, дуг, текста и др.
Вычерчивание графических примитивов на графической поверхности (Graphics) выполняют соответствующие методы (табл. 1.6).
Табл.1.6 Некоторые методы вычерчивания графических примитивов
Метод | Действие |
DrawLine(Pen, x1, y1, x2, y2), DrawLine(Pen, p1, p2) | Рисует линию. Параметр Pen определяет цвет, толщину и стиль линии; параметры x1, y1, x2, y2 или p1 и p2 — координаты точек начала и конца линии |
DrawRectangle(Pen, x, y, w, h) | Рисует контур прямоугольника. Параметр Pen определяет цвет, толщину и стиль границы прямоугольника: параметры x, y– координаты левого верхнего угла; параметры w и h за-дают размер прямоугольника |
FillRectangle(Brush, x, y, w, h) | Рисует закрашенный прямоугольник. Параметр Brush определяет цвет и стиль закраски прямоугольника; параметры x, y – координаты левого верхнего угла; параметры w и h задают размер прямоугольника |
DrawEllipse(Pen, x, y, w, h) | Рисует эллипс (контур). Параметр Pen определяет цвет, толщину и стиль линии эллипса; параметры x, y, w, h – координаты левого верхнего угла и размер прямоугольника, внутри которого вычерчивается эллипс |
FillEllipse(Brush, x, y, w, h) | Рисует закрашенный эллипс. Параметр Brush определяет цвет и стиль закраски внутренней области эллипса; параметры x, y, w, h – координаты левого верхнего угла и размер прямоугольника, внутри которого вычерчивается эллипс |
DrawPolygon(Pen, P) | Рисует контур многоугольника. Параметр Pen определяет цвет, толщину и стиль линии границы многоугольника; параметр P (массив типа Point) — координаты углов многоугольника |
FillPolygon(Brush, P) | Рисует закрашенный многоугольник. Пара-метр Brush определяет цвет и стиль закраски внутренней области многоугольника; пара-метр P (массив типа Point) – координаты углов многоугольника |
DrawString(str, Font, Brush, x, y) | Выводит на графическую поверхность строку текста. Параметр Font определяет шрифт; Brush – цвет символов; x и y – точку, от ко-торой будет выведен текст |
DrawImage(Image, x, y) | Выводит на графическую поверхность иллюстрацию. Параметр Image определяет иллюстрацию; x и y – координату левого верхнего угла области вывода иллюстрации |
Один и тот же элемент можно нарисовать при помощи разных, но имеющих одинаковые имена методов (вспомните: возможность объявления функций, имеющих одинаковые имена, но разные параметры, называется перегрузкой).
Например, прямоугольник можно нарисовать методом DrawRectangle, которому в качестве параметров передаются координаты левого верхнего угла и размеры прямоугольника:
e->Graphics->DrawRectangle(Pens::Black, x, x, w, h)
Эту же задачу может решить метод DrawRectangle, которому в качестве параметра передается структура типа Rectangle, поля которой определяют прямоугольник (положение и размер):
Rectangle aRect = Rectangle(20,100,50,50);
e->Graphics->DrawRectangle(Pens::Blue, aRect);
Существование нескольких методов, выполняющих одну и ту же задачу, позволяет программисту выбрать метод, наиболее подходящий для решения конкретной задачи.
В качестве параметров методов вычерчивания графических примитивов часто используется структура Point. Ее поля X и Y определяют положение (координаты) точки графической поверхности. Например:
Point p1 = Point(10,10);
Point p2 = Point(100,10);
// рисуем линию из p1 в p2
e->Graphics->DrawLine(Pens::Green, p1, p2);
Линия
Метод DrawLine рисует прямую линию. В инструкции вызова метода следует указать карандаш, которым надо нарисовать линию, и координаты точек начала и конца линии:
DrawLine(aPen, x1, y1, x2, y2)
или
DrawLine(aPen, p1, p2)
Параметр aPen (типа Brush) задает карандаш, которым рисуется линия, x1 и y1 или p1 — точку начала линии, а x2 и y2 или p2 — точку конца линии. Параметры x1, y1, x2 и y2 должны быть одного типа (Integer или Single). Тип параметров p1 и p2 — Point.
Например, инструкция
e->Graphics->DrawLine(Pens::Green,10,10,300,10
рисует зеленую линию толщиной в один пиксел из точки (10, 10) в точку (300, 10).
Эту же линию можно нарисовать и так:
Point p1 = Point(10,10);
Point p2 = Point(300,10);
e->Graphics->DrawLine(Pens::Green, p1, p2);
Программа "График" (ее окно приведено на рис. 1.8, а текст — в листинге 1.7) показывает использование метода DrawLine. Данные, отображаемые в окне программы, загружаются из текстового файла.
Загружает данные из файла конструктор формы (файл данных должен находиться в папке приложения, при запуске программы в режиме отладки из среды разработки — в папке Debug). Он же выполняет обработку массива данных – ищет минимальный и максимальный элементы ряда. Конструктор также, в случае успешной загрузки данных, задает функцию обработки собы-тия Paint формы. Непосредственно вывод графика на поверхность формы выполняет функция drawDiagram. Ее вызывает функция обработки события Paint формы, а также косвенно (путем вызова метода Refresh) — функция обработки события Resize формы.
Рис. 1. 8 Программа "График"
Листинг 1.7. График
public ref class Form1: public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
// чтение данных из файла в массив
System::IO::StreamReader^ sr; // поток для чтения
try
{
sr = gcnew System::IO::StreamReader(
Application::StartupPath + "\\usd.dat");*/
// создаем массив
d = gcnew array<double>(10);
// читаем данные из файла
int i = 0;
String^ t = sr->ReadLine();
while ((t!= String::Empty) && (i < d->Length))
for(int i=0;i<10;i++)
{
// записываем считанное число в массив
d[i++] = Convert::ToDouble(i);
//t = sr->ReadLine();
}
// закрываем поток
sr->Close();
// определить минимальное и максимальное значения ряда
min = d[0];
max = d[0];
for (int i = 1; i < d->Length; i++)
{
if (d[i] > max) max = d[i];
if (d[i] < min) min = d[i];
}
// Данные загружены.
// Задаем функцию обработки события Paint
this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this,&Form1::drawDiagram);
}
// Обработка исключений: файл данных не найден
catch (System::IO::FileNotFoundException^ ex)
{
MessageBox::Show(ex->Message + "\n",
"График",
MessageBoxButtons::OK,
MessageBoxIcon::Error);
}
}
protected:
~Form1()
{
if (components)
{
delete components;
}
}
private:
System::ComponentModel::Container ^components;
array<double>^ d; // ряд данных
double max; // максимальный элемент массива
double min; // минимальный элемент массива
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 262);
this->Name = L"Form1";
this->Text = L"Form1";
this->Resize += gcnew System::EventHandler(this, &Form1::Form1_Resize);
this->ResumeLayout(false);
}
#pragma endregion
// строим график
void drawDiagram(System::Object^ sender,
System::Windows::Forms::PaintEventArgs^ e)
{
// графическая поверхность
System::Drawing::Graphics^ g = e->Graphics;
// шрифт подписей данных
System::Drawing::Font^ dFont =gcnew System::Drawing::Font("Tahoma", 9);
// шрифт заголовка
System::Drawing::Font^ hFont =
gcnew System::Drawing::Font("Tahoma", 13, FontStyle::Regular);
String^ header = "Изменение курса доллара";
// ширина области отображения текста
int wh =(int)g->MeasureString(header, hFont).Width;
int x = (this->ClientSize.Width - wh) / 2;
//g->DrawString(header,hFont, Brushes::DarkGreen, x, 5);
/* Область построения графика.
Отступы: сверху — 100;
снизу — 20;
слева — 20;
справа — 20.
ClientSize — размер внутренней области окна
График строим в отклонениях от минимального значения
ряда данных так, чтобы он занимал всю область построения
*/
// рисуем график
int x1, y1, x2, y2;
// расстояние между точками графика (шаг по Х)
int sw = (int)((this->ClientSize.Width - 40) /(d->Length - 1));
// первая точка
x1 = 20;
y1 = this->ClientSize.Height - 20 -(int)((this->ClientSize.Height - 100) *(d[0] - min) / (max - min));
// маркер первой точки
g->DrawRectangle(Pens::Black, x1 - 2, y1 - 2, 4, 4);
// подпись численного значения первой точки
g->DrawString(Convert::ToString(d[0]),dFont, Brushes::Black, x1 - 10, y1 - 20);
// остальные точки
for (int i = 1; i < d->Length; i++)
{
x2 = 8 + i * sw;
y2 = this->ClientSize.Height - 20 -(int)((this->ClientSize.Height - 100) *(d[i] - min) / (max - min));
// маркер точки
g->DrawRectangle(Pens::Black, x2 - 2, y2 - 2, 4, 4);
// соединим текущую точку с предыдущей
g->DrawLine(Pens::Black, x1, y1, x2, y2);
// подпись численного значения
g->DrawString(Convert::ToString(d[i]),
dFont, Brushes::Black, x2 - 10, y2 - 20);
x1 = x2;
y1 = y2;
}
}
private: System::Void Form1_Resize(System::Object^ sender, System::EventArgs^ e) {
this->Refresh();
}
};
}
Замечание: Листинг программы имеет ошибки, их необходимо исправить. Кроме того, добавить файл, содержащий необходимую информацию.
Ломаная линия
Метод DrawLines рисует ломаную линию. В качестве параметров методу передается карандаш (Pen) и массив типа Point, элементы которого содержат координаты узловых точек линии. Метод рисует ломаную линию, последовательно соединяя точки, координаты которых находятся в массиве: первую со второй, вторую с третьей, третью с четвертой и т. д. Например, следующий фрагмент кода рисует ломаную линию, состоящую из четырех звеньев.
array <Point>^ p; // массив точек
p = gcnew array<Point>(5);
p[0].X = 10; p[0].Y =50;
p[1].X = 20; p[1].Y =20;
p[2].X = 30; p[2].Y =50;
p[3].X = 40; p[3].Y =20;
p[4].X = 50; p[4].Y =50;
e->Graphics->DrawLines(Pens::Green,p);
Метод DrawLines можно использовать для вычерчивания замкнутых контуров. Для этого первый и последний элементы массива должны содержать координаты одной и той же точки.
Прямоугольник
Метод DrawRectangle чертит прямоугольник (рис. 4.5). В качестве параметров метода надо указать карандаш, координаты левого верхнего угла и размер прямоугольника:
DrawRectangle(aPen, x, y, w, h);
Рис. 1. 9 Метод DrawRectangle рисует прямоугольник
Вместо четырех параметров, определяющих прямоугольник, можно указать структуру типа Rectangle:
DrawRectangle(aPen, aRect);
Поля X и Y структуры aRect задают координаты левого верхнего угла прямо-угольника, а Width и Height — размер (ширину и высоту).
Вид линии границы прямоугольника (цвет, стиль и ширину) определяет параметр aPen, в качестве которого можно использовать один из стандартных карандашей или карандаш, созданный программистом.
Метод FillRectangle рисует закрашенный прямоугольник. В качестве пара-метров методу надо передать кисть, координаты левого верхнего угла и размер прямоугольника:
FillRectangle(aBrush, x, y, w, h);
Вместо x, y, w и h можно указать структуру типа Rectangle:
FillRectangle(aBrush, aRect);
Параметр aBrush, в качестве которого можно использовать стандартную или созданную программистом штриховую (HatchBrush), градиентную (LineadGradientBrush) или текстурную (TextureBrush) кисть, определяет цвет и стиль закраски области.
Далее приведен фрагмент кода (процедуры обработки события Paint), который демонстрирует использование методов DrawRectangle и FillRectangle.
Rectangle aRect; // положение и размер прямоугольника
// Зеленый прямоугольник размером 60х30,
// левый верхний угол которого в точке (10, 10)
aRect = Rectangle(10,10,60,30); // положение и размер
e->Graphics->FillRectangle(Brushes::ForestGreen, aRect);
// Желтый прямоугольник с черной границей размером 60х30,
// левый верхний угол которого в точке (100, 10)
aRect.X = 100;
e->Graphics->FillRectangle(Brushes::Gold, aRect); // прямоугольник
e->Graphics->DrawRectangle(Pens::Black, aRect); // граница
Точка
Казалось бы, чего проще — нарисовать на графической поверхности точку.Но у объекта Graphics нет метода, который позволяет это сделать. Метод SetPixel есть у объекта Bitmap. Поэтому если действительно необходимо сформировать картинку из точек, придется создать объект Bitmap, сформиро вать на его поверхности изображение, а затем это изображение при помощи метода DrawImage вывести на графическую поверхность. Но можно поступить проще — вместо точки вывести квадрат размером в один пиксел.
Например, инструкция
e->Graphics->FillRectangle(Brushes::Red,x,y,1,1);
рисует на графической поверхности красную точку.
Многоугольник
Метод DrawPolygon чертит многоугольник (контур). Инструкция вызова метода в общем виде выглядит так:
DrawPolygon(aPen, p)
Параметр p — массив типа Point, определяет координаты вершин много-угольника. Метод DrawPolygon чертит многоугольник, соединяя прямыми линиями точки, координаты которых находятся в массиве: первую со второй, вторую с третьей и т. д. Последняя точка соединяется с первой. Вид границы многоугольника определяет параметр aPen, в качестве которого можно использовать стандартный или созданный программистом карандаш.
Закрашенный многоугольник рисует метод FillPolygon. Инструкция вызова метода в общем виде выглядит так:
FillPolygon(aBrush, p)
Параметр aBrush, в качестве которого можно использовать стандартную или созданную программистом штриховую (HatchBrush), градиентную (LineadGradientBrush) или текстурную (TextureBrush) кисть, определяет цвет и стиль закраски внутренней области многоугольника.
Далее приведен фрагмент кода, который демонстрирует использование мето дов DrawPolygon и FillPolygon - рисует корону.
array <Point>^ p;
p = gcnew array <Point>(5);
p[0].X = 10; p[0].Y =30;
p[1].X = 10; p[1].Y =10;
p[2].X = 30; p[2].Y =20;
p[3].X = 50; p[3].Y =10;
p[4].X = 50; p[4].Y =30;
e->Graphics->FillPolygon(Brushes::Gold, p);
e->Graphics->DrawPolygon(Pens::Black,p);
Задания.
1. Набрать коды всех листингов, находящихся в теоретической части работы, уметь комментировать их.
2. Построить фигуру, соответствующую Вашему варианту:
Вариант | Фигура |
1. | Ромб |
2. | Стрелка влево |
3. | Фигура в виде буквы W |
4. | Стрелка вниз |
5. | Фигура в виде буквы Н |
6. | Фигура в виде буквы F |
7. | Правильный пятиугольник |
8. | Правильный восьмиугольник |
9. | Фигура в виде буквы П |
10. | Правильный семиугольник |
11. | Фигура в виде буквы Ш |
12. | Трапеция |
13. | Стрелка вправо |
14. | Параллелограмм |
15. | Фигура в виде буквы И |
16. | Правильный шестиугольник |
17. | Стрелка вверх |
18. | Фигура в виде 8 |
19. | Фигура в виде 4 |
20. | Фигура в виде 9 |
21. | Квадрат в квадрате |
22. | Песочные часы |
23. | Правильный пятиугольник |
24. | Фигура в виде цифры 5 |
25. | Фигура в виде цифры 3 |