Цитата:
Если можете, пожалуйста, реализуй вращение обычной линии без всяких сцен, просто преобразованием координат из 3d + углы наклона относительно трех осей. Мне фактически нужен только этот пример, а дальше я могу сам.
А в чем проблема-то? Все вроде бы очень просто... Чтобы крутануть отрезок, достаточно крутануть его концы, и все! То есть вам достаточно научиться вращать точку! Если её мировые координаты суть компоненты вектора
, то для получения экранных координат (компонент
) вам нужно просто умножить её слева на подходящую матрицу поворота (обозначим её
, где
-- радианные углы поворота вокруг соответствующих осей), возможно дополнив преобразование некоторым смещением на вектор
, т.е.
.
Для рисования куба вам будет достаточно крутить 8 точек, а потом соединять их образы на экране отрезками.
Для справки, матрица
может быть определена как
, где
,
, и
-- матрицы поворота вокруг осей
,
и
, соответственно.
Матрицы вычисляются лишь при смене углов, а затем используются многократно для вращения точек. Элементарно.
Кстати, после таких преобразований ваша 3d-графика будет смотреться не очень хорошо. Это можно исправить добавив эффект перспективы. Все очень просто, когда вы получите экранные координаты, например
,
,
, просто умножьте каждую из них на
, где
-- расстояние от экрана до сцены (можно подобрать экспериментально).
Потом подумайте об отсечении невидимых (экранированных) примитивов, освещении, и т.д.
-- Пт окт 09, 2009 22:32:21 --Перед тем, как честно и аккуратно реализовать необходимые операции линейной алгебры вы можете запрототипировать проецирование, что позволит поиграться с 3d уже через пару минут кодинга.
Псевдокод (здесь не учитывается трансляция, зато добавлен параметр, управляющий масштабированием, позволяющим хорошо разглядеть сцену):
Код:
Project(Vertex, Angle, Scale)
{
// Introduce short aliases.
sinx = sin(Angle->x);
siny = sin(Angle->y);
sinz = sin(Angle->z);
cosx = cos(Angle->x);
cosy = cos(Angle->y);
cosz = cos(Angle->z);
x = Vertex->x;
y = Vertex->y;
z = Vertex->z;
// Rotate it!
yx = y*cosx + z*sinx;
zx = z*cosx - y*sinx;
xy = x*cosy + zx*siny;
zy = zx*cosy - x*siny;
xz = xy*cosz + yx*sinz;
yz = yx*cosz - xy*sinz;
// Final step.
Vertex->u = Canvas->Width/2+xz*Scale;
Vertex->v = Canvas->Height/2+yz*Scale;
// Now we have the desired point at (u,v) on the screen.
}
Примерно так.