float ylntercept;
float xStep; // intercept steps
float yStep; 4 int dxTile;
// check for vertical rays if (fabs ( cos ( angle )) < 1 e-7 ) return 10000.0;
if ( angle >= ANGLE_270 || angle <= ANGLE_90 ) {
xTile ++; xStep = 1;
yStep = tan ( angle ); xlntercept = xTile; dxTile = 1;
Компьютерная графика. Полигональные модели
}
else
{
xTile --; xStep = -1;
yStep = -tan ( angle ); xlntercept = xTile + 1; dxTile = -1;
}
// find interception point ylntercept = locY + ( xlntercept - locX ) * tan ( angle );
for(;;) {
yTile = ylntercept;
if ( xTile<0 || xTile>MAX_XTILE )
return 10000.0; if ( yTile<0 || yTile>MAX_YTILE )
return 10000.0; // out of map
if ( map [yTile][xTile] != '') return (xlntercept - locX ) / cos ( angle );
xlntercept += xStep; ylntercept += yStep; xTile += dxTile;
}
}
Аналогично определяется ближайшая точка пересечения луча с горизонтал ми линиями сетки у -jh. Если 0 < а < ж, то х\ = ** + [у\ ~y*\tga*
J>1=(/+1K xi+\ = xi + hctga,
Ум = У( + К а в случае ж < а < 2л х] = х* + (у, - у* ]ctga,
- (/ - iK
^,+1 = xt ~ hctga, Ум = Ух - hСоответствующая проверка осуществляется процедурой
float checkHWalls (float angle )
{
int xTile = (int) locX;
13. Элементы виртуальной реальности
int yTile = (int) locY; float xlntercept; float ylntercept; float xStep; float yStep; int dyTile;
if (fabs ( sin (angle )) < 1 e-7 ) return 10000.0;
if ( angle <= ANGLE J 80) {
yTile ++;
xStep = 1 / tan ( angle ); yStep = 1; ylntercept = yTile;
dyTile = 1;
}
else
{
yTile -; yStep = -1;
xStep = -1 / tan ( angle ); ylntercept = yTile + 1; dyTile = -1;
}
xlntercept = locX + ( ylntercept - locY ) / tan ( angle );
for (;;) {
xTile = xlntercept*
if ( xTileO || xTile >52 || yTiieO || yTile>9 ) return 10000.0;
if ( map [yTiie][xTile] != '')
return ( ylntercept - locY ) / sin ( angle );
xlntercept += xStep; ylntercept += yStep; yTile += dyTile;
}
}
После того как найдены ближайшие точки пересечения луча как с вертикальными, так и с горизонтальными стенами, среди них выбирается наименее удаленная от игрока.