Существует модификация описанного подхода, когда сразу проверяются все пересечения луча, без отдельного рассмотрения пересечений с вертикальными и горизонтальными стенами. При этом последовательный переход из клетки в клетку осуществляется до тех пор, пока не будет найдена непустая клетка.
Подобный подход и был реализован в игре Wolfenstein 3-D. Вариант подобного подхода можно найти на компакт-диске.
Однако данный подход заметно сложнее предложенного выше, почти не отличаясь от него по быстродействию.
Компьютерная графика. Полигональные модели Рассмотрим теперь, каким образом по найденному расстоянию d до точки пересечения строится соответствующий столбец пикселов.
Пусть глаз наблюдателя расположен по высоте посередине между полом и потолком и расстояние от игрока до картинной плоскости равно/(см. рис. 13.3). Тогда столбцу пикселов на картинной плоскости соответствует отрезок АВ, состоящий из трех частей: проекции потолка АС, проекции пола DB и собственно проекции стены CD, причем АС = DB. Длина отрезка CD (высота проекции стены в пикселах) легко находится из равенства
. SCREEN __ HEIGHT'* f
' . SCREEN HEIGHT*/ CD =-=--,
d
SCREEN HEIGHT - CD
AC = DB =-=-
Простейший вариант программы, реализующий описанный алгоритм, приведен ниже.
void drawView () {
float phi; float distance;
totalFrames++;
for (int col = 0; col < SCREENJ/VIDTH; col++ ) {
phi = angle + rayAngle [col]; if ( phi < 0 )
phi += 2 * M_PI;
else
if ( phi >= 2 * M_PI ) phi -= 2 * M_PI;
float d1 = checkVWalls ( phi); float d2 = checkHWalls ( phi );
distance = d1;
if ( d2 < distance ) distance = d2;
distance *= cos ( phi - angle ); drawSpan (distance, WALL_COLOR, col);
}
}
Для задания углов лучей здесь используется массив ray^ngle - для каждого луча указан угол между направлением луча и направлением взгляда игрока. Наиболее простым способом описания этого массива является задание углов с постоянным шагом, но, так как этот способ вызывает некоторые искажения, рекомендуется следующий метод:
rayAngle[i]-arctg(tg(VIEW_ANGLE/2)*(l-fi/(SCREEN_WIDTH-l))) Приводимая ниже программа реализует данный алгоритм. // File wolfl.cpp