U途骑士
- UID66741
- 粉丝1
- 关注0
- 发帖数1
- 铜币12枚
- 威望12点
- 贡献0点
|
楼主#
更多
发布于:2014-11-08 23:01
[tr][td]本教程的主题是利用HTML5技术在2D和3D图形之间搭一座互通的桥梁(通过WebGL方式)。今天我将展示如何使用一个多边形网格绘制一个三维对象。 一个多边形网格或非结构化网格是一个集合的顶点,边缘和面孔,在3 d电脑图像和实体建模定义了一个多面体的对象的形状。通常由三角形的面孔,四边形或其他简单凸多边形,因为这样可以简化渲染,但也可能是由更一般的凹多边 形,或多边形的洞。 为了演示,我们准备了简单的三维物体——一个多维数据集和多维领域 HTML CODE 通常我们会在canvas里做一个简单的标记
Triangle mesh for 3D objects in HTML5 | Script Tutorials
Please use Up / Down keys to change opacity
我提取一个生成的对象初始化来: 这意味着如果我们需要显示一个多维数据集——你必须取消第一个一行,如果你想显示一个球体与6张面孔——选择第二个变体。 JS CODE JS的代码分为三部分:主体的代码,网格代码和转换代码 meshes.js // get random color function getRandomColor() { var letters = '0123456789ABCDEF'.split(''); var color = '#'; for (var i = 0; i < 6; i++ ) { color += letters[Math.round(Math.random() * 15)]; } return color; }
// prepare object function prepareObject(o) { o.colors = new Array();
// prepare normals o.normals = new Array(); for (var i = 0; i < o.faces.length; i++) { o.normals = [0, 0, 0];
o.colors = getRandomColor(); }
// prepare centers: calculate max positions o.center = [0, 0, 0]; for (var i = 0; i < o.points.length; i++) { o.center[0] += o.points[0]; o.center[1] += o.points[1]; o.center[2] += o.points[2]; }
// prepare distances o.distances = new Array(); for (var i = 1; i < o.points.length; i++) { o.distances = 0; }
// calculate average center positions o.points_number = o.points.length; o.center[0] = o.center[0] / (o.points_number - 1); o.center[1] = o.center[1] / (o.points_number - 1); o.center[2] = o.center[2] / (o.points_number - 1);
o.faces_number = o.faces.length; o.axis_x = [1, 0, 0]; o.axis_y = [0, 1, 0]; o.axis_z = [0, 0, 1]; }
// Cube object function cube() {
// prepare points and faces for cube this.points=[ [0,0,0], [100,0,0], [100,100,0], [0,100,0], [0,0,100], [100,0,100], [100,100,100], [0,100,100], [50,50,100], [50,50,0], ];
this.faces=[ [0,4,5], [0,5,1], [1,5,6], [1,6,2], [2,6,7], [2,7,3], [3,7,4], [3,4,0], [8,5,4], [8,6,5], [8,7,6], [8,4,7], [9,5,4], [9,6,5], [9,7,6], [9,4,7], ];
prepareObject(this); }
// Sphere object function sphere(n) { var delta_angle = 2 * Math.PI / n;
// prepare vertices (points) of sphere var vertices = []; for (var j = 0; j < n / 2 - 1; j++) { for (var i = 0; i < n; i++) { vertices[j * n + i] = []; vertices[j * n + i][0] = 100 * Math.sin((j + 1) * delta_angle) * Math.cos(i * delta_angle); vertices[j * n + i][1] = 100 * Math.cos((j + 1) * delta_angle); vertices[j * n + i][2] = 100 * Math.sin((j + 1) * delta_angle) * Math.sin(i * delta_angle); } } vertices[(n / 2 - 1) * n] = []; vertices[(n / 2 - 1) * n + 1] = [];
vertices[(n / 2 - 1) * n][0] = 0; vertices[(n / 2 - 1) * n][1] = 100; vertices[(n / 2 - 1) * n][2] = 0;
vertices[(n / 2 - 1) * n + 1][0] = 0; vertices[(n / 2 - 1) * n + 1][1] = -100; vertices[(n / 2 - 1) * n + 1][2] = 0;
this.points = vertices;
// prepare faces var faces = []; for (var j = 0; j < n / 2 - 2; j++) { for (var i = 0; i < n - 1; i++) { faces[j * 2 * n + i] = []; faces[j * 2 * n + i + n] = [];
faces[j * 2 * n + i][0] = j * n + i; faces[j * 2 * n + i][1] = j * n + i + 1; faces[j * 2 * n + i][2] = (j + 1) * n + i + 1; faces[j * 2 * n + i + n][0] = j * n + i; faces[j * 2 * n + i + n][1] = (j + 1) * n + i + 1; faces[j * 2 * n + i + n][2] = (j + 1) * n + i; }
faces[j * 2 * n + n - 1] = []; faces[2 * n * (j + 1) - 1] = [];
faces[j * 2 * n + n - 1 ][0] = (j + 1) * n - 1; faces[j * 2 * n + n - 1 ][1] = (j + 1) * n; faces[j * 2 * n + n - 1 ][2] = j * n; faces[2 * n * (j + 1) - 1][0] = (j + 1) * n - 1; faces[2 * n * (j + 1) - 1][1] = j * n + n; faces[2 * n * (j + 1) - 1][2] = (j + 2) * n - 1; } for (var i = 0; i < n - 1; i++) { faces[n * (n - 4) + i] = []; faces[n * (n - 3) + i] = [];
faces[n * (n - 4) + i][0] = (n / 2 - 1) * n; faces[n * (n - 4) + i][1] = i; faces[n * (n - 4) + i][2] = i + 1; faces[n * (n - 3) + i][0] = (n / 2 - 1) * n + 1; faces[n * (n - 3) + i][1] = (n / 2 - 2) * n + i + 1; faces[n * (n - 3) + i][2] = (n / 2 - 2) * n + i; }
faces[n * (n - 3) - 1] = []; faces[n * (n - 2) - 1] = [];
faces[n * (n - 3) - 1][0] = (n / 2 - 1) * n; faces[n * (n - 3) - 1][1] = n - 1; faces[n * (n - 3) - 1][2] = 0; faces[n * (n - 2) - 1][0] = (n / 2 - 1) * n + 1; faces[n * (n - 2) - 1][1] = (n / 2 - 2) * n; faces[n * (n - 2) - 1][2] = (n / 2 - 2) * n + n - 1;
this.faces=faces;
prepareObject(this); }
main.js // inner variables var canvas, ctx; var vAlpha = 0.5; var vShiftX = vShiftY = 0; var distance = -700; var vMouseSens = 0.05; var iHalfX, iHalfY;
// initialization function sceneInit() { // prepare canvas and context objects canvas = document.getElementById('scene'); ctx = canvas.getContext('2d');
iHalfX = canvas.width / 2; iHalfY = canvas.height / 2;
// initial scale and translate scaleObj([3, 3, 3], obj); translateObj([-obj.center[0], -obj.center[1], -obj.center[2]],obj); translateObj([0, 0, -1000], obj);
// attach event handlers document.onkeydown = handleKeydown; canvas.onmousemove = handleMousemove;
// main scene loop setInterval(drawScene, 25); }
// onKeyDown event handler function handleKeydown(e) { kCode = ((e.which) || (e.keyCode)); switch (kCode) { case 38: vAlpha = (vAlpha = 0.2) ? (vAlpha - 0.1) : vAlpha; break; // Down key } }
// onMouseMove event handler function handleMousemove(e) { var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop;
if ((x > 0) && (x < canvas.width) && (y > 0) && (y < canvas.height)) { vShiftY = vMouseSens * (x - iHalfX) / iHalfX; vShiftX = vMouseSens * (y - iHalfY) / iHalfY; } }
// draw main scene function function drawScene() { // clear canvas ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// set fill color, stroke color, line width and global alpha ctx.strokeStyle = 'rgb(0,0,0)'; ctx.lineWidth = 0.5; ctx.globalAlpha= vAlpha;
// vertical and horizontal rotate var vP1x = getRotationPar([0, 0, -1000], [1, 0, 0], vShiftX); var vP2x = getRotationPar([0, 0, 0], [1, 0, 0], vShiftX); var vP1y = getRotationPar([0, 0, -1000], [0, 1, 0], vShiftY); var vP2y = getRotationPar([0, 0, 0], [0, 1, 0], vShiftY); rotateObj(vP1x, vP2x, obj); rotateObj(vP1y, vP2y, obj);
// recalculate distances for (var i = 0; i < obj.points_number; i++) { obj.distances = Math.pow(obj.points[0],2) + Math.pow(obj.points[1],2) + Math.pow(obj.points[2], 2); }
// prepare array with face triangles (with calculation of max distance for every face) var iCnt = 0; var aFaceTriangles = new Array(); for (var i = 0; i < obj.faces_number; i++) { var max = obj.distances[obj.faces[0]]; for (var f = 1; f < obj.faces.length; f++) { if (obj.distances[obj.faces[f]] > max) max = obj.distances[obj.faces[f]]; } aFaceTriangles[iCnt++] = {faceVertex:obj.faces, faceColor:obj.colors, distance:max}; } aFaceTriangles.sort(sortByDistance);
// prepare array with projected points var aPrjPoints = new Array(); for (var i = 0; i < obj.points.length; i++) { aPrjPoints = project(distance, obj.points, iHalfX, iHalfY); }
// draw an object (surfaces) for (var i = 0; i < iCnt; i++) {
ctx.fillStyle = aFaceTriangles.faceColor;
// begin path ctx.beginPath();
// face vertex index var iFaceVertex = aFaceTriangles.faceVertex;
// move to initial position ctx.moveTo(aPrjPoints[iFaceVertex[0]][0], aPrjPoints[iFaceVertex[0]][1]);
// and draw three lines (to build a triangle) for (var z = 1; z < aFaceTriangles.faceVertex.length; z++) { ctx.lineTo(aPrjPoints[iFaceVertex[z]][0], aPrjPoints[iFaceVertex[z]][1]); }
// close path, strole and fill a triangle ctx.closePath(); ctx.stroke(); ctx.fill(); } }
// sort function function sortByDistance(x, y) { return (y.distance - x.distance); }
// initialization if (window.attachEvent) { window.attachEvent('onload', sceneInit); } else { if (window.onload) { var curronload = window.onload; var newonload = function() { curronload(); sceneInit(); }; window.onload = newonload; } else { window.onload = sceneInit; } }
查看演示:http://www.script-tutorials.com/demos/319/index.html 下载:用HTML5画一个3D的三角形网格.zip [/td][/tr]
|