Страницы

Поиск по вопросам

вторник, 16 июля 2019 г.

Поворот плоскости в пространстве

Всем привет. Это сюжетное продолжение вопроса, язык также не принципиален.
Есть плоскость - проекция мира("камера"), задана точкой 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

Комментариев нет:

Отправить комментарий