Всем привет. Это сюжетное продолжение вопроса, язык также не принципиален.
Есть плоскость - проекция мира("камера"), задана точкой PP:{x,y,z} и нормалью PV:{x,y,z}. Абсолютный рандом.
Все точки(массив) - тоже P[N]:{x,y,z}. Точки заведомо принадлежат плоскости.
Ситуация: мир готов, спроецирован на камеру и ожидает показа. Нужно только выдрать с камеры 2Д-координаты относительно PP.
Суть вопроса: как повернуть плоскость(т.е. массив), чтобы PP совпала с {0,0,0}, а сама плоскость с OXY? Перетащить плоскость могу сам, квест - повернуть.
Мои мысли:
по матрицам поворота (некоммутативность поворота мне не обломает всю малину?)
как-то исходя из вектора P[N]-PP (мысль бьется в голову, но не оформляется)
я уверен, что есть простое решение)
Я явно где-то туплю =) Хотя есть подозрение, что это очередная глобальная проблема движков.
Если задача (вытащить координаты) проще решается другим способом, я не расстроюсь)
ЗЫ: очень прошу, как можно меньше матриц
Ответ
В общем случае для камеры не хватает третьего вектора, т.к. существует бесконечное множеcтво векторов, ортогональных PV. Поэтому необходим третий вектор PU - обычно указывающий вверх относительно камеры.
Поворот мира относительно камеры (вид камеры) определяется (в правосторонней системе координат, векторах-строках) как:
l = PV;
r = PU x l; // подразумевается векторное умножение
u = PU;
// так называемая LookAt матрица
( rx, ux, lx, 0 )
( ry, uy, ly, 0 )
v_view = v * ( rz, uz, lz, 0 )
( -dot(r, PP), -dot(u, PP), -dot(l, PP), 1 )
где вектор v - изначальное положение точки в мире, v_view - положение точки если смотреть на неё из камеры. Подразумевается, что вектора PV и PU имеют длину, равную 1.
Линейные преобразования (хотя в данном случае аффинные) удобнее всего описывать именно матрицей, т.к. это представление всегда существуют для любого такого преобразования, да и работать с ними удобно.
UPD: Отвечаю на комментарий о применении матриц к векторам.
Данная тема входит в курс линейной алгебры, однако можно почитать об этом отдельно: Умножение матриц
Вектор в 3D обычно (но не всегда) это матрица-строка размера 1x4 вида (X, Y, Z, 1).
Четвёртый компонент-единица необходим для однородности координат; это позволяет умножением на матрицу сдвигать вектор на некоторый другой.
Рассмотрим пример: пусть есть вектор h = (hx, hy, hz). Тогда после умножения на указанную выше матрицу A результатом преобразования будет:
h_view = h * A = (h_view_x, h_view_y, h_view_z, 1)
// четвёртая компонента в данном случае не важна
// и после умножения остаётся равной 1
h_view_x = hx * rx + hy * ry + hz * rz - dot(r, PP) // новый X
h_view_y = hx * ux + hy * uy + hz * rz - dot(u, PP) // новый Y
h_view_z = hx * lx + hy * ly + hz * lz - dot(l, PP) // новый Z
Комментариев нет:
Отправить комментарий