Работа с контейнером Для работы
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; // Претендент на минимум
}