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
。