Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005
.pdf40 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
Листинг 15.2. Первая часть кода (выше шаблона pictureBox1_Paint).
//Параметры графика функции y = a*x + b //в виде глобальных переменных и функции: public: float a, b, x_min, x_max;
public: float Function_of_graph(float x)
{
//Функция y = f(x), график которой будем строить: float Function = a * x + b;
return Function;
}
Листинг 15.3. Вторая часть кода (выше шаблона pictureBox1_Paint).
//Число точек графика:
public: int static Npoints = 100; //Величины (в пикселах) O_x_pix и O_y_pix //для параллельного переноса
//осей "x" и "y" новой системы координат (по сравнению //со старой системой в верхнем левом углу PictureBox): public: float static O_x_pix = 500;
public: float static O_y_pix = 350;
//Масштабы по осям "x" и "y" (M_x и M_y) для перехода //от действительных значений к пикселам //и построения графика в пикселах:
public: float static M_x = 450; public: float static M_y = 300;
Листинг 15.4. Главный код построения графика функции на экране монитора.
//Шаг по оси абсцисс "x" между точками графика: float step_x;
step_x = (x_max-x_min)/Npoints; //Наибольшее абсолютное значение x_max_abs
//из двух концов заданного нами числового интервала
//x_min и x_max: float x_max_abs;
x_max_abs = Math::Abs(x_max);
if (x_max_abs < Math::Abs(x_min)) x_max_abs = Math::Abs(x_min);
//Промежуточные локальные переменные:
float x_0, y_0, x_1, y_1, x_0_pix, y_0_pix, x_1_pix, y_1_pix; //Расчет минимального y_min и максимального y_max //действительных значений функции:
Глава 15. График линейной функции |
41 |
float y_min, y_max;
//Присваиваем y_min, y_max значение y_0 //для нулевой точки (i=0):
x_0 = x_min;
y_0 = Function_of_graph(x_0); y_min = y_0;
y_max = y_0; int i;
//Организовываем цикл по всем точкам, начиная с i=1: for (i=1; i<=(Npoints-1); i++)
{
x_1 = x_min + i * step_x; y_1 = Function_of_graph(x_1);
//Расчет минимального и максимального //значений функции:
if (y_min > y_1) y_min = y_1; if (y_max < y_1) y_max = y_1;
}
//Т.к. в последней точке i = Npoints //значение x_1 = x_min + Npoints * step_x //может отличаться от заданного значения x_max //(из-за накопления погрешности в цикле), //то проверяем,
//может быть y_min или y_max находится в последней //точке при точном задании нами значения x_max: x_1 = x_max;
y_1 = Function_of_graph(x_1); //Проверка минимального и максимального //значений функции в последней точке: if (y_min > y_1) y_min = y_1;
if (y_max < y_1) y_max = y_1;
//Наибольшее абсолютное значение функции y_max_abs //из двух значений y_min и y_max:
float y_max_abs;
y_max_abs = Math::Abs(y_max);
if (y_max_abs < Math::Abs(y_min)) y_max_abs = Math::Abs(y_min);
//Строим сетку координат:
//Сначала строим ось абсцисс "x" от x = -1 до x = 1: //Задаем абсциссу последней точки оси абсцисс "x" //при x = 1:
float x_point_end, x_point_end_pix; x_point_end = 1;
x_point_end_pix = x_point_end * M_x + O_x_pix; //Выбираем зеленое перо толщиной 2:
Pen^ greenPen_x = gcnew Pen(Color::Green, 2);
42 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
//Строим линию через две заданные граничные точки: e->Graphics->DrawLine(greenPen_x,
-1 * M_x + O_x_pix, O_y_pix, x_point_end_pix, O_y_pix); //Строим горизонтальные линии сетки координат
//(кроме оси "x"):
//Ширина (размах) графика по оси ординат "y": float span_y = y_max - y_min;
//Число шагов по всей высоте сетки (по оси "y"): int N_step_grid_y = 20;
//Шаг сетки в направлении оси "y" //(высота всей сетки равна 2 единицам): float step_grid_y; float step_grid_y_pix; //Преобразование типов переменных: step_grid_y = (float) 2 / N_step_grid_y; step_grid_y_pix = step_grid_y * M_y; //Выбираем красное перо толщиной 1:
Pen^ redPen = gcnew Pen(Color::Red, 1);
//Строим сетку от нулевой линии в одну сторону (вниз): int j_y; float y1, y1_pix;
for (j_y = 1; j_y<=(N_step_grid_y/2); j_y++)
{
y1 = j_y * step_grid_y;
y1_pix = O_y_pix + j_y * step_grid_y_pix;
//Строим линию через две заданные граничные точки: e->Graphics->DrawLine(redPen,
-1 * M_x + O_x_pix, y1_pix, x_point_end_pix, y1_pix);
}
//Строим сетку от нулевой линии в другую сторону (вверх): for (j_y = 1; j_y<=(N_step_grid_y / 2); j_y++)
{
y1_pix = O_y_pix - j_y * step_grid_y * M_y; //Строим прямую линию через две заданные //граничные точки: e->Graphics->DrawLine(redPen,
-1 * M_x + O_x_pix, y1_pix, x_point_end_pix, y1_pix);
}
//Строим ось ординат "y" от y= -1 до y = 1:
//Задаем ординату последней точки оси ординат "y" при y = 1: float y_point_end, y_point_end_pix; y_point_end = 1; y_point_end_pix = y_point_end * M_y + O_y_pix;
//Выбираем зеленое перо толщиной 2:
Pen^ greenPen_y = gcnew Pen(Color::Green, 2); //Строим линию через две заданные граничные точки:
e->Graphics->DrawLine(greenPen_y, |
O_x_pix, y_point_end_pix); |
O_x_pix, -1 * M_y + O_y_pix, |
//Строим вертикальные линии сетки координат (кроме оси "y"): //Ширина (размах) графика по оси абсцисс "x":
Глава 15. График линейной функции |
43 |
float span_x = x_max - x_min; //Число шагов по всей ширине сетки //(по обе стороны от оси "y"): int N_step_grid_x = 20;
//Шаг сетки в направлении оси "x" //(ширина всей сетки равна 2 единицам): float step_grid_x = 0.1F, step_grid_x_pix; step_grid_x_pix = step_grid_x * M_x; //Выбираем красное перо толщиной 1:
Pen^ redPen_y = gcnew Pen(Color::Red, 1);
//Строим сетку от нулевой линии в одну сторону (вправо): int j_x;
float x1, x1_pix;
for (j_x = 1; j_x<=(N_step_grid_x / 2); j_x++)
{
x1 = j_x |
* step_grid_x; |
|
x1_pix = |
O_x_pix + j_x * step_grid_x_pix; |
|
//Строим линию через две заданные граничные точки: |
||
e->Graphics->DrawLine(redPen_y, |
x1_pix, y_point_end_pix); |
|
x1_pix, -1 * M_y + O_y_pix, |
}
//Строим сетку от нулевой линии в другую сторону (влево): for (j_x = 1; j_x<=(N_step_grid_x / 2); j_x++)
{
x1 = j_x * step_grid_x;
x1_pix = O_x_pix - j_x * step_grid_x_pix; //Строим прямую линию через две заданные //граничные точки: e->Graphics->DrawLine(redPen_y,
x1_pix, -1 * M_y + O_y_pix, x1_pix, y_point_end_pix);
}
//Записываем числа по осям координат: //Объявляем локальные переменные: int n;
float p1 = 1; float p2; String^ msg;
//Записываем числа по оси "O","+y": for (n = 0; n<=9; n++)
{
p2 = p1 - n * 0.1F; msg = p2.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix - 35, O_y_pix - 323 + n * step_grid_y_pix);
}
//Записываем числа по оси "O","-y": p1 = 0;
44 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
for (n = 1; n<=10; n++)
{
p2 = p1 - n * 0.1F; msg = p2.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix - 40, O_y_pix - 23 + n * step_grid_y_pix);
}
//Записываем числа по оси "O","+x": p1 = 0;
for (n = 0; n<=10; n++)
{
p2 = p1 + n * 0.1F; msg = p2.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix - 0 + n * step_grid_x_pix, O_y_pix - 0);
}
//Записываем числа по оси "O","-x": p1 = 0;
for (n = 1; n<=10; n++)
{
p2 = p1 - n * 0.1F; msg = p2.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix - 39 - n * step_grid_x_pix, O_y_pix - 0);
}
//Записываем обозначение оси y' = y / y_max: msg = "y ' = y / | y_max | ;";
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix - 5, O_y_pix - 333);
//Записываем обозначение | y_max |: msg = "| y_max | = ";
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 170, O_y_pix - 333);
//Записываем значение | y_max |: msg = y_max_abs.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 270, O_y_pix - 333);
//Записываем обозначение y_max: msg = "y_max = ";
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 380, O_y_pix - 333);
//Записываем значение y_max: msg = y_max.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 455, O_y_pix - 333);
//Записываем обозначение y_min:
Глава 15. График линейной функции |
45 |
msg = "y_min = ";
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 455, O_y_pix - 300);
//Записываем значение y_min: msg = y_min.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 525, O_y_pix - 300);
//Записываем обозначение оси x' = x / | x_max |: msg = "x ' = x / | x_max |";
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 455, O_y_pix - 30);
//Записываем обозначение | x_max |: msg = "| x_max | = ";
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 455, O_y_pix + 40);
//Записываем значение | x_max |: msg = x_max_abs.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 555, O_y_pix + 40);
//Записываем обозначение x_max: msg = "x_max = ";
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 455, O_y_pix + 90);
//Записываем значение x_max: msg = x_max.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 530, O_y_pix + 90);
//Записываем обозначение x_min: msg = "x_min = ";
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 455, O_y_pix + 140);
//Записываем значение x_min: msg = x_min.ToString();
e->Graphics->DrawString(msg, this->Font, Brushes::Blue, O_x_pix + 525, O_y_pix + 140);
//Построение графика функции y = f(x):
//Координаты нулевой (i=0) точки, //с которой строится график:
x_0 = x_min;
x_0_pix = x_0 / x_max_abs * M_x + O_x_pix; //Рассчитываем "y" и вводим знак минус, //чтобы положительное значение "y" //отложилось вверх по оси "y" (а не вниз): y_0 = -(Function_of_graph(x_0));
y_0_pix = y_0 / y_max_abs * M_y + O_y_pix;
46 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
//Выбираем черное перо толщиной 4:
Pen^ blackPen = gcnew Pen(Color::Black, 4); //Организовываем цикл по всем точкам, начиная с i = 1: for (i = 1; i<=Npoints; i++)
{
//Рассчитываем абсциссу "x" данной i-й точки: x_1 = x_min + i * step_x;
//Рассчитываем ординату "y" этой i-й точки //и вводим знак минус,
//чтобы положительные значения "y" //откладывались вверх (а не вниз), //и чтобы строить график традиционно снизу-вверх
//по оси "y":
y_1 = -(Function_of_graph(x_1));
//Переходим к относительным величинам и пикселам: x_1_pix = x_1 / x_max_abs * M_x + O_x_pix; y_1_pix = y_1 / y_max_abs * M_y + O_y_pix; //Строим отрезок линии графика y = f(x)
//между двумя известными точками: e->Graphics->DrawLine(blackPen, x_0_pix, y_0_pix,
x_1_pix, y_1_pix); //Присваиваем предыдущей (i-1)-й точке //координаты данной i-й точки:
x_0_pix = x_1_pix; y_0_pix = y_1_pix;
//В цикле задается следующая (i+1)-я точка:
}
Листинг 15.5. Код для выполнения анимации.
//Объявляем булеву переменную myText со значением false: bool static myText = false;
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
//Вводим анимацию: if (myText == false)
{
//Выводим текст: label1->Text =
"Graph 'Straight Line' of function y = a*x + b:"; //Изменяем значение myText на противоположное: myText = true;
}
else
{
//Удаляем текст:
Глава 15. График линейной функции |
47 |
label1->Text = "";
//Изменяем значение myText на противоположное: myText = false;
}
}
Глава 16. Графики типичных функций
Листинг 16.1. Метод для обработки щелчка по кнопке Graph.
private: System::Void button5_Click( System::Object^ sender, System::EventArgs^ e)
{
float a, b, c, x_min, x_max;
a = Convert::ToSingle(textBox1->Text); b = Convert::ToSingle(textBox2->Text); c = Convert::ToSingle(textBox3->Text);
x_min = Convert::ToSingle(textBox4->Text); x_max = Convert::ToSingle(textBox5->Text);
Form9^ myForm9 = gcnew Form9(); myForm9->a = a;
myForm9->b = b; myForm9->c = c; myForm9->x_min = x_min; myForm9->x_max = x_max; myForm9->Show();
}
Листинг 16.2. Метод для выполнения анимации.
//Объявляем булеву переменную myColor со значением false: bool static myColor = false;
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
//Вводим анимацию: if (myColor == false)
{
//Выводим черный цвет текста //для всех элементов внутри рамки:
groupBox1->ForeColor = Color::Black;
//Изменяем значение myColor на противоположное: myColor = true;
}
else
{
//Выводим белый цвет текста //для всех элементов внутри рамки:
groupBox1->ForeColor = Color::White;
Глава 16. Графики типичных функций |
49 |
//Изменяем значение myColor на противоположное: myColor = false;
}
}
Листинг 16.3. Метод для выполнения анимации.
//Объявляем булеву переменную myColor со значением false: bool static myColor = false;
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
//Вводим анимацию: if (myColor == false)
{
//Выводим красный цвет панели pictureBox1: pictureBox1->BackColor = Color::Red;
//Изменяем значение myColor на противоположное: myColor = true;
}
else
{
//Выводим зеленый цвет панели pictureBox1: pictureBox1->BackColor = Color::Green; //Изменяем значение myColor на противоположное: myColor = false;
}
}
Листинг 16.4. Метод для кнопки Graph.
private: System::Void button5_Click( System::Object^ sender, System::EventArgs^ e)
{
float a, b, c, d, x_min, x_max;
a = Convert::ToSingle(textBox1->Text); b = Convert::ToSingle(textBox2->Text); c = Convert::ToSingle(textBox3->Text); d = Convert::ToSingle(textBox4->Text);
x_min = Convert::ToSingle(textBox5->Text); x_max = Convert::ToSingle(textBox6->Text); Form13 myForm13 = new Form13();
myForm13->a = a; myForm13->b = b; myForm13->c = c;