我在3D空间中有一对由四个点组成的小平面。我知道刻面的缠绕方向'顶点使得如果两个面都面向观察者,则每个面的点将逆时针方向。
我正在尝试确定如何确定第一个方面的方向,以便我可以将第二个方面旋转到同一方向。
我可以使用矩阵乘法旋转点,但我无法确定现有的方向。
我是否需要简单地计算每个平面(x-y,x-z,y-z)中的顶点角度,还是比它更复杂?
我有这个几乎工作。不幸的是,结果是我总是从我希望得到的方向转过90度。
该过程是创建两个面,两个面都朝向相同的方向,然后在X,Y和Z轴上随机旋转其中一个面。我试图建立的代码应该确定随机旋转小平面的面向方向并产生一个旋转矩阵,该矩阵可以应用于第一小平面以使其面向相同的方向。
我希望旋转矩阵适用于任何朝向任何方向的小平面,这样任何小平面都可以旋转到与随机旋转小平面相同的方向。
这是我目前所拥有的完整代码(Lua):
local function newXRotationMatrix( x )
x = math.rad(x)
return {
{1,0,0,0},
{0,math.cos(x),math.sin(x),0},
{0,-math.sin(x),math.cos(x),0},
{0,0,0,1},
}
end
local function newYRotationMatrix( y )
y = math.rad(y)
return {
{math.cos(y),0,-math.sin(y),0},
{0,1,0,0},
{math.sin(y),0,math.cos(y),0},
{0,0,0,1},
}
end
local function newZRotationMatrix( z )
z = math.rad(z)
return {
{math.cos(z),math.sin(z),0,0},
{-math.sin(z),math.cos(z),0,0},
{0,0,1,0},
{0,0,0,1},
}
end
local function multiply( aMatrix, bMatrix )
if #aMatrix[1] ~= #bMatrix then
return nil
end
local empty = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
}
for aRow = 1, #aMatrix do
for bCol = 1, #bMatrix[1] do
local sum = empty[aRow][bCol]
for bRow = 1, #bMatrix do
sum = sum + aMatrix[aRow][bRow] * bMatrix[bRow][bCol]
end
empty[aRow][bCol] = sum
end
end
return empty
end
local function vector2d3dLength( vector )
return math.sqrt( vector[1]*vector[1] + vector[2]*vector[2] + vector[3]*vector[3] )
end
local function normalise2d3dVector( vector )
local len = vector2d3dLength( vector )
if (len == 0) then
return vector
end
local normalised = { vector[1]/len, vector[2]/len, vector[3]/len }
return normalised
end
local function subtract2d3dVectors( a, b )
local sub = { a[1]-b[1], a[2]-b[2], a[3]-b[3] }
return sub
end
local function crossProduct3d( a, b )
return {
a[2]*b[3] - a[3]*b[2],
a[3]*b[1] - a[1]*b[3],
a[1]*b[2] - a[2]*b[1],
}
end
local function new3dMatrix( x, y, z )
return {
{x[1],x[2],x[3],0},
{y[1],y[2],y[3],0},
{z[1],z[2],z[3],0},
{0,0,0,1},
}
end
local function getLookAtMatrix( bt )
local T = normalise2d3dVector( subtract2d3dVectors( bt[2], bt[1] ) ) -- normalize(P1 - P0)
local N = normalise2d3dVector( crossProduct3d( subtract2d3dVectors( bt[3], bt[1] ), T ) ) -- normalize(cross(T, P2 - P0))
local B = normalise2d3dVector( crossProduct3d( T, N ) ) -- normalize(cross(T, N))
local rotmat = new3dMatrix( T, N, B ) -- rotMat = mat3(T, N, B)
return rotmat
end
local a = {
{ -100, -100, -100, 1 },
{ -100, 100, -100, 1 },
{ 100, 100, -100, 1 },
{ 100, -100, -100, 1 },
}
local b = {
{ -100, -100, -100, 1 },
{ -100, 100, -100, 1 },
{ 100, 100, -100, 1 },
{ 100, -100, -100, 1 },
}
local matrix = multiply( newZRotationMatrix( 160 ), newYRotationMatrix( 30 ) )
matrix = multiply( matrix, newXRotationMatrix( 40 ) )
-- APPLY 'matrix' MATRIX TO 'b' VECTOR TABLE AND DISPLAY ON SCREEN
local bt = b.transformed
local rotmat = getLookAtMatrix( bt )
-- APPLY 'rotate' MATRIX TO 'a' VECTOR TABLE AND DISPLAY ON SCREEN
这会产生以下图像。绿色方面是' b'并且已经围绕所有三个轴随机旋转。黑色方面是' a'并根据'rotmat'旋转。矩阵试图面对它与' b'。
相同的方向正如你所看到的,黑色方面' a'已经围绕Y轴旋转到90度。我试图解释这一点,但我无法解释。有人可以解释我做错了什么吗?我遗漏的唯一代码是渲染代码,因为它在这里并不相关 - 并且包含的内容太长了。
答案 0 :(得分:1)
如果您的4个点位于同一平面上并且您想要找到平面的法线,则只需标准化两个非平行边的叉积(您只需要3个点)。