Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005

.pdf
Скачиваний:
306
Добавлен:
13.08.2013
Размер:
1.14 Mб
Скачать

Глава 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);

Соседние файлы в предмете Программирование на C++