вот что я написал в opengl.основной алгоритм должен быть одинаковым на любом языке.следующие вещи, которые вам нужны:
вектор повышения длины единицы (где up определяется, если вы смотрите в центр): (upx, upy, upz)
origin (место, где высмотрите:) (ox, oy, oz)
положение камеры (где находится ваша камера): (cx, cy, cz)
предположим, что «del» - это количество, которое вы хотитедвигаться, и что
norma() = (ox-cx, oy-cy, oz-cz)/sqrt( (ox-cx) * (ox-cx) + (oy-cy) * (oy-cy) + (oz-cz) * (oz-cz) )
после этого, вы можете рассчитать «вперед» вектор.то есть вектор, который является единицей длины и указывает от вас к центру через:
(fox, foy, foz) = (ox-cx, oy-cy, oz-cz)/norma();
, вы можете затем вычислить единицу «левого» вектора, то есть вектор, указывающий налево от длины единицыесли вы смотрите в центр:
lx = foz*upy-foy*upz;
ly = fox*upz-foz*upx;
lz = foy*upx-fox*upy;
, то вы можете написать следующие подпрограммы (каждая оригинальная буква «//» влево означает новую подпрограмму)
// move camera forward
cx = cx + del*fox;
cy = cy + del*foy;
cz = cz + del*foz;
// move camera backward
cx = cx - del*fox;
cy = cy - del*foy;
cz = cz - del*foz;
// rotate figure right
cx0 = cx; // initial position
cy0 = cy;
cz0 = cz;
R1 = norma(); // initial distance
cx = cx + del*lx;
cy = cy + del*ly;
cz = cz + del*lz;
R2 = norma(); // new distance after moving in up direction
cx = cx + (R2-R1)*fox;
cy = cy + (R2-R1)*foy;
cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same
// new "left" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
lx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
ly = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
lz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
// rotate left
cx0 = cx; // initial position
cy0 = cy;
cz0 = cz;
R1 = norma(); // initial distance
cx = cx - del*lx;
cy = cy - del*ly;
cz = cz - del*lz;
R2 = norma(); // new distance after moving in up direction
cx = cx + (R2-R1)*fox;
cy = cy + (R2-R1)*foy;
cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same
// new "left" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
lx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
ly = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
lz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
// rotate figure up
cx0 = cx; // initial position
cy0 = cy;
cz0 = cz;
R1 = norma(); // initial distance
cx = cx + del*upx;
cy = cy + del*upy;
cz = cz + del*upz;
R2 = norma(); // new distance after moving in up direction
cx = cx + (R2-R1)*fox;
cy = cy + (R2-R1)*foy;
cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same
// new "up" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
upx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
upy = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
upz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
// rotate figure down
cx0 = cx; // initial position
cy0 = cy;
cz0 = cz;
R1 = norma(); // initial distance
cx = cx - del*upx;
cy = cy - del*upy;
cz = cz - del*upz;
R2 = norma(); // new distance after moving in up direction
cx = cx + (R2-R1)*fox;
cy = cy + (R2-R1)*foy;
cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same
// new "up" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
upx = (cx0-cx)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
upy = (cy0-cy)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
upz = (cz0-cz)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
// move fig down
cx = cx + del*upx;
cy = cy + del*upy;
cz = cz + del*upz;
ox = ox + del*upx;
oy = oy + del*upy;
oz = oz + del*upz;
// move fig up
cx = cx - del*upx;
cy = cy - del*upy;
cz = cz - del*upz;
ox = ox - del*upx;
oy = oy - del*upy;
oz = oz - del*upz;
// move fig left
cx = cx + del*rx;
cy = cy + del*ry;
cz = cz + del*rz;
ox = ox + del*rx;
oy = oy + del*ry;
oz = oz + del*rz;
// move fig right
cx = cx - del*rx;
cy = cy - del*ry;
cz = cz - del*rz;
ox = ox - del*rx;
oy = oy - del*ry;
oz = oz - del*rz;