html5<canvas模拟三维图形>(旋转的正方体)
<!DOCTYPE html>
<html>
<head>
<style>
canvas{
background:#eee;
}
</style>
<title>noTitle</title>
<meta charset="">
<link rel="stylesheet" href="">
<script>
window.onload=function () {
var canvas=document.getElementById("canvas");
var cobj=canvas.getContext("2d");
cobj.translate(250,250);
var focusLen=300;
var points=[
{x_3d:-50,y_3d:-50,z_3d:-50},
{x_3d:50,y_3d:-50,z_3d:-50},
{x_3d:50,y_3d:50,z_3d:-50},
{x_3d:-50,y_3d:50,z_3d:-50},
{x_3d:-50,y_3d:-50,z_3d:50},
{x_3d:50,y_3d:-50,z_3d:50},
{x_3d:50,y_3d:50,z_3d:50},
{x_3d:-50,y_3d:50,z_3d:50},
]
setInterval(function () {
cobj.clearRect(-200,-200,500,500);
var points2d=[];
for (var i=0; i<points.length; i++) {
var newxyz=rectarr([1,-1,1],10*Math.PI/180,[points[i].x_3d,points[i].y_3d,points[i].z_3d,]);
points[i].x_3d=newxyz[0];
points[i].y_3d=newxyz[1];
points[i].z_3d=newxyz[2];
var obj= change2d (newxyz[0],newxyz[1],newxyz[2],focusLen);
points2d.push(obj);
}
drawRect (cobj,points2d)
},100)
}
function change2d (x_3d,y_3d,z_3d,focusLen) {
var xy={};
var scales=focusLen/(focusLen+z_3d);
xy.x=x_3d*scales;
xy.y=y_3d*scales;
return xy;
}
function drawRect (cobj,points2d) {
cobj.beginPath();
cobj.moveTo(points2d[0].x,points2d[0].y);
cobj.lineTo(points2d[1].x,points2d[1].y);
cobj.lineTo(points2d[2].x,points2d[2].y);
cobj.lineTo(points2d[3].x,points2d[3].y);
cobj.closePath();
cobj.stroke()
cobj.beginPath();
cobj.moveTo(points2d[4].x,points2d[4].y);
cobj.lineTo(points2d[5].x,points2d[5].y);
cobj.lineTo(points2d[6].x,points2d[6].y);
cobj.lineTo(points2d[7].x,points2d[7].y);
cobj.closePath();
cobj.stroke()
cobj.beginPath();
cobj.moveTo(points2d[0].x,points2d[0].y);
cobj.lineTo(points2d[4].x,points2d[4].y);
cobj.lineTo(points2d[7].x,points2d[7].y);
cobj.lineTo(points2d[3].x,points2d[3].y);
cobj.closePath();
cobj.stroke()
cobj.beginPath();
cobj.moveTo(points2d[1].x,points2d[1].y);
cobj.lineTo(points2d[5].x,points2d[5].y);
cobj.lineTo(points2d[6].x,points2d[6].y);
cobj.lineTo(points2d[2].x,points2d[2].y);
cobj.closePath();
cobj.stroke()
}
//xiangl: 也就是3维旋转轴(数组形式)
//theta: 旋转的度数(数组形式)
//xyzArr: 旋转以后的x,y,z的值(数组形式)
//旋转后的坐标
function rectarr (xiangl,theta,xyzArr){
var sqrt = Math.sqrt(xiangl[0] * xiangl[0] + xiangl[1] * xiangl[1] + xiangl[2] * xiangl[2]);
var u = xiangl[0] / sqrt;
var v = xiangl[1] / sqrt;
var w = xiangl[2] / sqrt;
var newarr = [];
newarr[0]= [
Math.cos(theta) + (u * u) * (1 - Math.cos(theta)) ,
u * v * (1 - Math.cos(theta)) + w * Math.sin(theta),
u * w * (1 -Math.cos(theta)) - v * Math.sin(theta),
0
];
newarr[1] = [
u * v * (1 - Math.cos(theta)) - w * Math.sin(theta),
Math.cos(theta) + v * v * (1 - Math.cos(theta)),
w * v * (1 - Math.cos(theta)) + u * Math.sin(theta),
0
];
newarr[2]= [
u * w * (1 - Math.cos(theta)) + v * Math.sin(theta),
v * w * (1 - Math.cos(theta)) - u * Math.sin(theta),
Math.cos(theta) + w * w * (1 - Math.cos(theta)),
0
];
newarr[3] = [
0,
0,
0,
1
];
//计算旋转以后的值
var arr = [];
for (var i=0; i<newarr.length; i++) {
var val = 0;
for (var j=0; j<xyzArr.length; j++) {
val += newarr[i][j] * xyzArr[j];
}
arr.push (val);
}
return arr;
}
</script>
</head>
<body>
<canvas id="canvas" height=500 width=500>
</canvas>
</body>
<head>
<style>
canvas{
background:#eee;
}
</style>
<title>noTitle</title>
<meta charset="">
<link rel="stylesheet" href="">
<script>
window.onload=function () {
var canvas=document.getElementById("canvas");
var cobj=canvas.getContext("2d");
cobj.translate(250,250);
var focusLen=300;
var points=[
{x_3d:-50,y_3d:-50,z_3d:-50},
{x_3d:50,y_3d:-50,z_3d:-50},
{x_3d:50,y_3d:50,z_3d:-50},
{x_3d:-50,y_3d:50,z_3d:-50},
{x_3d:-50,y_3d:-50,z_3d:50},
{x_3d:50,y_3d:-50,z_3d:50},
{x_3d:50,y_3d:50,z_3d:50},
{x_3d:-50,y_3d:50,z_3d:50},
]
setInterval(function () {
cobj.clearRect(-200,-200,500,500);
var points2d=[];
for (var i=0; i<points.length; i++) {
var newxyz=rectarr([1,-1,1],10*Math.PI/180,[points[i].x_3d,points[i].y_3d,points[i].z_3d,]);
points[i].x_3d=newxyz[0];
points[i].y_3d=newxyz[1];
points[i].z_3d=newxyz[2];
var obj= change2d (newxyz[0],newxyz[1],newxyz[2],focusLen);
points2d.push(obj);
}
drawRect (cobj,points2d)
},100)
}
function change2d (x_3d,y_3d,z_3d,focusLen) {
var xy={};
var scales=focusLen/(focusLen+z_3d);
xy.x=x_3d*scales;
xy.y=y_3d*scales;
return xy;
}
function drawRect (cobj,points2d) {
cobj.beginPath();
cobj.moveTo(points2d[0].x,points2d[0].y);
cobj.lineTo(points2d[1].x,points2d[1].y);
cobj.lineTo(points2d[2].x,points2d[2].y);
cobj.lineTo(points2d[3].x,points2d[3].y);
cobj.closePath();
cobj.stroke()
cobj.beginPath();
cobj.moveTo(points2d[4].x,points2d[4].y);
cobj.lineTo(points2d[5].x,points2d[5].y);
cobj.lineTo(points2d[6].x,points2d[6].y);
cobj.lineTo(points2d[7].x,points2d[7].y);
cobj.closePath();
cobj.stroke()
cobj.beginPath();
cobj.moveTo(points2d[0].x,points2d[0].y);
cobj.lineTo(points2d[4].x,points2d[4].y);
cobj.lineTo(points2d[7].x,points2d[7].y);
cobj.lineTo(points2d[3].x,points2d[3].y);
cobj.closePath();
cobj.stroke()
cobj.beginPath();
cobj.moveTo(points2d[1].x,points2d[1].y);
cobj.lineTo(points2d[5].x,points2d[5].y);
cobj.lineTo(points2d[6].x,points2d[6].y);
cobj.lineTo(points2d[2].x,points2d[2].y);
cobj.closePath();
cobj.stroke()
}
//xiangl: 也就是3维旋转轴(数组形式)
//theta: 旋转的度数(数组形式)
//xyzArr: 旋转以后的x,y,z的值(数组形式)
//旋转后的坐标
function rectarr (xiangl,theta,xyzArr){
var sqrt = Math.sqrt(xiangl[0] * xiangl[0] + xiangl[1] * xiangl[1] + xiangl[2] * xiangl[2]);
var u = xiangl[0] / sqrt;
var v = xiangl[1] / sqrt;
var w = xiangl[2] / sqrt;
var newarr = [];
newarr[0]= [
Math.cos(theta) + (u * u) * (1 - Math.cos(theta)) ,
u * v * (1 - Math.cos(theta)) + w * Math.sin(theta),
u * w * (1 -Math.cos(theta)) - v * Math.sin(theta),
0
];
newarr[1] = [
u * v * (1 - Math.cos(theta)) - w * Math.sin(theta),
Math.cos(theta) + v * v * (1 - Math.cos(theta)),
w * v * (1 - Math.cos(theta)) + u * Math.sin(theta),
0
];
newarr[2]= [
u * w * (1 - Math.cos(theta)) + v * Math.sin(theta),
v * w * (1 - Math.cos(theta)) - u * Math.sin(theta),
Math.cos(theta) + w * w * (1 - Math.cos(theta)),
0
];
newarr[3] = [
0,
0,
0,
1
];
//计算旋转以后的值
var arr = [];
for (var i=0; i<newarr.length; i++) {
var val = 0;
for (var j=0; j<xyzArr.length; j++) {
val += newarr[i][j] * xyzArr[j];
}
arr.push (val);
}
return arr;
}
</script>
</head>
<body>
<canvas id="canvas" height=500 width=500>
</canvas>
</body>
</html>
效果: