На главную страницу
Форум txt.version   




Статья :: Visual Studio.Net Работа с контейнером

 

Работа с контейнером

Для работы с файлом мы пользовались буфером переменных типа BYTE. Для работы с данными в памяти значительно более удобной структурой данных является динамический контейнер. Мы, как вы помните, выбрали для этой цели контейнер, скроенный по шаблону vector. При заказе на его изготовление указали тип данных для хранения в контейнере. Это объекты класса CPointSD (точки трехмерного пространства). Мы пошли по простому пути и храним в файле только один компонент Y из трех координат точек поверхности в 3D. Остальные две координаты (узлов сетки на плоскости X-Z) будем генерировать на регулярной основе. Такой подход оправдан тем, что изображение OpenGL все равно претерпевает нормирующие преобразования, перед тем как попасть на двухмерный экран. Создание контейнера точек производится в теле функции SetGraphPoints, к разработке которой сейчас и приступим.

На вход функции подается временный буфер (и его размер), в который попали данные из файла. В настоящий момент в буфере находятся данные тестовой поверхности, а потом, при вызове из функции ReadData, в него действительно попадут данные из файла. Выбор данных из буфера происходит аналогично их записи. Здесь мы пользуемся адресной арифметикой, определяемой типом указателя. Так, операция ++ в применении к указателю типа UINT сдвигает его в памяти на sizeof (UINT) байт. Смена типа указателя (на float*) происходит в тот момент, когда выбраны данные о размерах сетки узлов.

Для надежности сначала проверяем данные из буфера на внутреннюю непротиворечивость в смысле размерностей. Затем мы уничтожаем данные контейнера и генерируем новые на основе содержимого буфера. В процессе генерации трехмерных координат точек их ординаты (Y) масштабируются для того, чтобы график имел пропорции, удобные для просмотра:

void COGView::SetGraphPoints(BYTE* buff, DWORD nSize)

{

//====== Готовимся к расшифровке данных буфера

//====== Указываем на него указателем целого типа

UINT *p = (UINT*)buff;

//=== Выбираем данные целого типа, сдвигая указатель

m_xSize = *р; m_zSize = *++p;

//====== Проверка на непротиворечивость

if (m_xSize<2 || m_zSize<2 ||

m_xSize*m_zSize*sizeof(float)

+ 2 * sizeof(UINT) != nSize)

{

MessageBox (_T ("Данные противоречивы") ) ;

return;

}

//====== Изменяем размер контейнера

//====== При этом его данные разрушаются

m_cPoints . resize (m_xSize*m_zSize) ;

if (m_cPoints .empty () )

{

MessageBox (_T ("He возможно разместить данные")

return;

}

//====== Подготовка к циклу пробега по буферу

//====== и процессу масштабирования

float x, z,

//====== Считываем первую ординату

*pf = (float*) ++р,

fMinY = *pf,

fMaxY = *pf,

right = (m_xSize-l) /2 . f ,

left = -right,

read = (m_zSize-l) /2 . f ,

front = -rear,

range = (right + rear) /2. f;

UINTi, j, n;

//====== Вычисление размаха изображаемого объекта

m_fRangeY = range;

m_fRangeX = float (m_xSize) ;

m_fRangeZ = float (m_zSize) ;

//====== Величина сдвига вдоль оси Z

m_zTrans = -1.5f * m_fRangeZ;

//====== Генерируем координаты сетки (X-Z)

//====== и совмещаем с ординатами Y из буфера

for (z=front, i=0, n=0; i<m_zSize; i++, z+=l.f)

{

for (x=left, j=0; j<m_xSize; j++, x+=l.f, n++)

{

MinMax (*pf, fMinY, fMaxY) ;

m_cPoints[n] = CPoint3D(x, z, *pf++) ;

}

}

//====== Масштабирование ординат

float zoom = fMaxY > fMinY ? range/ (fMaxY-fMinY)

: l.f;

for (n=0; n<m_xSize*m_zSize;n++)

{

m_cPoints [n] . у = zoom * (m_cPoints [n] . у - fMinY) - range/2. f;

}

}

При изменении размеров контейнера методом (resize) все его данные разрушаются. В двойном цикле пробега по узлам сетки мы восстанавливаем (генерируем заново) координаты X и Z всех вершин четырехугольников. В отдельном цикле пробега по всему контейнеру происходит масштабирование ординат (умножение на предварительно вычисленный коэффициент zoom). В используемом алгоритме необходимо искать экстремумы функции у = f (x, z). С этой целью удобно иметь глобальную функцию MinMax, которая корректирует значение минимума или максимума, если входной параметр превышает существующие на сей момент экстремумы. Введите тело этой функции в начало файла реализации оконного класса (ChildView.cpp):

inline void MinMax (float d, floats Min, float& Max)

{

//====== Корректируем переданные по ссылке параметры

if (d > Max)

Max = d; // Претендент на максимум

else if (d < Min)

Min = d; // Претендент на минимум

}

 

Visual Studio.Net Работа с контейнером

страницы в данном разделе 
 Visual Studio.Net Урок 7. Трехмерные графики функций  Visual Studio.Net Трехмерные графики функций
 Visual Studio.Net Настройка проекта  Visual Studio.Net Вспомогательный класс
 Visual Studio.Net Реакции на сообщения Windows  Visual Studio.Net Подготовка окна
 Visual Studio.Net Реакция на сообщение о перерисовке  Visual Studio.Net Параметры освещения
 Visual Studio.Net Установка цвета фона  Visual Studio.Net Установка цвета фона
 Visual Studio.Net График по умолчанию  Visual Studio.Net Работа с контейнером
 Visual Studio.Net Чтение данных  Visual Studio.Net Управление изображением с помощью мыши
 Visual Studio.Net Включаем анимацию  Visual Studio.Net Ввод новых команд
 Visual Studio.Net Диалог по управлению светом   


Разделы
Околокомпьютерная литература (375)
Программирование (102)
Программы (75)
ОС и Сети (49)
Интернет (29)
Аппаратное обеспечение (16)
Базы данных (6)

Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)

PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C





 
©  programming-lang.com  справочник программиста