YellowAfterlife |
25.06.2011 15:10 |
Ответ: Проекция 3D
Преобразование 3d координат точки в 2d координаты на экране.
Пример на п̶с̶е̶в̶д̶о̶к̶о̶д̶е GameMaker:
Функция задания проэкции (вызывать при смене позиции камеры):
Код:
/* argument[] - массив переданных в функцию параметров
P.S.: практически все переменные из этой функции должны быть глобальными */
/*
0..2 координаты источника камеры (откуда смотрит)
3..5 координаты цели камеры (куда смотрит)
6..8 вектор "нормали" камеры (можно просто поставить 0,0,1)
*/
/*
p3d_set_projection(
0 xFrom
1 yFrom
2 zFrom
3 xTo
4 yTo
5 zTo
6 xUp
7 yUp
8 zUp
9 arc = 60
A view = 0
)
*/
_sx = argument[0]
_sy = argument[1]
_sz = argument[2]
_sw = view_wview[argument[10]] /* ширина экрана */
_sh = view_hview[argument[10]] /* высота экрана */
_sa = _sw / _sh
// delta:
_dx = argument[3] - _sx
_dy = argument[4] - _sy
_dz = argument[5] - _sz
// delta vector length:
_dl = sqrt(_dx * _dx + _dy * _dy + _dz * _dz)
// divide by length to get 1-long vector:
_dx /= _dl
_dy /= _dl
_dz /= _dl
// xyzUp:
_nx = argument[6]
_ny = argument[7]
_nz = argument[8]
//
_nn = _dx * _nx + _dy * _ny + _dz * _nz
// subtract from xyzUp:
_nx -= _dx * _nn
_ny -= _dy * _nn
_nz -= _dz * _nn
// xyzUp length:
_nl = sqrt(_nx * _nx + _ny * _ny + _nz * _nz)
_am = tan(argument[9] * pi / 360)
//
_nx *= _am / _nl
_ny *= _am / _nl
_nz *= _am / _nl
//
_vx = (_dz * _ny - _dy * _nz) * _sa
_vy = (_dx * _nz - _dz * _nx) * _sa
_vz = (_dy * _nx - _dx * _ny) * _sa
Преобразование координат:
Код:
/* px, py - глобальные переменные. можно заменить на возврат структуры Point {x, y }*/
/*
p3d_vertex(offset, x, y, z)
*/
var tx, ty, tz, tl, tt, ti;
ti = argument[0]
tx = argument[1] - _sx
ty = argument[2] - _sy
tz = argument[3] - _sz
tl = tx * _dx + ty * _dy + tz * _dz
//
tx /= tl
ty /= tl
tz /= tl
//
tt = (tx * _vx + ty * _vy + tz * _vz) / sqr(_sa * tan(pi / 8))
px[ti] = (tt + 1) * _sw / 2
tt = (tx * _nx + ty * _ny + tz * _nz) / sqr(tan(pi / 8))
py[ti] = (1 - tt) * _sh / 2
Для рисования, используем вторую функцию для занесения преобразованных координат точки в массив, и потом рисуем это как-либо:
Код:
p3d_vertex(0, 0, 0, 0)
p3d_vertex(1, 256, 0, 0)
p3d_vertex(3, 0, 256, 0)
p3d_vertex(2, 256, 256, 0)
for (i = 0; i < 4; i += 1)
draw_line(px[i], py[i], px[(i + 1) mod 4], py[(i + 1) mod 4])
Отредактировано: кажется, я зря писал это сообщение и добавлял комментарии в код.
(по крайней мере я пытался помочь)
|