添加旋轉(zhuǎn)
按照上面的算法我們只能看到北面。不同的角度需要多行代碼來(lái)旋轉(zhuǎn)坐標(biāo)。
def Render(p, phi, height, horizon, scale_height, distance, screen_width, screen_height):
# precalculate viewing angle parameters
var sinphi = math.sin(phi);
var cosphi = math.cos(phi);
# Draw from back to the front (high z coordinate to low z coordinate)
for z in range(distance, 1, -1):
# Find line on map. This calculation corresponds to a field of view of 90°
pleft = Point(
?。?cosphi*z - sinphi*z) + p.x,
?。?sinphi*z - cosphi*z) + p.y)
pright = Point(
( cosphi*z - sinphi*z) + p.x,
?。?sinphi*z - cosphi*z) + p.y)
# segment the line
dx = (pright.x - pleft.x) / screen_width
dy = (pright.y - pleft.y) / screen_width
# Raster line and draw a vertical line for each segment
for i in range(0, screen_width):
height_on_screen = (height - heightmap[pleft.x, pleft.y]) / z * scale_height. + horizon
DrawVerticalLine(i, height_on_screen, screen_height, colormap[pleft.x, pleft.y])
p1eft.x += dx
p1eft.y += dy
# Call the render function with the camera parameters:
# position, viewing angle, height, horizon line position,
# scaling factor for the height, the largest distance,
# screen width and the screen height parameter
Render( Point(0, 0), 0, 50, 120, 120, 300, 800, 600 )
123456789101112131415161718192021222324252627282930313233
更多的性能說(shuō)明
當(dāng)然,要想達(dá)到更高的性能,還有很多小技巧可以使用。
與從后面到前面繪制相比,從前面到后面進(jìn)行繪制會(huì)更好。優(yōu)點(diǎn)之一就是我們不必每次都因?yàn)檎趽醵枰谄聊坏牡撞慨嬀€。但是,為了保證遮擋,我們需要一個(gè)額外的Y緩沖區(qū)。對(duì)于每一列來(lái)說(shuō),相當(dāng)于y的最高位置已經(jīng)存儲(chǔ)了。因?yàn)槲覀兪前凑諒那懊娴胶竺孢@個(gè)順序進(jìn)行繪制的,那么下一行的可見(jiàn)部分只能大于先前繪制的最高行。
詳細(xì)的渲染程度。前面的細(xì)節(jié)渲染多一點(diǎn),遠(yuǎn)處的細(xì)節(jié)渲染的少一點(diǎn)。
def Render(p, phi, height, horizon, scale_height, distance, screen_width, screen_height):
# precalculate viewing angle parameters
var sinphi = math.sin(phi);
var cosphi = math.cos(phi);
# initialize visibility array. Y position for each column on screen
ybuffer = np.zeros(screen_width)
for i in range(0, screen_width):
ybuffer[i] = screen_height
# Draw from front to the back (low z coordinate to high z coordinate)
dz = 1.
z = 1.
while z 《 distance
# Find line on map. This calculation corresponds to a field of view of 90°
pleft = Point(
?。?cosphi*z - sinphi*z) + p.x,
?。?sinphi*z - cosphi*z) + p.y)
pright = Point(
?。?cosphi*z - sinphi*z) + p.x,
?。?sinphi*z - cosphi*z) + p.y)
# segment the line
dx = (pright.x - pleft.x) / screen_width
dy = (pright.y - pleft.y) / screen_width
# Raster line and draw a vertical line for each segment
for i in range(0, screen_width):
height_on_screen = (height - heightmap[pleft.x, pleft.y]) / z * scale_height. + horizon
DrawVerticalLine(i, height_on_screen, ybuffer[i], colormap[pleft.x, pleft.y])
if height_on_screen 《 ybuffer[i]:
ybuffer[i] = heightonscreen
p1eft.x += dx
p1eft.y += dy
# Go to next line and increase step size when you are far away
z += dz
dz += 0.2
# Call the render function with the camera parameters:
# position, viewing angle, height, horizon line position,
# scaling factor for the height, the largest distance,
# screen width and the screen height parameter
Render( Point(0, 0), 0, 50, 120, 120, 300, 800, 600 )
評(píng)論
查看更多