我正在尝试使用 TypeScript 计算三角形的法线,但我得到了意想不到的结果。以下是使用的顶点和三角形的详细信息:
let vertices: Vertex[] = [
{ x: 0, y: 0, z: 0 },
{ x: 1, y: 0, z: 0 },
{ x: 1, y: 1, z: 0 },
{ x: 0, y: 1, z: 0 },
{ x: 0, y: 0, z: 1 },
{ x: 1, y: 0, z: 1 },
{ x: 1, y: 1, z: 1 },
{ x: 0, y: 1, z: 1 },
];
const triangles: Triangle[] = [
{ v1: 0, v2: 1, v3: 2 }, { v1: 0, v2: 2, v3: 3 }, // Front face
{ v1: 4, v2: 5, v3: 6 }, { v1: 4, v2: 6, v3: 7 }, // Back face
{ v1: 0, v2: 1, v3: 5 }, { v1: 0, v2: 5, v3: 4 }, // Bottom face
{ v1: 2, v2: 3, v3: 7 }, { v1: 2, v2: 7, v3: 6 }, // Top face
{ v1: 0, v2: 3, v3: 7 }, { v1: 0, v2: 7, v3: 4 }, // Left face
{ v1: 1, v2: 2, v3: 6 }, { v1: 1, v2: 6, v3: 5 } // Right face
];
我还对顶点应用了一些旋转和平移,它们工作正常。但是,当我尝试使用
calculateNormal()
函数计算三角形的法线时,结果似乎不正确。
这里是旋转和平移的实现:
const angle = 1;
const rotationX = rotationMatrixX(angle);
const rotationY = rotationMatrixY(angle);
vertices = vertices.map((vertex) => {
let [x, y, z, w] = multiplyMatrixVector(rotationX, [
vertex.x,
vertex.y,
vertex.z,
1,
]);
return {x, y, z};
})
vertices = vertices.map((vertex) => {
let [x, y, z, w] = multiplyMatrixVector(rotationY, [
vertex.x,
vertex.y,
vertex.z,
1,
]);
return {x, y, z};
})
const translatedVertices = transformVertices(vertices, translationMatrix);
const culledTriangles = [];
const normals = [];
for (let i = 0; i < triangles.length; i++) {
const { v1, v2, v3 } = triangles[i];
const p1 = translatedVertices[v1];
const p2 = translatedVertices[v2];
const p3 = translatedVertices[v3];
const normal = calculateNormal(p1, p2, p3);
if (normal.z > 0) {
culledTriangles.push(triangles[i]);
normals.push(normal);
}
}
// Transform and project the rotated vertices
const transformedVertices = transformVertices(translatedVertices, perspectiveProjectionMatrix());
const scaledVertices = scaleAndNormalizeVertices(transformedVertices);
// Draw the rotated cube
drawWireframe(ctx, scaledVertices, culledTriangles, normals);
这里是
calculateNormal()
函数的实现:
function calculateNormal(a: Vertex, b: Vertex, c: Vertex): Vertex {
const line1: Vertex = {
x: b.x - a.x,
y: b.y - a.y,
z: b.z - a.z,
};
const line2: Vertex = {
x: c.x - a.x,
y: c.y - a.y,
z: c.z - a.z,
};
const normal: Vertex = {
x: line1.y * line2.z - line1.z * line2.y,
y: line1.z * line2.x - line1.x * line2.z,
z: line1.x * line2.y - line1.y * line2.x,
};
const length = Math.sqrt(normal.x ** 2 + normal.y ** 2 + normal.z ** 2);
normal.x /= length;
normal.y /= length;
normal.z /= length;
return normal;
}
我已验证每个三角形都正确调用了
calculateNormal()
函数,但生成的法线似乎不正确。
对于我可能做错了什么以及如何解决它的任何建议或建议,我将不胜感激。