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

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

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

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

'Рассчитываем градиент в этой точке: Private Sub Gradient(ByVal x As Single, _

ByVal y As Single, ByRef dx As Single, ByRef dy As Single) Dim dist As Single

dx = df_dx(x, y) : dy = df_dy(x, y) dist = CSng(Sqrt(dx * dx + dy * dy)) If Abs(dist) < 0.0001 Then

dx = 0 : dy = 0 Else

dx = dx / dist : dy = dy / dist End If

End Sub

'Программируем второй массив для передачи в файл:

'Задаем границы индексов второго массива myArrayVB_2(i, j): Dim N_x_2 As Integer = 20000

Dim N_y_2 As Integer = 1

'Объявляем массив myArrayVB_2(i, j) переменных типа Single , 'когда i = 0,1,2,3,...,N_x; j = 0,1,2,3,...,N_y:

Dim myArrayVB_2(20000, 1) As Single 'Автомат-ки обнуляется. 'Значение первой границы массива myArrayVB_2:

Dim N_1_myArrayVB_2 As Integer 'Счетчик элементов массива: Dim ii As Integer = -1

'Рисуем линию уровня f(x, y) = LevelCurves: Private Sub PlotLevelCurve(ByVal g As Graphics, _

ByVal LevelCurves As Single, ByVal x_min As Single, _ ByVal x_max As Single, ByVal y_min As Single, _ ByVal y_max As Single, _

Optional ByVal step_size As Single = 0.1, _ Optional ByVal start_x As Single = 1.0, _ Optional ByVal start_y As Single = 1.0, _ Optional ByVal tolerance As Single = 0.02)

'Объявляем индексы элементов всех массивов: Dim i, j As Integer

'Программируем 1-й массив для рисования здесь. 'Задаем границы индексов 1-го массива myArrayVB(i, j): Dim N_x As Integer = 2000

Dim N_y As Integer = 1

'Объявляем 1-й массив myArrayVB(i, j) переменных Single, 'когда i = 0,1,2,3,...,N_x; j = 0,1,2,3,...,N_y:

Dim myArrayVB(N_x, N_y) As Single 'Автомат-ки обнуляется. 'Значение первой границы массива myArrayVB:

Dim N_1_myArrayVB As Integer

'Объявляем переменные для точек линий уровня:

Глава 33. Расчет и изображение линий уровня на VB для VC++ и VC#

161

Dim num_points As Integer

Dim x0 As Single : Dim y0 As Single

Dim x1 As Single : Dim y1 As Single

Dim x2 As Single : Dim y2 As Single Dim dx As Single : Dim dy As Single

'Находим точку (x0, y0) на линии уровня LevelCurves: FindPointOnCurve(x0, y0, LevelCurves, _

start_x, start_y, tolerance) 'Начальная точка линии: num_points = 1

'Следующая линия уровня LevelCurves: x2 = x0

y2 = y0

i = -1 'Задаем до цикла. 'Начало цикла Do - Loop: Do

x1 = x2

y1 = y2

'Находим следующую точку на линии: Gradient(x2, y2, dx, dy)

If Abs(dx) + Abs(dy) < 0.001 Then Exit Do x2 = x2 + dy * step_size

y2 = y2 - dx * step_size

FindPointOnCurve(x2, y2, LevelCurves, x2, y2, _ tolerance)

'Можно рисовать и здесь (без массива) до этой точки: 'g.DrawLine(myPen, x1, y1, x2, y2)

'Записываем коорд-ты точек в 1-й массив для текущей 'линии уровня, которую будем рисовать здесь:

i = i + 2 myArrayVB(i, 0) = x1 myArrayVB(i, 1) = y1

myArrayVB(i + 1, 0) = x2 myArrayVB(i + 1, 1) = y2

N_1_myArrayVB = i + 1 'Значение границы массива. 'Записываем координаты точек текущей линии 'во 2-й массив, который будем экспортировать в файл: ii = ii + 2

myArrayVB_2(ii, 0) = x1 myArrayVB_2(ii, 1) = y1 myArrayVB_2(ii + 1, 0) = x2 myArrayVB_2(ii + 1, 1) = y2

N_1_myArrayVB_2 = ii + 1 'Значение границы массива. 'Задаем следующую точку:

num_points = num_points + 1

'Смотрим,находится ли точка вне области рисования: If x2 < x_min Or x2 > x_max Or _

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

y2 < y_min Or y2 > y_max _ Then Exit Do

'Если мы ушли более чем на 4 точки, то смотрим 'не пришли ли мы в начало:

If num_points >= 4 Then

If Sqrt((x0 - x2) * (x0 - x2) + (y0 - y2) _ * (y0 - y2)) <= step_size * 1.1 Then

'Можно рисовать и здесь (без массива): 'g.DrawLine(myPen, x2, y2, x0, y0) 'Записываем координаты точек в 1-й массив: i = i + 2

myArrayVB(i, 0) = x2 myArrayVB(i, 1) = y2 myArrayVB(i + 1, 0) = x0 myArrayVB(i + 1, 1) = y0

N_1_myArrayVB = i + 1 'Граница массива. 'Записываем координаты точек во 2-й массив, 'который будем экспортировать в файл:

ii = ii + 2 myArrayVB_2(ii, 0) = x2 myArrayVB_2(ii, 1) = y2 myArrayVB_2(ii + 1, 0) = x0 myArrayVB_2(ii + 1, 1) = y0

N_1_myArrayVB_2 = ii + 1 'Граница массива. Exit Do

End If End If

Loop 'Переход в начало цикла Do - Loop. 'Начало N_first_line и конец N_last_line цикла

'при рисовании здесь из массива myArrayVB: Dim N_first_line, N_last_line As Integer N_first_line = 1

N_last_line = N_1_myArrayVB

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

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

'myArrayVB(0, 0) и myArrayVB(0, 1): myArrayVB(0, 0) = N_first_line myArrayVB(0, 1) = N_last_line

'Рисуем при помощи массива координат myArrayVB(2000, 1): Dim k As Integer

i = -1

For k = N_first_line To N_last_line i = i + 2

x1 = myArrayVB(i, 0)

y1 = myArrayVB(i, 1)

x2 = myArrayVB(i + 1, 0)

Глава 33. Расчет и изображение линий уровня на VB для VC++ и VC#

163

y2 = myArrayVB(i + 1, 1) g.DrawLine(myPen, x1, y1, x2, y2)

Next

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

'при рисовании из массива myArrayVB_2 в другом проекте: Dim N_first_line_2, N_last_line_2 As Integer N_first_line_2 = 1

N_last_line_2 = N_1_myArrayVB_2 'Передаем значения начала N_first_line_2

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

'myArrayVB_2(0, 0) и myArrayVB_2(0, 1): myArrayVB_2(0, 0) = N_first_line_2 myArrayVB_2(0, 1) = N_last_line_2

'Записываем массив корд-т myArrayVB_2(20000, 1) в файл. 'Создаем объект sw класса StreamWriter

'для записи в файл D:\MyDocs\MyTest_LevelCurves.txt. 'Файл автоматически очищается:

Dim sw As StreamWriter = _

New StreamWriter("D:\MyDocs\MyTest_LevelCurves.txt") 'Каждый элемент массива myArrayVB_2(i, j) запис-м в файл 'в виде отдельной строки при помощи процедуры WriteLine: For i = 0 To N_x_2

For j = 0 To N_y_2 sw.WriteLine(myArrayVB_2(i, j))

Next Next sw.Close()

End Sub

Глава 34. Изображение линий уровня поверхности в проекте Visual C++ по данным из проекта Visual C# или Visual Basic

Листинг 34.1. Код для рисования изображения.

//Концы числового интервала области задания поверхности: private: static const float x_min = -1.5;

private: static const float x_max = 1.5; private: static const float y_min = -1.5; private: static const float y_max = 1.5; private:

System::Void pictureBox1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e)

{

//Масштабируем объекты класса Graphics на pictureBox1. //Коэффициенты масштабирования:

float M_1 = 2 * (x_max - x_min); float M_2 = 2 * (y_max - y_min); e->Graphics->ScaleTransform(

Convert::ToSingle(pictureBox1->Width / M_1), Convert::ToSingle(pictureBox1->Height / M_2)); float M_3 = 2 * (-x_min); float M_4 = 2 * (-y_min); e->Graphics->TranslateTransform(M_3, M_4,

MatrixOrder::Prepend); //Задавая M_1, M_2, M_3, M_4 другие значения,

//мы будем смещать линии уровня на pictureBox1. //Объявляем индексы элементов всех массивов: int i, j, k;

//Задаем границы индексов массива myArrayVC(i, j): int N_x = 30000; int N_y = 2;

//Объявляем массив myArrayVC[i, j] пер-х типа float, //когда i = 0,1,2,3,...,(N_x - 1);

// j = 0,1,2,3,...,(N_y - 1): array<float,2>^ myArrayVC =

gcnew array<float,2>(N_x, N_y); //Для считывания из файла

//по адресу D:\\MyDocs\\MyTest_LevelCurves.txt //координат изображения в массив myArrayVC[30000, 2] //создаем объект sr класса StreamReader:

String^ path = "D:\\MyDocs\\MyTest_LevelCurves.txt"; StreamReader^ sr = gcnew StreamReader(path);

Глава 34. Изображение линий уровня на VC++ по данным VC# или VB

165

//Считываем из файла MyTest_LevelCurves.txt //координаты изображения в массив myArrayVC[30000, 2] //при помощи метода ReadLine:

for (i = 0; i <= N_x - 1; i++) for (j = 0; j <= N_y - 1; j++)

myArrayVC[i, j] = Convert::ToSingle(sr->ReadLine()); sr->Close();

//Рисуем изображение по координатам из массива. //Объявляем координаты двух точек:

float x1, y1, x2, y2;

//Будем рисовать пером myPen толщиной 0: Pen^ myPen = gcnew Pen(Color::Black, 0);

//Объявляем переменные для начала N_first_line //и конца N_last_line цикла при рисовании: int N_first_line, N_last_line;

//Передаем переменным для начала и конца цикла //значения первых двух элементов массива myArrayVC: N_first_line = Convert::ToInt32(myArrayVC[0, 0]); N_last_line = Convert::ToInt32(myArrayVC[0, 1]);

//Рисуем изображение, начиная с точки (1,0; 1,1): i = -1;

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

{

i = i + 2;

x1 = myArrayVC[i, 0];

y1 = myArrayVC[i, 1];

x2 = myArrayVC[i + 1, 0];

y2 = myArrayVC[i + 1, 1]; e->Graphics->DrawLine(myPen, x1, y1, x2, y2);

}

}

Глава 35. Изображение объектов на Visual C++, Visual Basic и Visual C++ на основе ин-

теграции по методике “компонент - клиент”

Кратко опишем эти этапы. Сначала создаем проект типа Visual Basic по шаблону Class Library с каким-либо нашим именем и видим файл Class1.vb с двумя строчками для объявления класса:

Public Class Class1 End Class

Далее, как обычно, в самом верху файла Class1.vb мы пытаемся импортировать необходимые для программы пространства имен (как в приведенных выше проектах по шаблону Windows Application), например, такие:

Imports System.Math 'Для математических функций. Imports System.Drawing 'Для рисования изображений. Imports System.Drawing.Drawing2D 'Для рисования.

Листинг 35.1. Метод для расчета массива с координатами точек графика.

Public Class Class1

Public Function myFunction1() As Object

'Объявляем индексы элементов массива myArrayVB(i, j): Dim i, j As Integer

'Задаем границы индексов массива myArrayVB(i, j): Dim N_x As Integer = 2000

Dim N_y As Integer = 1

'Массив переменных Single в виде myArrayVB(i, j), 'когда i = 0,1,2,3,...,N_x; j = 0,1,2,3,...,N_y: Dim myArrayVB(N_x, N_y) As Single

'Задаем произвольное значение 10 в двойном цикле: For i = 0 To N_x

For j = 0 To N_y myArrayVB(i, j) = 10

Next Next

'Произвольные координаты 4-х точек ломаной линии: myArrayVB(0, 0) = 100

myArrayVB(0, 1) = 50 myArrayVB(1, 0) = 200 myArrayVB(1, 1) = 75 myArrayVB(2, 0) = 300 myArrayVB(2, 1) = 150

Глава 35. Изображение на VC++, VB и VC# по методике “компонент-клиент”167

myArrayVB(3, 0) = 400 myArrayVB(3, 1) = 300

Return myArrayVB

End Function

End Class

Листинг 35.2. Процедура PictureBox1_Paint для рисования.

Private Sub PictureBox1_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) _ Handles PictureBox1.Paint

'Объявляем объект myObject класса Class1 компонента VB: Dim myObject As New ComponentVB.Class1

'Объявляем индексы элементов массива myArrayVC(i, j): Dim i, j As Integer

'Задаем границы индексов массива myArrayVC(i, j): Dim N_x As Integer = 2000

Dim N_y As Integer = 1

'Объявляем массив myArrayVC(i, j) переменных типа float, 'когда i = 0,1,2,3,...,(N_x - 1);

'j = 0,1,2,3,...,(N_y - 1):

Dim myArrayVB_Client(N_x, N_y) As Single

'Экспортируем массив myArrayVB(i, j) компонента VB 'в массив myArrayVB_Client(i, j) клиента VB:

For i = 0 To N_x For j = 0 To N_y

myArrayVB_Client(i, j) = myObject.myFunction1(i, j) Next

Next

'Рисуем изображение из массива.

'Объявляем координаты двух граничных точек: Dim x1, y1, x2, y2 As Single

'Будем рисовать пером myPen толщиной 3: Dim myPen As New Pen(Color.Black, 3)

'Рисуем линию, заданную в массиве myArrayVB_Client(i, j): x1 = myArrayVB_Client(0, 0)

y1 = myArrayVB_Client(0, 1)

x2 = myArrayVB_Client(1, 0)

y2 = myArrayVB_Client(1, 1) e.Graphics.DrawLine(myPen, x1, y1, x2, y2) x1 = x2

y1 = y2

x2 = myArrayVB_Client(2, 0)

y2 = myArrayVB_Client(2, 1)

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

e.Graphics.DrawLine(myPen, x1, y1, x2, y2) x1 = x2

y1 = y2

x2 = myArrayVB_Client(3, 0)

y2 = myArrayVB_Client(3, 1) e.Graphics.DrawLine(myPen, x1, y1, x2, y2)

End Sub

Листинг 35.3. Метод pictureBox1_Paint для рисования.

private void pictureBox1_Paint(object sender, PaintEventArgs e)

{

//Объявляем объект myObject кл. Class1 компонента VB: ComponentVB.Class1 myObject =

new ComponentVB.Class1();

//Объявляем индексы элементов массива myArrayVC(i, j): int i, j;

//Задаем границы индексов массива myArrayVC(i, j): int N_x = 2001; int N_y = 2;

//Объявляем массив myArrayVC[i, j] перем-х типа float, //когда i = 0,1,2,3,...,(N_x - 1);

// j = 0,1,2,3,...,(N_y - 1): float[,] myArrayVC = new float[N_x, N_y];

//Объявляем вспомогательный массив myArray класса Array //и связываем его с функцией myFunction1, которая //возвращает массив myArrayVB(i, j) компонента VB: Array myArray = (Array)myObject.myFunction1(); //Экспортируем массив myArrayVB(i, j) компонента VB //в массив myArrayVC[i, j] клиента VC:

for (i = 0; i <= N_x - 1; i++)

for (j = 0; j <= N_y - 1; j++) myArrayVC[i, j] =

Convert.ToSingle(myArray.GetValue(i,j)); //Рисуем изображение из массива.

//Объявляем координаты двух граничных точек: float x1, y1, x2, y2;

//Будем рисовать пером myPen толщиной 3: Pen myPen = new Pen(Color.Black, 3);

//Рисуем линию, заданную в массиве myArrayVC[i, j]: x1 = myArrayVC[0, 0];

y1 = myArrayVC[0, 1];

x2 = myArrayVC[1, 0];

y2 = myArrayVC[1, 1]; e.Graphics.DrawLine(myPen, x1, y1, x2, y2); x1 = x2; y1 = y2;

Глава 35. Изображение на VC++, VB и VC# по методике “компонент-клиент”169

x2 = myArrayVC[2, 0]; y2 = myArrayVC[2, 1]; e.Graphics.DrawLine(myPen, x1, y1, x2, y2); x1 = x2; y1 = y2;

x2 = myArrayVC[3, 0]; y2 = myArrayVC[3, 1]; e.Graphics.DrawLine(myPen, x1, y1, x2, y2);

}

Листинг 35.4. Метод pictureBox1_Paint для рисования.

private:

System::Void pictureBox1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e)

{

//Объявляем объект myObject класса Class1 компонента VB: ComponentVB::Class1^ myObject =

gcnew ComponentVB::Class1();

//Объявляем индексы элементов массива myArrayVC(i, j): int i, j;

//Задаем границы индексов массива myArrayVC(i, j): int N_x = 2001; int N_y = 2;

//Объявляем массив myArrayVC[i, j] переменных типа float, //когда i = 0,1,2,3,...,(N_x - 1);

// j = 0,1,2,3,...,(N_y - 1): array<float,2>^ myArrayVC =

gcnew array<float,2>(N_x, N_y);

//Объявляем вспомогательный массив myArray класса Array //и связываем его с функцией myFunction1, которая //возвращает массив myArrayVB[i, j] компонента VB: Array^ myArray = (Array^)myObject->myFunction1(); //Экспортируем массив myArrayVB(i, j) компонента VB //в массив myArrayVC[i, j] клиента VC:

for (i = 0 ; i <= N_x - 1; i++) for (j = 0 ; j <= N_y - 1; j++)

myArrayVC[i, j] = Convert::ToSingle(myArray->GetValue(i,j));

//Рисуем изображение из массива. //Объявляем координаты двух граничных точек: float x1, y1, x2, y2;

//Будем рисовать пером myPen толщиной 3: Pen^ myPen = gcnew Pen(Color::Black, 3);

//Рисуем линию, заданную в массиве myArrayVC[i, j]: x1 = myArrayVC[0, 0];

y1 = myArrayVC[0, 1];

x2 = myArrayVC[1, 0];

y2 = myArrayVC[1, 1]; e->Graphics->DrawLine(myPen, x1, y1, x2, y2);

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