- •1. Цель работы
- •2. Сведения из теории
- •2.2. Пространство имен System.Drawing. Служебные типы
- •2.3. Сеансы вывода графики. Класс Graphics
- •2.5. Графический вывод текста. Работа со шрифтами
- •2.6. Рисование графиков функций
- •3. Пример выполнения работы
- •3.1. Визуальное проектирование диалогового окна
- •3.2. Проектирование программного кода
- •4. Варианты заданий для самостоятельной работы
3. Пример выполнения работы
Задание. Построить график функции y = e-4x|cos(15x)|. Самостоятельно выбрать удобные параметры настройки. Пользователь задает количество точек графика, коэффициент упругости, а также шрифт для подписей осей координат.
3.1. Визуальное проектирование диалогового окна
Внешний вид окна приложения с описанием используемых компонентов приведен на рисунке 5.2.
Счетчик PointsNumeric-UpDown
Счетчик TensitionNume-ricUpDown Кнопка FontButton Кнопка GraphicButton Графическая
панель pictureBox1 Кнопка ExitButton
Рис. 5.2. Внешний вид приложения
Для графической панели pictureBox1 устанавливаются следующие дополнительные свойства:
|
Свойство |
Значение |
Описание |
|
BorderStyle |
Fixed3D |
Стиль границы |
|
BackColor |
White |
Цвет фона |
Коэффициент упругости графика может принимать значение в диапазоне от 0 до 1. Поэтому для счетчика TensitionNumericUpDown устанавливаются следующие свойства:
|
Свойство |
Значение |
Описание |
|
Minimum |
0 |
Минимальное значение |
|
Maximum |
1 |
Максимальное значение |
|
Increment |
0,1 |
Шаг инкремента |
|
DecimalPlaces |
1 |
Количество знаков после запятой |
Также на форму нужно поместить компонент FontDialog (диалоговое окно выбора шрифта), для которого следует установить в true свойство ShowColor. Благодаря этому свойству в окне можно будет выбирать не только характеристики шрифта, но и его цвет. При желании можно также изменить шрифт по умолчанию (свойство Font).
3.2. Проектирование программного кода
Для обеспечения графического вывода данному приложению понадобятся кисть и шрифт. Поэтому в класс формы необходимо добавить объекты классов Font (шрифт) и SolidBrush (сплошная кисть):
Font font;
SolidBrush brush;
Создание этих объектов может производиться в обработчике события Load или в конструкторе формы:
//шрифт берем установленный по умолчанию
font = fontDialog1.Font;
//создаем сплошную кисть черного цвета
brush = new SolidBrush(Color.Black);
При нажатии на кнопку «Выбрать шрифт» на экране должно появляться соответствующее диалоговое окно. Если после выбора настроек шрифта пользователь нажимает кнопку OK, то выбранные установки должны передаться объектам font и brush:
private void FontButton_Click(object sender, EventArgs e)
{
//если выбор шрифта завершен нажатием кнопки OK
if (fontDialog1.ShowDialog() == DialogResult.OK)
{
//получить параметры шрифта из диалогового окна
font = fontDialog1.Font;
//получить цвет шрифта из того же окна
brush.Color = fontDialog1.Color;
}
}
Функцию, для которой будет рисоваться график, можно задать отдельно:
private double f(double x)
{
return Math.Exp(-4 * x) * Math.Abs(Math.Cos(15 * x));
}
Обработчик нажатия кнопки «Нарисовать график» состоит из нескольких частей:
описание и инициализация вспомогательных переменных, задающих начало координат, масштабы по осям x и y, а также число точек графика;
создание и инициализация графического объекта;
создание и заполнение массива точек, по которым будет строиться график, при этом производится преобразование физических координат точек в экранные с учетом значений масштабов;
непосредственно рисование графика и осей координат;
разметка оси x с выводом числовых значений.
Более подробное описание кода содержится в комментариях к листингу:
private void GraphicButton_Click(object sender, EventArgs e)
{
//Начало координат графика
int x0 = 15;
int y0 = (int)(pictureBox1.Height * 0.85);
//Масштаб по оси Х
int Mx = pictureBox1.Width - 2 * x0;
//Масштаб по оси Y
int My = -y0 + 10;
//Число точек графика
int M = (int)PointsNumericUpDown.Value;
//Создание графического объекта
Graphics G = pictureBox1.CreateGraphics();
//Очистка PictureBox1
G.Clear(Color.White);
//Описание и создание массива точек
Point[] p = new Point[M];
//Цикл по числу точек графика
for (int n = 0; n < M; n++)
{
//Физические координаты
double x = (double)n / M;
double y = f(x);
//Экранные координаты
int xi = (int)(x0 + Mx * x);
int yi = (int)(y0 + My * y);
//заносим в массив вычисленные значения координат
p[n] = new Point(xi, yi);
}
//коэффициент упругости графика
float tensition = (float)TensitionNumericUpDown.Value;
//рисование графика
G.DrawCurve(Pens.Blue, p, tensition);
//Рисование оси Х
G.DrawLine(Pens.Black, x0, y0, x0 + Mx, y0);
//Рисование оси Y
G.DrawLine(Pens.Black, x0, y0, x0, y0 + My);
//Разметка оси Х
for (int n = 0; n <= 10; n++)
{
//физическая координата штриха
double x = n / 10.0;
//экранная координата штриха
int xi = (int)(x0 + Mx * x);
//Наносим штрих
G.DrawLine(Pens.Black, xi, y0, xi, y0 + 4);
//Наносим число
G.DrawString(x.ToString(), font, brush, xi - 9, y0 + 4);
}
}
После создания данного обработчика при нажатии на кнопку «Нарисовать график» в компоненте PictureBox отображается график функции. Однако, если окно программы перекрыть другим окном или перетащить его (или только часть окна с графиком) за пределы экрана, а затем вернуть назад, то рисунок (или его часть) исчезнет. Происходит это из-за того, что каждый раз при появлении Windows-окна на экране его необходимо перерисовывать. Перерисовка самой формы и компонентов (кнопок, флажков и т.д.) производится автоматически операционной системой, а перерисовка всей выводимой в окне графики должна производиться программистом.
Если форма или какой-то компонент поврежден, генерируется событие Paint, которое и нужно обрабатывать для перерисовки. Сгенерировать событие Paint вручную можно с помощью метода Invalidate().
Таким образом, для данного приложения весь код рисования нужно перенести из обработчика щелчка кнопки «Нарисовать график» в обработчик события Paint компонента pictureBox1. При этом строка
Graphics G = pictureBox1.CreateGraphics();
заменяется на
Graphics G = e.Graphics;
т.е. графический объект для рисования мы получаем из параметра обработчика.
Обработчик кнопки «Нарисовать график» теперь будет содержать всего одну строчку – принудительный вызов перерисовки графической панели.
private void GraphicButton_Click(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
Теперь график будет выведен в панели постоянно: при запуске программы, при перекрытии окна, при нажатии кнопки (с новыми параметрами).
