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

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

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

80 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

+ A[2, 3] * B[3, 1];

Result[2, 2] = A[2, 1] * B[1, 2] + A[2, 2] * B[2, 2] + A[2, 3] * B[3, 2];

Result[2, 3] = A[2, 1] * B[1, 3] + A[2, 2] * B[2, 3]

+A[2, 3] * B[3, 3]; Result[2, 4] = 0;

Result[3, 1] = A[3, 1] * B[1, 1] + A[3, 2] * B[2, 1]

+A[3, 3] * B[3, 1];

Result[3, 2] = A[3, 1] * B[1, 2] + A[3, 2] * B[2, 2] + A[3, 3] * B[3, 2];

Result[3, 3] = A[3, 1] * B[1, 3] + A[3, 2] * B[2, 3]

+A[3, 3] * B[3, 3]; Result[3, 4] = 0;

Result[4, 1] = A[4, 1] * B[1, 1] + A[4, 2] * B[2, 1]

+A[4, 3] * B[3, 1] + B[4, 1];

Result[4, 2] = A[4, 1] * B[1, 2] + A[4, 2] * B[2, 2] + A[4, 3] * B[3, 2] + B[4, 2];

Result[4, 3] = A[4, 1] * B[1, 3] + A[4, 2] * B[2, 3] + A[4, 3] * B[3, 3] + B[4, 3];

Result[4, 4] = 1;

}

Листинг 24.5. Передача данных о геометрии объектов на внешний файл.

//Вводим перем-ю N_Graphics для номера многих геом-х изобр-й. //Номер первого изображения равен 1:

int static N_Graphics = 1;

public: void DrawSolid(Bitmap^ bmp,

int first_line, int last_line, Color color, bool clear)

{

float x1, y1, x2, y2; Graphics^ g; Pen^ pen; //Задаем толщину линии рисования, например, 2 //(цвет линии мы задали в процедуре Designing): pen = gcnew Pen(color, 2);

//Связываем объект g с изображением bmp: g = Graphics::FromImage(bmp);

if (clear) g->Clear(System::Drawing::Color::Black); //Объявляем индексы элементов всех массивов:

int i, j, k;

//Если этот метод DrawSolid вызван второй раз

//для рисования второго изображения и N_Graphics = 2, //то обходим 1-й массив для первого изобр-я до метки M2: if (N_Graphics == 2) goto M2;

//Программируем первый массив для первого изображения. //Задаем границы индексов первого массива myArray[i, j]:

Глава 24. Изображение и управление трехмерными объектами

81

int N_x = 200; int N_y = 2;

//Объявляем массив myArray[i, j] переменных типа float, //когда i = 0,1,2,3,...,(N_x-1); j = 0,1,2,3,...,(N_y-1): array<float,2>^ myArray = gcnew array<float,2>(N_x, N_y); //Значение первой границы массива myArray:

int N_1_myArray;

//Рассчитываем элементы массива myArray(i, j) //для рисования линий первого геом-го изображения: i = -1; //Задаем до цикла.

for (k = first_line; k <= last_line; k++)

{

x1 = Lines[k].fr_tr_points[1];

y1 = Lines[k].fr_tr_points[2];

x2 = Lines[k].to_tr_points[1];

y2 = Lines[k].to_tr_points[2];

//Можно рисовать линии изображения и здесь: //g->DrawLine(pen,

//(x1 * bmp->Width / 4) + bmp->Width / 2.0F,

//bmp->Height / 2.0F - (y1 * bmp->Height / 4),

//(x2 * bmp->Width / 4) + bmp->Width / 2.0F,

//bmp->Height / 2.0F - (y2 * bmp->Height / 4)); //Масштабируем значения координат:

x1 = (x1 * bmp->Width / 4) + bmp->Width / 2.0F; y1 = bmp->Height / 2.0F - (y1 * bmp->Height / 4); x2 = (x2 * bmp->Width / 4) + bmp->Width / 2.0F; y2 = bmp->Height / 2.0F - (y2 * bmp->Height / 4); //Записываем координаты точек в массив:

i= i + 2;

myArray[i, 0] = x1; myArray[i, 1] = y1; myArray[i + 1, 0] = x2; myArray[i + 1, 1] = y2;

N_1_myArray = i + 1; //Значение границы массива.

}

//Начало N_first_line и конец N_last_line цикла

//при рисовании из массива myArray: int N_first_line, N_last_line; N_first_line = first_line; N_last_line = last_line;

//Передаем значения начала N_first_line

//и конца цикла N_last_line в элементы массива

//myArray[0, 0] и myArray[0, 1]: myArray[0, 0] = N_first_line; myArray[0, 1] = N_last_line;

//Рисуем при помощи массива координат myArray[200, 2]. i = -1;

for (k = N_first_line; k <= N_last_line; k++)

82 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

{

i = i + 2;

x1 = myArray[i, 0];

y1 = myArray[i, 1];

x2 = myArray[i + 1, 0];

y2 = myArray[i + 1, 1]; g->DrawLine(pen, x1, y1, x2, y2);

}

//Записываем массив координат myArray[200, 1] в файл. //Создаем объект sw класса StreamWriter для записи

//в файл по адресу D:\\MyDocs\\MyTest3D_Graphics.txt: if (N_Graphics == 1)

{

StreamWriter^ sw = gcnew StreamWriter("D:\\MyDocs\\MyTest3D_Graphics.txt"); //Каждый элемент myArray[i, j] записываем в файл //в виде отдельной строки при помощи WriteLine: for (i = 0; i <= N_x-1; i++)

for (j = 0; j <= N_y-1; j++) sw->WriteLine(myArray[i, j]);

sw->Close();

}

M2:

//Если этот метод DrawSolid вызван первый раз

//для рисования первого изображения и N_Graphics = 1, //то обходим 2-й массив для 2-го изобр-я до метки M_End: if (N_Graphics == 1) goto M_End;

//Программируем второй массив для второго изображения. //Задаем границы индексов 2-го массива myArray_2(i, j): int N_x_2 = 200;

int N_y_2 = 2;

//Задаем массив myArray_2(i, j) переменных типа Single, //когда i = 0,1,2,3,...,(N_x-1); j = 0,1,2,3,...,(N_y-1): array<float,2>^ myArray_2 =

gcnew array<float,2>(N_x_2, N_y_2); //Значение первой границы массива myArray_2: int N_1_myArray_2;

//Рассчитываем элементы массива myArray_2(i, j) //для рисования линий второго геом-го изображения: i = -1; //Задаем до цикла.

for (k = first_line; k <= last_line; k++)

{

x1 = Lines[k].fr_tr_points[1];

y1 = Lines[k].fr_tr_points[2];

x2 = Lines[k].to_tr_points[1];

y2 = Lines[k].to_tr_points[2];

Глава 24. Изображение и управление трехмерными объектами

83

//Можно рисовать линии изображения и здесь: //g->DrawLine(pen,

//(x1 * bmp->Width / 4) + bmp->Width / 2.0F,

//bmp->Height / 2.0F - (y1 * bmp->Height / 4),

//(x2 * bmp->Width / 4) + bmp->Width / 2.0F,

//bmp->Height / 2.0F - (y2 * bmp->Height / 4)); //Масштабируем значения координат:

x1 = (x1 * bmp->Width / 4) + bmp->Width / 2.0F; y1 = bmp->Height / 2.0F - (y1 * bmp->Height / 4); x2 = (x2 * bmp->Width / 4) + bmp->Width / 2.0F; y2 = bmp->Height / 2.0F - (y2 * bmp->Height / 4); //Записываем координаты точек в массив:

i = i + 2; myArray_2[i, 0] = x1; myArray_2[i, 1] = y1;

myArray_2[i + 1, 0] = x2; myArray_2[i + 1, 1] = y2;

N_1_myArray_2 = i + 1;//Граница массива.

}

//Начало N_first_line_2 и конец N_last_line_2 цикла

//при рисовании из массива myArray_2: int N_first_line_2, N_last_line_2; N_first_line_2 = first_line; N_last_line_2 = last_line;

//Передаем значения начала N_first_line_2

//и конца цикла N_last_line_2 в элементы массива

//myArray_2[0, 0] и myArray_2[0, 1]: myArray_2[0, 0] = N_first_line_2; myArray_2[0, 1] = N_last_line_2;

//Рисуем при помощи массива координат myArray_2[200, 1]: i = -1;

for (k = N_first_line_2; k <= N_last_line_2; k++)

{

i = i + 2;

x1 = myArray_2[i, 0];

y1 = myArray_2[i, 1];

x2 = myArray_2[i + 1, 0];

y2 = myArray_2[i + 1, 1]; g->DrawLine(pen, x1, y1, x2, y2);

}

//Записываем массив координат myArray_2(200, 1) в файл. //Создаем объект sw_2 класса StreamWriter для записи

//в файл по адресу D:\\MyDocs\\MyTest3D_Graphics_2.txt: StreamWriter^ sw_2 = gcnew StreamWriter("D:\\MyDocs\\MyTest3D_Graphics_2.txt"); //Каждый элемент массива myArray_2[i, j] запис-м в файл //в виде отдельной строки при помощи метода WriteLine:

84 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

for (i = 0; i <= N_x_2-1; i++) for (j = 0; j <= N_y_2-1; j++)

sw_2->WriteLine(myArray_2[i, j]); sw_2->Close();

//Высвобождаем ресурсы от объектов g и pen: g->Dispose(); pen->Dispose();

M_End:

//Если этот метод DrawSolid вызван еще раз //для рисования следующего изображения,

//то увеличиваем номер изображения N_Graphics на 1: N_Graphics = N_Graphics + 1;

}

Листинг 24.6. Метод для печати изображения с элемента PictureBox.

private: System::Void printDocument1_PrintPage(System::Object^ sender, System::Drawing::Printing::PrintPageEventArgs^ e)

{

e->Graphics->DrawImage(pictureBox1->Image, 0, 0);

}

Глава 25. Изображение и управление трехмерными объектами на Visual Basic для интеграции с Visual C++, Visual C# и други-

ми языками

Листинг 25.1. Код выше и в теле процедуры Form1_Load.

'Начало координат:

Private Const x_focus As Double = 0

Private Const y_focus As Double = 0

Private Const z_focus As Double = 0

'Сферические координаты точки E (глаза наблюдателя Eye): Private r_Eye As Single

Private phi_Eye As Single Private theta_Eye As Single

'Объявляем матрицу (как массив) и переменные '(во всех массивах нулевые индексы не используем): Private Const pi As Double = Math.PI

Private MatrixProjection(4, 4) As Single Private Tetrahedron As Integer

Private Cube As Integer Private Octahedron As Integer Private Dodecahedron As Integer

Private Icosahedron_first As Integer

Private Icosahedron_last As Integer

'Для параллельного проецирования объекта на экран

'(parallel projection) задаем константу: Private Const ParallelProjection As Integer = 0

'Для перспективного проецирования объекта на экран

'(perspective projection)задаем константу: Private Const PerspectiveProjection As Integer = 1

Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As EventArgs) Handles MyBase.Load

'Задаем координаты глаза наблюдателя, например:

r_Eye = 4 : phi_Eye = 0.05 * pi : theta_Eye = 0.3 * pi 'Вызываем процедуру для перспективного проецирования, 'когда type_of_projection = PerspectiveProjection '(для параллельного проецирования вместо

'PerspectiveProjection пишем ParallelProjection): Projection(MatrixProjection, PerspectiveProjection, _ r_Eye, phi_Eye, theta_Eye, _

86Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

x_focus, y_focus, z_focus, 0, 1, 0) 'Рассчитываем параметры геометрического тела:

СalculateParameters()

'Связываем элемент PictureBox1 с классом Bitmap: PictureBox1.Image = New Bitmap(PictureBox1.Width, _

PictureBox1.Height) 'Проектируем и в PictureBox1 рисуем выбранное нами тело: Designing(DirectCast(PictureBox1.Image, Bitmap))

End Sub

Листинг 25.2. Метод ProcessCmdKey.

Protected Overrides Function ProcessCmdKey( _ ByRef msg As System.Windows.Forms.Message, _

ByVal keyData As System.Windows.Forms.Keys) As Boolean 'Задаем угол поворота фигуры после нажатия клавиши: Const delta_theta As Single = pi / 20

Select Case keyData

Case System.Windows.Forms.Keys.Left theta_Eye = theta_Eye - delta_theta

Case System.Windows.Forms.Keys.Right theta_Eye = theta_Eye + delta_theta

Case System.Windows.Forms.Keys.Up phi_Eye = phi_Eye - delta_theta

Case System.Windows.Forms.Keys.Down phi_Eye = phi_Eye + delta_theta

Case Else

Return MyBase.ProcessCmdKey(msg, keyData) End Select

Projection(MatrixProjection, PerspectiveProjection, _ r_Eye, phi_Eye, theta_Eye, _

x_focus, y_focus, z_focus, 0, 1, 0)

'В элементе PictureBox1 перерисовываем объект: Designing(DirectCast(PictureBox1.Image, Bitmap)) PictureBox1.Refresh()

Return True End Function

Листинг 25.3. Процедуры и функции.

'Проектируем и при помощи процедуры DrawSolid

'рисуем выбранное флажком CheckBox геометрическое тело: Private Sub Designing(ByVal bmp As Bitmap)

'Создаем объект g класса Graphics: Dim g As Graphics

Глава 25. Изображение и управление объектами на VB и VC++

87

'Связываем объект 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 Then

DrawSolid(bmp, Tetrahedron, Cube - 1, _ System.Drawing.Color.Red, False)

End If

If CheckBox2.CheckState = _ System.Windows.Forms.CheckState.Checked Then _ DrawSolid(bmp, Cube, Octahedron - 1, _ System.Drawing.Color.Black, False)

If CheckBox3.CheckState = _ System.Windows.Forms.CheckState.Checked Then _ DrawSolid(bmp, Octahedron, Dodecahedron - 1, _ System.Drawing.Color.Green, False)

If CheckBox4.CheckState = _ System.Windows.Forms.CheckState.Checked Then _ DrawSolid(bmp, Dodecahedron, Icosahedron_first - 1, _ System.Drawing.Color.Blue, False)

If CheckBox5.CheckState = _ System.Windows.Forms.CheckState.Checked Then _ DrawSolid(bmp, Icosahedron_first, Icosahedron_last, _ System.Drawing.Color.Orange, False)

If CheckBox6.CheckState = _ System.Windows.Forms.CheckState.Checked Then _ DrawSolid(bmp, 1, Tetrahedron - 1, _ System.Drawing.Color.Salmon, False)

End Sub

'Рассчитываем параметры геометрических тел и осей: Private Sub СalculateParameters()

Dim theta1 As Single : Dim theta2 As Single Dim s1 As Single : Dim s2 As Single

Dim c1 As Single : Dim c2 As Single

Dim S As Single : Dim R As Single

Dim H As Single : Dim A As Single

Dim B As Single : Dim C As Single

Dim D As Single : Dim X As Single

Dim Y As Single : Dim y2 As Single

Dim M As Single : Dim N As Single

88Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

'Оси координат:

DesigningLine(0, 0, 0, 0.5, 0, 0) 'Ось x. DesigningLine(0, 0, 0, 0, 0.5, 0) 'Ось y. DesigningLine(0, 0, 0, 0, 0, 0.5) 'Ось z. 'Тетраэдр (Tetrahedron):

Tetrahedron = NumLines + 1 S = CSng(Sqrt(6))

A = S / CSng(Sqrt(3)) B = -A / 2

C = A * CSng(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) 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):

Глава 25. Изображение и управление объектами на VB и VC++

89

Dodecahedron = NumLines +

1

 

theta1 = pi * 0.4

: theta2 = pi * 0.8

 

s1 = CSng(Sin(theta1))

 

 

 

 

c1 = CSng(Cos(theta1))

 

 

 

 

s2 = CSng(Sin(theta2))

 

 

 

 

c2 = CSng(Cos(theta2))

4

*

s1 * s1) / (2 * c1 - 2)

 

M = 1 - (2 - 2 * c1 -

 

N = CSng(Sqrt((2 - 2 * c1) - M * M)) * _

 

(1 + (1 - c2) /

(c1 - c2)) : R = 2 / N

 

S = R * CSng(Sqrt(2 -

2

* c1))

 

A = R * s1 : B = R * s2

 

 

 

C = R * c1 : D = R * c2

 

 

 

H = R * (c1 - s1)

2 *

c1)

- 4 * A * A) / _

 

X = (R * R * (2 -

 

(2 * C - 2 * R)

 

 

 

 

 

 

Y = CSng(Sqrt(S * S - (R - X) * (R - X)))

 

y2 = Y * (1 - c2)

/ (c1

-

c2)

 

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)

 

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