我在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,基本上 n D.
我不熟悉三角学,无法理解需要做什么。我有一个想法,第三个维度需要切线,但后来我失去了如何做第四个维度。
有人能指出一些有助于我理解的文章,谷歌并没有真正帮助我(但我老实说可能使用的搜索条件不正确)。
答案 0 :(得分:1)
你的问题被标记为c ++,但是你不清楚你用于n维向量数学的类库,所以我会尝试纯数学地回答这个问题,假设你有类表示N维向量和NxN维矩阵(即从N维欧氏空间到自身的线性映射)。
概括你的2d代码,计算螺旋映射的算法就像:
theta = percent * percent * angle;
)第4步可能就是你被困的地方。在将(旋转)映射推广到N-1维的球体时,必须牢记Hairy ball theorem,其中指出:
在偶数维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
,请参阅例如Rotating one 3-vector to another