function P3D(x,y,z) {
this.x = x;this.y = y;this.z = z;
this.rotateX = angle => {
var rad = angle * Math.PI / 180,
cosa = Math.cos(rad),sina = Math.sin(rad),
y = this.y * cosa - this.z * sina,
z = this.y * sina + this.z * cosa
return new P3D(this.x, y, z)
}
this.rotateY = angle => {
var rad = angle * Math.PI / 180,
cosa = Math.cos(rad), sina = Math.sin(rad),
z = this.z * cosa - this.x * sina,
x = this.z * sina + this.x * cosa
return new P3D(x,this.y, z)
}
this.rotateZ = angle => {
var rad = angle * Math.PI / 180,
cosa = Math.cos(rad), sina = Math.sin(rad),
x = this.x * cosa - this.y * sina,
y = this.x * sina + this.y * cosa
return new P3D(x, y, this.z)
}
this.project = (viewWidth, viewHeight, fov, viewDistance) => {
var factor = fov / (viewDistance + this.z),
x = this.x * factor + viewWidth / 2,
y = this.y * factor + viewHeight / 2
return new P3D(x, y, this.z)
}
}
var vx = [
new P3D(-1,1,-1),
new P3D(1,1,-1),
new P3D(-1,-1,-1),
new P3D(1,-1,-1),
new P3D(-1,-1,1),
new P3D(1,-1,1),
new P3D(-1,1,1),
new P3D(1,1,1),
];
// Define the vx that compose each of the 6 faces. These numbers are
// indices to the vertex list defined above.
var faces = [[0,1,3,2],[2,3,5,4],[4,5,7,6],[6,7,1,0],[0,2,4,6],[1,3,5,7]]
faces.map((f,i)=>{
var mx=vx[f[0]].x+vx[f[1]].x+vx[f[2]].x+vx[f[3]].x,
my=vx[f[0]].y+vx[f[1]].y+vx[f[2]].y+vx[f[3]].y,
mz=vx[f[0]].z+vx[f[1]].z+vx[f[2]].z+vx[f[3]].z
vx[i+10]=new P3D(mx/4, my/4, mz/4)
f[4]=i
f[5]=i+10
})
var angle = 0;
var ctx = CV.getContext("2d");
setInterval(loop,33)
function loop() {
ctx.fillStyle = "#fff"
ctx.fillRect(0,0,400,200);
ctx.font = "20px Arial"
angle += 2
var t = vx.map(v=>
v
.rotateX(angle).rotateY(-angle).rotateZ(-angle)
.project(400,200,128,3)
)
ctx.strokeStyle = "#f00"
t.forEach((v,i)=>i<8?ctx.strokeText(i,v.x,v.y):0)
ctx.strokeStyle = "#428"
ctx.beginPath()
faces.forEach(f=>(
ctx.moveTo(t[f[0]].x,t[f[0]].y),
ctx.lineTo(t[f[1]].x,t[f[1]].y),
ctx.lineTo(t[f[2]].x,t[f[2]].y),
ctx.lineTo(t[f[3]].x,t[f[3]].y),
ctx.lineTo(t[f[0]].x,t[f[0]].y),
ctx.strokeText(f[4],t[f[5]].x,t[f[5]].y)
))
ctx.closePath(),
ctx.stroke()
}
<canvas id=CV width=400 height=200></canvas>