Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005
.pdfГлава 21. Непрерывный график-осцилло- грамма и его проверка при помощи диспетчера задач и файла подкачки
Листинг 21.1. Переменные и функция для построения графика.
//Объявляем и инициализируем переменные: float static x = 0;
float static y0 = 49; float static y1 = 0; float static k = 10; float static b = -5;
//Перемещение графика dx за каждый интервал времени:: private: const float static dx = 2;
//Определяем значение функции y=f(x): private: float f()
{
//Генератор в виде метода NextDouble возвращает //случайное число типа double, которое присваиваем x: Random^ myRandom = gcnew Random();
x = Convert::ToSingle(myRandom->NextDouble()); //Вычисляем новое значение функции y=f(x):
y1 = y0 + k * x + b;
//Задаем интервал для значений функции y=f(x): if (y1 > 98.9) y1 = 98.9f;
if (y1 < 0.999) y1 = 0.999f; return y1;
}
Листинг 21.2. Метод Form1_Load.
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
//Для рисования графика создаем объект myGraphics, //связываем его с PictureBox1 и масштабируем: Bitmap^ myBitmap = gcnew Bitmap(pictureBox1->Width,
pictureBox1->Height); Graphics^ myGraphics = Graphics::FromImage(myBitmap); myGraphics->ScaleTransform(1, -100.0f / pictureBox1->Height); myGraphics->TranslateTransform(0, -100);
Глава 21. Непрерывный график-осциллограмма и его проверка |
61 |
//Проектируем координатные горизонтальные линии: Pen^ myPen = gcnew Pen(Color::Blue, 1);
int i;
for (i = 10; i <= 100; i+=10) myGraphics->DrawLine(myPen, 0, i, pictureBox1->Width, i);
//Показываем коорд-е гориз-е линии на PictureBox: pictureBox1->Image = myBitmap;
//Освобождаем ресурсы, занятые объектом myGraphics: myGraphics->Dispose();
}
Листинг 21.3. Метод Timer1_Tick.
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
//Перемещаем прежний график влево:
Bitmap^ myBitmap = gcnew Bitmap(pictureBox1->Width, pictureBox1->Height);
Graphics^ g = Graphics::FromImage(myBitmap); g->DrawImage(pictureBox1->Image, -dx, 0.0f); //Проектируем координатные горизонтальные линии: g->ScaleTransform(1, -100.0F / pictureBox1->Height); g->TranslateTransform(0, -100);
Pen^ myPen = gcnew Pen(Color::Blue, 1); int i;
for (i = 10; i <= 100; i+=10) g->DrawLine(myPen, Convert::ToInt32(pictureBox1->Width - dx), i, Convert::ToInt32(pictureBox1->Width), i);
//На каждом интервале времени //получаем новое значение функции f(): y1 = f();
//Справа рисуем новую часть графика: Pen^ myPen2 = gcnew Pen(Color::Black, 1); g->DrawLine(myPen2,
Convert::ToSingle(pictureBox1->Width - 1 - dx), y0, Convert::ToSingle(pictureBox1->Width - 1), y1);
y0 = y1;
//Показываем новую часть графика
//на панели PictureBox1: pictureBox1->Image = myBitmap;
}
Часть V. Методология создания графической системы в трехмерном пространстве
Глава 22. Теория и алгоритмы системы
В этой части книги мы разработаем методологию создания графической системы для построения в трехмерном пространстве широко распространенных плоских и пространственных геометрических объектов (тел, фигур и поверхностей): прямые и кривые линии; плоскости и поверхности; объемные тела, например, многогранники и т.д. Эти геометрические тела могут быть частью какой-либо детали (изделия, конструкции) или инструмента, при помощи которого обрабатывается заданная заготовка из какого-нибудь материала.
Главное достоинство нашей методологии заключается в том, что в данной части книги мы спроектируем типичные приложения для построения различных пространственных изображений только на одной открытой (последней версии) платформе Visual Studio 2005 (без использования закрытых побочных библиотек типа DirectX и OpenGL, которые к тому же очень сложны в изучении). А в следующей части книги мы спроектируем пространственные изображения на базе VC++ 2005 и DirectX 9.0c.
Чтобы на экране монитора отобразить объект, у нас должны быть (рис. 22.1): точка наблюдения E (E – первая буква одного из ключевых, в данной теории,
английских слов Eye – глаз (наблюдателя));
объект наблюдения, который отождествлен с множеством точек; одна из этих точек P показана на рис. 22.1 (P – это первая буква английского слова Point – точка); экран монитора; на этом экране точку объекта P мы видим в точке экрана P’, ко-
торая находится на пересечении прямой EP с плоскостью экрана.
Отметим, что мы приводим ключевые английские слова по данной тематике с целью, чтобы далее легче было разобраться со сложными программами на Visual C++ 2005, Visual Basic и Visual C#, где имена переменных, массивов, процедур, функций, методов и других элементов программирования записаны с использованием этих ключевых слов.
В трехмерном пространстве вводим неподвижную правую прямоугольную систему координат x, y, z, а также сферическую систему координат r, ϕ , θ (рис. 22.2), в
которой определяются положения и размеры точки наблюдения, объекта и экрана. Эта прямоугольная система координат в литературе называется по-разному, напри-
мер, глобальной (global coordinates) или мировой (world coordinates) в отличие от ло-
кальной (local coordinates). Такую глобальную систему координат можно задать, например, в центре изображаемого объекта.
Глава 23. Методика создания графической системы на основе интеграции Visual C++ с Visual Basic, Visual C# и другими языками
При создании объекта sw класса StreamWriter в коде, например, на VB:
Dim sw As StreamWriter = _
New StreamWriter("D:\MyDocs\MyTest.txt")
При записи циклов для записи данных из массива myArrayVB(i, j) в файл
For i = 0 To N_x
For j = 0 To N_y
sw.WriteLine(myArrayVB(i, j))
Next
Next
мы увидим методы, свойства и другие элементы программирования класса
StreamWriter, в том числе функцию WriteLine (рис. 23.3).
Глава 24. Изображение и управление трехмерными объектами в трехмерном пространстве
Листинг 24.1. Код выше и в теле метода Form1_Load.
//Начало координат:
private: const double static x_focus = 0; private: const double static y_focus = 0; private: const double static z_focus = 0;
//Сферические координаты глаза наблюдателя (точки E): private: float static r_Eye;
private: float static phi_Eye; private: float static theta_Eye;
//Переменные и матрица (как массив) MatrixProjection //(во всех массивах нулевые индексы не используем): private: const double static pi = Math::PI;
private: int Tetrahedron; private: int Cube; private: int Octahedron; private: int Dodecahedron;
private: int Icosahedron_first; private: int Icosahedron_last;
private: static array<float,2>^ MatrixProjection = gcnew array<float,2>(5, 5);
//Для параллельного проецирования объекта на экран
//(parallel projection) задаем константу: private: const int static ParallelProjection = 0;
//Для перспективного проецирования объекта на экран
//(perspective projection) задаем константу: private: const int static PerspectiveProjection = 1;
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
//Задаем координаты глаза наблюдателя, например: r_Eye = 4;
phi_Eye = (float)(0.05 * pi); theta_Eye = (float)(0.3 * pi);
//Вызываем метод для перспективного проецирования, //когда type_of_projection = PerspectiveProjection //(для параллельного проецирования вместо
//PerspectiveProjection пишем ParallelProjection): Projection(MatrixProjection, PerspectiveProjection,
Глава 24. Изображение и управление трехмерными объектами |
65 |
r_Eye, phi_Eye, theta_Eye,
(float)x_focus, (float)y_focus, (float)z_focus, 0, 1, 0); //Рассчитываем параметры геометрического тела:
СalculateParameters();
//Связываем элемент PictureBox1 с классом Bitmap: pictureBox1->Image = gcnew Bitmap(pictureBox1->Width,
pictureBox1->Height);
//Проектируем и в PictureBox рисуем выбранное нами тело: Designing((Bitmap^)pictureBox1->Image);
}
Листинг 24.2. Метод для управления изображением фигуры.
private:
System::Void pictureBox1_MouseDown_1(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e)
{
//Задаем угол поворота объекта после нажатия клавиши: const float delta_theta = (float)pi / 20; //Используем переключатель:
switch ( e->Button )
{
//Если нажата левая кнопка мыши:
case System::Windows::Forms::MouseButtons::Left: theta_Eye = theta_Eye - delta_theta;
break;
//Если нажата правая кнопка мыши:
case System::Windows::Forms::MouseButtons::Right: theta_Eye = theta_Eye + delta_theta;
break;
}
//Перепроектируем объект: Projection(MatrixProjection, PerspectiveProjection,
r_Eye, phi_Eye, theta_Eye,
(float)x_focus, (float)y_focus, (float)z_focus, 0, 1, 0);
Designing((Bitmap^)pictureBox1->Image);
//В элементе PictureBox перерисовываем фигуру: pictureBox1->Refresh();
}
Листинг 24.3. Метод для управления изображением фигуры.
private:
System::Void pictureBox1_MouseMove_1(System::Object^
66 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
sender, System::Windows::Forms::MouseEventArgs^ e)
{
//Задаем угол поворота объекта после перемещения мыши: const float delta_theta = (float)pi / 20;
//Изменяем угол проецирования после перемещения мыши: phi_Eye = phi_Eye - delta_theta;
//Перепроектируем фигуру: Projection(MatrixProjection, PerspectiveProjection,
r_Eye, phi_Eye, theta_Eye,
(float)x_focus, (float)y_focus, (float)z_focus, 0, 1, 0);
Designing((Bitmap^)pictureBox1->Image);
//В элементе PictureBox перерисовываем фигуру: pictureBox1->Refresh();
}
Листинг 24.4. Методы для решения поставленной задачи.
//Проектируем и при помощи метода DrawSolid //рисуем выбранное флажком CheckBox геом-е тело: private: void Designing(Bitmap^ bmp)
{
//Создаем объект g класса Graphics: Graphics^ g;
//Связываем объект g с изображением bmp: g = Graphics::FromImage(bmp);
//Задаем белый цвет типа Window
//для элемента управления PictureBox1: g->Clear(SystemColors::Window);
//Высвобождаем ресурсы от графического объекта g: g->Dispose();
//Преобразуем точки: TransformAllDataFull(MatrixProjection); //Проектируем и рисуем выбранное на CheckBox тело: if (checkBox1->CheckState ==
System::Windows::Forms::CheckState::Checked)
{
DrawSolid(
bmp, Tetrahedron, Cube - 1, System::Drawing::Color::Red, false);
}
if (checkBox2->CheckState == System::Windows::Forms::CheckState::Checked)
{
DrawSolid(bmp, Cube, Octahedron - 1, System::Drawing::Color::Black, false);
}
Глава 24. Изображение и управление трехмерными объектами |
67 |
if (checkBox3->CheckState == System::Windows::Forms::CheckState::Checked)
{
DrawSolid(bmp, Octahedron, Dodecahedron - 1, System::Drawing::Color::Green, false);
}
if (checkBox4->CheckState == System::Windows::Forms::CheckState::Checked)
{
DrawSolid(bmp, Dodecahedron, Icosahedron_first - 1, System::Drawing::Color::Blue, false);
}
if (checkBox5->CheckState == System::Windows::Forms::CheckState::Checked)
{
DrawSolid(bmp, Icosahedron_first, Icosahedron_last, System::Drawing::Color::Orange, false);
}
if (checkBox6->CheckState == System::Windows::Forms::CheckState::Checked)
{
DrawSolid(bmp, 1, Tetrahedron - 1, System::Drawing::Color::Salmon, false);
}
}
//Рассчитываем параметры геометрических тел и осей: private: void СalculateParameters()
{
float theta1; float theta2;
float s1; float s2; float c1; float c2; float S; float R; float H; float A; float B; float C; float D; float X; float Y; float y2; float M; float N; //Оси координат:
DesigningLine(0, 0, 0, 0.5f, 0, 0); //Ось x. DesigningLine(0, 0, 0, 0, 0.5f, 0); //Ось y. DesigningLine(0, 0, 0, 0, 0, 0.5f); //Ось z. //Тетраэдр (Tetrahedron):
Tetrahedron = NumLines + 1;
S = (float)Math::Sqrt(6);
A = (float)(S / Math::Sqrt(3)); B = -A / 2;
C = (float)(A * Math::Sqrt(2) - 1); D = S / 2; DesigningLine(0, C, 0, A, -1, 0); DesigningLine(0, C, 0, B, -1, D); DesigningLine(0, C, 0, B, -1, -D); DesigningLine(B, -1, -D, B, -1, D); DesigningLine(B, -1, D, A, -1, 0);
68 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
DesigningLine(A, -1, 0, B, -1, -D); //Куб (Cube):
Cube = NumLines + 1; DesigningLine(-1, -1, -1, -1, 1, -1); DesigningLine(-1, 1, -1, 1, 1, -1); DesigningLine(1, 1, -1, 1, -1, -1); DesigningLine(1, -1, -1, -1, -1, -1); DesigningLine(-1, -1, 1, -1, 1, 1); DesigningLine(-1, 1, 1, 1, 1, 1); DesigningLine(1, 1, 1, 1, -1, 1); DesigningLine(1, -1, 1, -1, -1, 1); DesigningLine(-1, -1, -1, -1, -1, 1); DesigningLine(-1, 1, -1, -1, 1, 1); DesigningLine(1, 1, -1, 1, 1, 1); DesigningLine(1, -1, -1, 1, -1, 1); //Октаэдр (Octahedron):
Octahedron = NumLines + 1; DesigningLine(0, 1, 0, 1, 0, 0); DesigningLine(0, 1, 0, -1, 0, 0); DesigningLine(0, 1, 0, 0, 0, 1); DesigningLine(0, 1, 0, 0, 0, -1); DesigningLine(0, -1, 0, 1, 0, 0); DesigningLine(0, -1, 0, -1, 0, 0); DesigningLine(0, -1, 0, 0, 0, 1); DesigningLine(0, -1, 0, 0, 0, -1); DesigningLine(0, 0, 1, 1, 0, 0); DesigningLine(0, 0, 1, -1, 0, 0); DesigningLine(0, 0, -1, 1, 0, 0); DesigningLine(0, 0, -1, -1, 0, 0); //ДОдекаэдр (Dodecahedron): Dodecahedron = NumLines + 1;
theta1 = (float)(pi * 0.4); theta2 = (float)(pi * 0.8); s1 = (float)Math::Sin(theta1);
c1 = (float)Math::Cos(theta1);
s2 = (float)Math::Sin(theta2);
c2 = (float)Math::Cos(theta2);
M = 1 - (2 - 2 * c1 - 4 * s1 * s1) / (2 * c1 - 2); //MessageBox::Show(Convert::ToString(M));//Нормально. N = (float)Math::Sqrt((2 - 2 * c1) - M * M) *
(1 + (1 - c2) / (c1 - c2)); R = 2 / N; S = (float)(R * Math::Sqrt(2 - 2 * c1));
A = R * s1; B = R * s2; C = R * c1; D = R * c2; H = R * (c1 - s1);
X = (R * R * (2 - 2 * c1) - 4 * A * A) / (2 * C - 2 * R);
Y = (float)Math::Sqrt(S * S - (R - X) * (R - X)); y2 = Y * (1 - c2) / (c1 - c2);
Глава 24. Изображение и |
управление трехмерными объектами |
69 |
||||
DesigningLine(R, |
1, 0, C, 1, A); |
|
|
|||
DesigningLine(C, |
1, A, D, 1, B); |
|
|
|||
DesigningLine(D, |
1, B, D, 1, -B); |
|
|
|||
DesigningLine(D, |
1, -B, C, 1, -A); |
|
|
|||
DesigningLine(C, |
1, -A, R, 1, 0); |
|
|
|||
DesigningLine(R, |
1, 0, X, |
1 - Y, 0); |
|
|||
DesigningLine(C, |
1, A, X * c1, 1 - Y, X * s1); |
|
||||
DesigningLine(C, |
1, -A, X * c1, 1 |
- Y, -X * s1); |
|
|||
DesigningLine(D, |
1, B, X * c2, 1 - Y, X * s2); |
|
||||
DesigningLine(D, |
1, -B, X * c2, 1 |
- Y, -X * s2); |
|
|||
DesigningLine(X, |
1 - Y, 0, -X * c2, 1 - y2, -X * s2); |
|
||||
DesigningLine(X, |
1 - Y, 0, -X * c2, 1 - y2, X * s2); |
|
||||
DesigningLine(X * c1, |
1 |
- Y, X * s1, |
|
|||
|
-X * |
c2, |
1 - y2, X * s2); |
|
||
DesigningLine(X * c1, |
1 |
- |
Y, X * s1, |
|
||
|
-X * |
c1, |
1 - y2, X * s1); |
|
||
DesigningLine(X * c2, |
1 |
- |
Y, X * s2, |
|
||
|
-X * |
c1, |
1 - y2, X * s1); |
|
||
DesigningLine(X * c2, |
1 |
- |
Y, X * s2, -X, 1 - y2, 0); |
|
||
DesigningLine(X * c2, |
1 |
- |
Y, -X * s2, -X, 1 - y2, 0); |
|
||
DesigningLine(X * c2, |
1 |
- |
Y, -X * s2, |
|
||
|
-X * |
c1, |
1 - y2, -X * s1); |
|
||
DesigningLine(X * c1, |
1 |
- |
Y, -X * s1, |
|
||
|
-X * |
c1, |
1 - y2, -X * s1); |
|
||
DesigningLine(X * c1, |
1 |
- |
Y, -X * s1, |
|
||
|
-X * |
c2, |
1 - y2, -X * s2); |
|
||
DesigningLine(-R, -1, |
0, -X, 1 - y2, 0); |
|
||||
DesigningLine(-C, -1, |
A, -X * c1, 1 - y2, X * s1); |
|
||||
DesigningLine(-D, -1, |
B, -X * c2, 1 - y2, X * s2); |
|
||||
DesigningLine(-D, -1, |
-B, -X * c2, 1 - y2, -X * s2); |
|
||||
DesigningLine(-C, -1, |
-A, -X * c1, 1 - y2, -X * s1); |
|
||||
DesigningLine(-R, -1, |
0, -C, -1, A); |
|
||||
DesigningLine(-C, -1, |
A, -D, -1, B); |
|
||||
DesigningLine(-D, -1, |
B, -D, -1, -B); |
|
||||
DesigningLine(-D, -1, |
-B, -C, -1, -A); |
|
DesigningLine(-C, -1, -A, -R, -1, 0); //Икосаэдр (Icosahedron): Icosahedron_first = NumLines + 1;
R = (float)(2.0 / (2.0 * Math::Sqrt(1.0 - 2.0 * c1) + Math::Sqrt(3.0 / 4.0 * (2.0 - 2.0 * c1) -
2.0 * c2 - c2 * c2 - 1.0)));
S = R * (float)Math::Sqrt(2 - 2 * c1);
H = 1 - (float)Math::Sqrt(S * S - R * R);
A = R * s1; B = R * s2; C = R * c1; D = R * c2; DesigningLine(R, H, 0, C, H, A); DesigningLine(C, H, A, D, H, B); DesigningLine(D, H, B, D, H, -B);