Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005
.pdf80 Жарков В.А. Компьютерная графика, мультимедиа и игры на 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) |
|