找到3D facet的方向向量

时间:2016-07-24 11:25:47

标签: lua 3d angle direction

我在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 个答案:

答案 0 :(得分:1)

如果您的4个点位于同一平面上并且您想要找到平面的法线,则只需标准化两个非平行边的叉积(您只需要3个点)。