Навигация по поверхности гиперсферы в OpenGL - PullRequest
2 голосов
/ 01 марта 2011

Может быть, это вписывается в math.stackexchange.com, но, поскольку я программирую это в OpenGL, я спрошу это здесь.

У меня была идея игры в космический корабль, где мир ограничен на поверхности4-D гиперсферы (также называемой 3-сферой).Таким образом, видя его изнутри, он выглядел бы как трехмерный мир, но, перемещаясь во всех направлениях, я бы никогда не покинул ограниченный объем трехмерной сферы.

Чтобы представить трехмерный шарв качестве «плоского» трехмерного пространства я использую стереографическую проекцию, которую очень просто реализовать в качестве шейдера GLSL, просто нужно разделить входной вектор на один минус его координату w.

Для представлениявершины объектов Я использую нормализованные 4d векторы, так что x² + y² + z² + w² = 1, таким образом, удерживая их внутри 3-сферы.

Первая проблема, которую нужно решить, это вращение.Но вскоре я понял, что обычных трехмерных матриц вращения будет достаточно, чтобы вращать мир вокруг зрителя в трехмерной проекции, поскольку он не портится с координатой w (почти как вращение сферы вокруг оси z также вращает еестереографическая проекция).

Затем я понял, что вращение вдоль оси w будет эквивалентно переводу внутри 3d-проекции (просто не коммутативно, как обычные 3d-переводы в «плоских» пространствах), тогда я мог бы перемещаться вдольось, используя простую матрицу вращения вокруг оси (x ', y') = (x * cos a - y * sin a, x * sin a + y * cos a), но изменяя w вместе с другой осью.

Это так далеко, куда я попал, и я не мог понять, как двигаться вперед, основываясь на положении, в котором зритель смотрит из проекции.Я могу применить обратное преобразование для получения нормализованного 4-D вектора (называемого F), с которым зритель сталкивается в координатах гиперсферы, но я не знаю, как перемещаться в этом направлении с помощью матрицы 4x4 (что является оптимальным в OpenGL).Я мог бы подумать о хакерском решении: для каждой вершины V сделать V '= normalize (d * F + V), где d - расстояние, пройденное вперед (в какой-то странной единице я не могу точно определить).Этот способ работает только для малых значений d, прямой зависимости между d и изменением угла не существует.

Таким образом, вопрос заключается в следующем: как двигаться вперед (используя матричное преобразование 4x4), находясь на поверхности4-D гиперсфера?

Ответы [ 3 ]

6 голосов
/ 01 марта 2011

Оказывается, я написал несколько статей в этой области некоторое время назад.Этот ( Интерактивные методы визуализации для четырех измерений ) наиболее близко относится к вашей конкретной проблеме, но другие документы, которые ссылаются на эту проблему, также могут помочьВ этом конкретном приложении я вращал объект, наблюдаемый в 4D, а не зритель, но математика эквивалентна.

Относительно этого конкретного вопроса:

Таким образом, вопрос таков:как двигаться вперед (используя матричное преобразование 4x4), находясь на поверхности четырехмерной гиперсферы?

Если вы перемещаетесь по поверхности гиперсферы, вы не переводите в ш .На самом деле вам нужно двигаться в сферической геометрии вокруг большого круга единичного радиуса.Это означает, что, если вы можете построить соответствующие оси для вашей системы отсчета, вы можете сферически интерполировать между тем, где вы находитесь и куда вы идете.

Например, одна конструкция, которая можетбыть использованным для такого шага, можно было бы использовать единичный вектор, который указывает прямо вперед (ваша точка обзора, aka p_1 в уравнении Википедии), векторную точку вне макушки головы (p_0) ивектор, указывающий из правого уха (чтобы создать правую систему координат).

Если вы затем отслеживаете свою скорость по сфере по угловой скорости, а не по линейной, вы можете просто ввести значение для t (прошедшее время) в Википедии, чтобы найти ваше новое угловое положение.

Обратите внимание, что это уравнение не ограничивает число компонентов в вершине p.Сферическая интерполяция работает в любой геометрии.

РЕДАКТИРОВАТЬ (отвечая на вопросы в комментариях):

Slerp, кажется, не так, потому что я делаюне хочу интерполировать вращение между 2 векторами с течением времени.Вместо этого на каждом временном шаге я хочу перемещать каждую вершину в противоположном направлении, в котором зритель движется в этот момент.Таким образом, я нахожусь в позиции (0, 0, 0, 1) и хочу быть в (sqrt (2) / 2, sqrt (2) / 2, 0, 0) в следующем кадре.

Думайте об этом так: ваша позиция на сфере (любого измерения) - это вектор, который перемещает вас из центра на поверхность.Если вы двигаетесь с определенной угловой скоростью, это ставит вас в положение p0 и время t0, p1 в момент времени t1 и т. Д. Slerp - это удобный способ расчета этих позиций в определенное время.

Аналогично,Ваша линия визирования - это вектор под прямым углом к ​​вектору смещения.Линия визирования v0 в момент времени t0, v1 в момент времени t1 и так далее.Slerp снова полезен для вычисления этого вектора.

Как построить соответствующую матрицу преобразования, чтобы каждая вершина умножалась на ее обратную?

Использованиеэти два вектора, ортогонализация дает вам третий, и теперь у вас есть новая система отсчета.Существует одиночный кватернион, который определяет поворот от вашей исходной системы отсчета до этой новой.Это то, что вы ищете.

ОДНАКО , прежде чем вы сможете визуализировать свой мир на двухмерном экране, вам сначала нужно отрендерить его с 4D до 3D.OpenGL (что неудивительно) не поддерживает это напрямую.

Чтобы понять почему, посмотрите на матрицу перспективной проекции .Предполагается, что вы визуализируете однородные точки в трехмерном пространстве: x, y, z находятся в первых трех компонентах, а w (коэффициент масштабирования) - в четвертом.w = 0 указывает на вектор, тогда как w = все остальное указывает на точку.w = что-либо, кроме 1, является ненормализованной точкой.

Таким образом, нет способа визуализировать точку в 4D-начале (0, 0, 0, 0).

Как видно из конструкции матрицы, сделать матрицу проекции 4D в 3D несложно. Примените это сначала к вашей геометрии, установленной независимо от матричного конвейера OpenGL. Тогда вы можете использовать стандартные матрицы OpenGL для 3D на экран.

1 голос
/ 15 марта 2011

Я задавал тот же вопрос на math.stackexchange.com, потому что вопрос слишком математический, и я мог бы получить лучший ответ там. Посмотрите здесь , если вас интересует оригинальный ответ, который я на самом деле использовал.

Находясь в 4D, нет ни одного вектора, перпендикулярного любому вращению, а фактически целой плоскости перпендикулярных векторов, и это меня смутило.

Кроме того, в OpenGL я вскоре понял, что могу упростить вычисление данного решения, потому что я всегда мог предположить, что я нахожусь в начале проекции 4D (0,0,0, -1), всегда обращен к (0 , 0, -1,0), затем переведите заданный угол вдоль z и w и умножьте его на уже накопленный GL_MODELVIEW_MATRIX из предыдущего кадра. Поэтому я сделал MODELVIEW <= M x MODELVIEW вместо MODELVIEW <= MODELVIEW x M, я бы получил, если бы просто позвонил glMultMatrix(M).

1 голос
/ 01 марта 2011

Вам, вероятно, понадобятся матрицы 5x5, так как вы работаете в четырехмерном пространстве. Идея однородных координат состоит в том, чтобы ввести дополнительное измерение для представления аддитивных операций с помощью линейного оператора.

Мне действительно нравится ваша идея, но просто из любопытства: почему бы просто не определить циклическое 3-пространство, то есть обернуть координаты в данное значение. Используя геометрический шейдер, вы можете дублировать те вершины примитивов, которые обертываются вокруг (вы должны обрезать и переместить обрезанную вершину вместе с введенными вспомогательными вершинами к противоположному концу пространства). Это может привести к некоторому эффекту залы зеркал, поэтому вам также придется ввести какой-то горизонт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...