ПРОГРАМИРУЕМ 3D ГРАФИКУ ИСПОЛЬЗУЯ DirectX




Проверка попадания - часть 10


// Преобразовать каждую вершину к экранным координатам double dZ = 0;

for (int v = 0; v « nVert; v++) {

// Получить вектор в локальных координатах

// (координатах фрейма)

m_hr = pIFace-»GetVertex(v, &lv, NULL) ;

ASSERT(SUCCEEDED(m_hr)) ;

// Преобразовать их в мировые координаты m_hr = m_pIFrame-»Transform(&wv, &lv) ;

ASSERT(SUCCEEDED(m_hr)) ;

// Преобразовать мировые координаты // в экранные

m_hr = pIViewport-»Transform(&sv, &wv) ;

ASSERT(SUCCEEDED(m_hr)) ;

// Преобразовать однородные координаты

// в абсолютные координаты пикселей

double w = sv.w;

if (w != 0) {

pScrnVert[v].x = (int) sv.x / w;

pScrnVert[v].у = (int) sv.y / w;

dZ += sv.z / w;

) else {

pScrnVert[v].x = 0;

pScrnVert[v].у = 0;

} } dZ /= nVert;

// Проверить, лежит ли точка попадания внутри // многоугольника на экране

if (::_3dPointInPolygon(pScrnVert, nVert, pt)) { if (iHitFace « 0) { iHitFace = i;

dHitZ = dZ;

} else (

if (dZ « dHitZ) {

iHitFace = i;

dHitZ •= dZ;

} } )

// Освободить грань после завершения delete [] pScrnVert;

Выделение отдельной грани 'тЩ 175

pIFace-»Release () ;

}

// Установить возвращаемое значение *piFace = iHitFace;

return TRUE;

}

Некоторые фрагменты кода опущены для экономии места, а также потому, что я хочу оставить их для дальнейшего обсуждения. Найдите то место, в котором координаты вершин преобразуются в однородный вектор. Давайте задержимся на нем.

Однородный вектор состоит из координат х, у, z и w. К чему так много координат, когда для представления точки в окне достаточно х и у? Причина заключается в том, что если вершина окажется очень близко к камере, то преобразование, отображающее координаты на плоскость вида, приведет к состоянию, близкому к делению на ноль, — разумеется, это нежелательно. Использование однородного вектора для представления результата позволяет избежать деления на ноль (поверьте мне на слово или покопайтесь в справочниках). При наличии однородного вектора мы вычисляем координаты точки в окне делением координат х, у и z на величину w. Если значение w равно нулю, мы считаем, что результат совпадает с точкой 0, 0. Но для чего нам нужно значение z? Разве точка на экране может обладать координатой z? Нет, не может, однако по координате z можно судить о положении на оси z той грани, которую мы проектируем на плоскость вида. С помощью этой информации мы выберем из множества возможных граней, содержащих точку попадания, ту, что находится ближе остальных.




Содержание  Назад  Вперед