размещение объектов перпендикулярно поверхности сферы, имеющей волнистую поверхность - PullRequest
1 голос
/ 06 мая 2020

Итак, у меня есть сфера. Он вращается вокруг заданной оси и изменяет свою поверхность функцией sin * cos. У меня также есть куча трактикоидов в фиксированных точках сферы. Эти объекты следуют за сферой при движении (включая вращение и изменение поверхности). Но я не могу понять, как сделать их всегда перпендикулярными сфере. У меня есть точки, где трактикоид соединяется с поверхностью сферы и ее вектором нормали. Трактикоиды изначально ориентированы по оси z. Итак, я попытался сделать его осью относительно данного вектора нормали, но у меня просто не получалось заставить его работать.

Здесь я вычисляю матрицу преобразования M и ее обратную:

virtual void SetModelingTransform(mat4& M, mat4& Minv, vec3 n) {
            M = ScaleMatrix(scale) * RotationMatrix(rotationAngle, rotationAxis) * TranslateMatrix(translation);
            Minv = TranslateMatrix(-translation) * RotationMatrix(-rotationAngle, rotationAxis) * ScaleMatrix(vec3(1 / scale.x, 1 / scale.y, 1 / scale.z));
    }

В моей функции рисования я устанавливаю значения для преобразования. _M и _Minv - это матрицы сферы, поэтому трактикоиды следуют за сферой, но когда я попытался использовать матрицу вращения, трактикоиды начали двигаться по поверхности сферы. _n - нормальный вектор, которому должен следовать трактикоид.

void Draw(RenderState state, float t, mat4 _M, mat4 _Minv, vec3 _n) {
        SetModelingTransform(M, Minv, _n);
        if (!sphere) {
            state.M = M * _M * RotationMatrix(_n.z, _n);
            state.Minv = Minv * _Minv * RotationMatrix(-_n.z, _n);
        }
        else {
            state.M = M;
            state.Minv = Minv;
        }
        .
        .
        .
    }

Ответы [ 2 ]

0 голосов
/ 08 мая 2020

Я не уверен, получил ли я ваши объяснения, но здесь я go.

У вас есть сфера с волнистой поверхностью. Это означает, что каждая точка на поверхности изменяет свое расстояние до центра сферы, как кусок дерева на волне в море меняет расстояние до морского дна в этом месте.
Мы можем сказать, что радиус R сферы меняется в каждый момент времени.

Теперь у вас есть трактикоид (что такое трактитоид?). Я приму это как некий объект, плывущий по волне и следящий за движением сферы.

Тогда, кажется, вы спрашиваете, как заставить трактикоид следовать как волнистой поверхности, так и движению сферы.

Хорошо. Если мы определяем каждое движение («преобразование») матрицей 4x4, все сводится к объединению в правильном порядке этих матриц.

Есть несколько хороших руководств по OpenGL, которые научат вас преобразованиям и их сочетанию. См., Например, Learnopengl.com .

В вашем случае можно использовать несколько преобразований.

Сфера вращается. Вам нужна матрица вращения, назовем ее MSR (вращение сферы матрицы) и ось вращения ASR. Если сфера также перемещается, то также требуется MST.
Поверхностные волны с некоторой функцией f(lat, long, time), которая вычисляет для этих параметров приращение (знак) радиуса. Итак, Ri = R + f(la,lo,ti)

Для трактикоида, я думаю, у вас есть несколько треугольников, которые определяют трактикоид. Я также предполагаю, что эти треугольники выражены в «локальной» системе координат, начало которой лежит в центре трактикоида. Проблема возникает, когда вам нужно расположить и повернуть трактикоид, верно?

У вас есть два варианта. Первый - повернуть трактикоид так, чтобы он был направлен перпендикулярно сфере, а затем переместил его, чтобы следовать за вращением сферы. Хотя этот вариант идеален с математической точки зрения, я считаю этот вариант сложным.

Лучший вариант - заставить трактикоид вращаться и сдвигаться точно так же, как и сфера, как если бы оба они имели одно и то же начало - центр сферы. А затем переведите его в текущее положение.

Первая часть довольно проста: матрица, определяющая такое преобразование, - M= MST * MSR, если вы используете типичное соглашение об осях OpenGL, в противном случае вам нужно поменять их порядок. Это M является общей частью для всех объектов (сфера и трактикоиды).

Вторая часть требует, чтобы у вас был вектор Vn, который определяет точку на поверхности, связанную с центром сферы. Вы должны быть в состоянии вычислить его с параметрами широты, долготы и R, полученными с помощью f() выше, плюс размер / 2 трактикоида (расстояние от его центра до точки, где он касается волны). Используйте компоненты Vn, чтобы построить матрицу трансляции MTT

А теперь просто заставьте полученное преобразование использовать с каждой вершиной трактикоида: Mt = MTT * M = MTT * MST * MSR

Для рендеринга сцены вам понадобятся две другие матрицы: для камеры (MV) и для проекции (MP). В то время как Mt соответствует каждому трактикоиду, MV и MP одинаковы для всех объектов, включая саму сферу.

0 голосов
/ 07 мая 2020

Вы сказали, что ваша сфера имеет ось вращения, поэтому у вас должен быть вектор a, выровненный с этой осью.

Пусть P = P(t) будет точкой на сфере, в которой расположен ваш объект. У вас также должен быть вектор n = n(t), перпендикулярный поверхности сферы в точке P=P(t) для каждого момента времени t. Все векторы интерпретируются как векторы-столбцы, т.е. матрицы 3 x 1.

Затем сформируйте матрицу

U[][1] = cross(a, n(t)) / norm(cross(a, n(t)))
U[][3] = n(t) / norm(n(t))  
U[][2] = cross(U[][3], U[][1])

, где для каждого j=1,2,3 U[][j] будет векторный столбец 3 x 1. Тогда

U(t) = [ U[][1], U[][2], U[][3] ]

- это ортогональная матрица 3 x 3 (т.е. это трехмерное вращение вокруг начала координат)

Для каждого момента времени t вычислить матрицу

M(t) = U(t) * U(0)^T

, где ^T - транспонирование матрицы.

Окончательное преобразование, которое поворачивает ваш объект из исходного положения в его положение во время t, должно быть

X(t) = P(t) + M(t)*(X - P(0))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...