Как вертеть, крутить, спирали в размерах выше 2D

У меня есть код, подобный следующему в C ++:

for(int x = position.x; x < position.x + dimensions.x; ++x)
{
for(int y = position.y; y < position.y + dimensions.y; ++y)
{
glm::vec2 tc = glm::vec2(x,y);
tc -= spiralPosition;
float distance = glm::length(tc-position);
if(distance < spiralRadius)
{
float percent = (spiralRadius - distance) / spiralRadius;
float theta = percent * percent * angle;
float s = std::sin(theta);
float c = std::cos(theta);
tc = glm::vec2(glm::dot(tc,glm::vec2(c,-s)),glm::dot(tc,glm::vec2(s,c)));
}
tc += spiralPosition;
returnValues[x][y] = noise->GetValue(tc);
}
}

Что он делает, так это создает контейнер значений градиентного шума. В то время как это делает это, это также спирали результаты вокруг эпицентра, как циклон. Это основано на коде здесь, результаты выглядят одинаково:

http://www.geeks3d.com/20110428/shader-library-swirl-post-processing-filter-in-glsl/

То, что я хотел бы сделать сейчас, это расширить это в 3D, 4D, в основном ND.

Я не знаком с тригонометрией, чтобы понять, что нужно сделать. У меня есть мысль, что тангенс необходим для третьего измерения, но потом я теряюсь в том, как сделать четвертое измерение.

Может кто-нибудь указать мне некоторые статьи, которые помогут мне понять, Google на самом деле не помогает мне (но я, честно говоря, вероятно, использую неправильные условия поиска).

1

Решение

Ваш вопрос помечен c ++, но не ясно, какую библиотеку классов вы используете для n-мерной векторной математики, поэтому я постараюсь ответить на вопрос чисто математически, предполагая, что у вас есть классы для представления N-мерных векторов и NxN-мерных матриц. (т.е. линейные отображения из N-мерного евклидова пространства на себя).

Обобщая ваш двумерный код, алгоритм для вычисления спирального отображения становится примерно таким:

  1. Переведите центр спирали в начало координат (векторное вычитание).
  2. Получите расстояние от точки, которая будет отображена от начала координат (используя N-мерное евклидово расстояние).
  3. Вычислить угол поворота на основе этого расстояния (theta = percent * percent * angle;)
  4. Нанесите на карту N-мерную сферу с центром в начале координат в этом радиусе, повернув ее вокруг центра.
  5. Переведите начало координат обратно в центр спирали.

Шаг 4, вероятно, где вы застряли. При обобщении (ротационных) отображений на сферы размерностей N-1 необходимо учитывать Теорема о волосяном шарике, в котором говорится:

На четномерных n-сферах нет неисчезающего непрерывного касательного векторного поля.

Это означает, что для нечетномерных векторных пространств (то есть четных вложенных сфер) всегда будет хотя бы одна видимая фиксированная точка в вашем спиральном отображении, и это нельзя избежать. В вашем случае, так как вы используете ротационные отображения, будет два фиксированные точки, каждая из которых там, где выбранная вами ось вращения пересекает сферу n-1.

Теперь n-мерное спиральное отображение между первыми двумя измерениями в n-мерном евклидовом пространстве будет выглядеть (как матрица линейного преобразования NxN):

    ⎡cos(θ)   −sin(θ)    0     .     0⎤
⎢sin(θ)    cos(θ)          .      ⎢
S = ⎢  0          0      1     .     0⎢
⎢  .          .      .     .      ⎢
⎣  0          0                  1⎦

Затем можно составить спиральные преобразования между последующими парами осей, чтобы получить следующую матрицу линейного преобразования NxN:

    ⎡cos(θ)   −sin(θ)     0         0                  ⎤
⎢sin(θ)    cos(θ)     0         0                  ⎢
⎢  0         0      cos(θ)   −sin(θ)               ⎢
S = ⎢  0         0      sin(θ)    cos(θ)               ⎢
⎢                                      .           ⎢
⎢                                            .     ⎢
⎣                                                 1⎦

Обратите внимание на трейлинг 1 в последней клетке? Это происходит, когда ваше N-мерное пространство имеет нечетное количество измерений, и, благодаря теореме о Волосатых шариках, не может обойтись.

В 3-х измерениях это становится спиралью вокруг оси Z:

    ⎡cos(θ)   −sin(θ)      0⎤
S = ⎢sin(θ)    cos(θ)      0⎢
⎣   0         0        1⎦

Таким образом, если O является центром спирали и P точка для преобразования, общее преобразование будет:

newP = O + S(P - O)

Если вы предпочитаете вращаться вокруг другой оси, вы должны построить матрицу вращения R принимая эту ось к оси Z, тогда общая спиральная матрица станет (R⁻¹)*S*R, Создать матрицу вращения Rсм. например Вращение одного 3-вектора на другой.

1

Другие решения


По вопросам рекламы [email protected]