JS 3D 实现:三维投影
代码: https://github.com/hanai/js-d3
坐标系

渲染
投影
将三维空间中的坐标 <x, y, z> 投影到平面上,得到投影的坐标 <x', y'>。
渲染函数
遍历每一个要渲染的对象,遍历对象的各个平面,对平面各个顶点由函数 project() 计算出投影在平面上的二维坐标,依次连接平面各顶点。
function render(objects, ctx, dx, dy) {
// Clear the previous frame
ctx.clearRect(0, 0, 2 * dx, 2 * dy);
// for each object
objects.forEach(object => {
// for each face
object.faces.forEach(face => {
face.forEach((vertex, vertexIdx) => {
var P = project(vertex);
if (vertexIdx === 0) {
// draw the first vertex
ctx.beginPath();
ctx.moveTo(P.x + dx, -P.y + dy);
} else {
// draw the other vertices
ctx.lineTo(P.x + dx, -P.y + dy);
}
});
// close the path and draw the face
ctx.closePath();
ctx.stroke();
ctx.fill();
});
});
}
正视图
function project(M) {
return new Vertex2D(M.x, M.z);
}
透视图


由三维空间中的顶点 M(x, y, z),我们希望的到平面上的投影 M' 的坐标 (x', z')。

如图,由截线定理可得 x' = d / y * x,故:
function project(M) {
// Distance between the camera and the plane
var d = 200;
var r = d / M.y;
return new Vertex2D(r * M.x, r * M.z);
}
其它
旋转鼠标旋转立方体

绑定事件 mousedown 与 mousemove,由 event.clientX 与 event.clientY 可得 Δx, Δy,换算得水平旋转角度 theta 与竖直旋转角度 phi。