我在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'相同的方向面对它。
正如你所看到的,黑面“A”已经旋转到绕Y轴90度。我试图说明这一点,但我不能。有人能解释我做错了什么吗?我唯一遗漏的代码是渲染代码,因为它在这里没有关系 - 并且太长时间会被包含在内。
然后,我会计算两个平面中每个小平面角度(例如x-y和x-z)的交叉乘积之间的差异,以找出要旋转多少以使小平面朝向相同方向? –
这可以工作,但我会做的是为每个方面创建旋转矩阵,并比较它们以获得两个方面之间的旋转矩阵。 – pleluron
我知道如何创建用于旋转点的旋转矩阵,但是您是指从上面的答案的交叉产品中填充该矩阵? –