2016-07-24 118 views
1

我在3D空间中有一对由4个点组成的面。我知道小平面顶点的缠绕方向,因此如果两个小平面都面向观察者,则每个小平面的点将按逆时针方向。查找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'相同的方向面对它。

After random rotation of b and facing direction detection applied to a

正如你所看到的,黑面“A”已经旋转到绕Y轴90度。我试图说明这一点,但我不能。有人能解释我做错了什么吗?我唯一遗漏的代码是渲染代码,因为它在这里没有关系 - 并且太长时间会被包含在内。

回答

1

如果你的4个点在同一个平面上,并且你想要找到平面的法线,只需对两个非平行边的交叉积进行归一化(你只需要3个点)。

+0

然后,我会计算两个平面中每个小平面角度(例如x-y和x-z)的交叉乘积之间的差异,以找出要旋转多少以使小平面朝向相同方向? –

+0

这可以工作,但我会做的是为每个方面创建旋转矩阵,并比较它们以获得两个方面之间的旋转矩阵。 – pleluron

+0

我知道如何创建用于旋转点的旋转矩阵,但是您是指从上面的答案的交叉产品中填充该矩阵? –