07-THREE.JS 各种形状的几何图形
<!DOCTYPE html> <html> <head>
<title>Example 02.04 - Geometries</title>
<script src="https://cdn.bootcss.com/three.js/r67/three.js"></script>
<script type="text/javascript" src="../libs/ParametricGeometries.js"></script>
<script type="text/javascript" src="../libs/ConvexGeometry.js"></script>
<script src="https://cdn.bootcss.com/stats.js/r10/Stats.min.js"></script>
<script type="text/javascript" src="https://cdn.bootcss.com/dat-gui/0.7.3/dat.gui.js"></script>
<style>
body {
/* set margin to 0 and overflow to hidden, to go fullscreen */
margin: 0;
overflow: hidden;
}
</style>
</head>
<body> <div id="Stats-output">
</div>
<div id="WebGL-output">
</div>
<script type="text/javascript"> // 初始化
function init() { var stats = initStats(); // 创建一个场景
var scene = new THREE.Scene(); // 创建一个相机
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // 创建渲染器
var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true; // 创建地面
var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true; // 旋转地面
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0; // 把地面添加到场景中去
scene.add(plane); // 相机对准场景
camera.position.x = -50;
camera.position.y = 30;
camera.position.z = 20;
camera.lookAt(new THREE.Vector3(-10, 0, 0)); // 添加自然光
var ambientLight = new THREE.AmbientLight(0x090909);
scene.add(ambientLight); // 添加聚光灯
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 40, 50);
spotLight.castShadow = true;
scene.add(spotLight); // 添加形状
addGeometries(scene); // 生成的渲染到DOM元素中去
document.getElementById("WebGL-output").appendChild(renderer.domElement); var step = 0; render(); function addGeometries(scene) {
var geoms = []; geoms.push(new THREE.CylinderGeometry(1, 4, 4)); // 基本立体型
geoms.push(new THREE.BoxGeometry(2, 2, 2)); // 圆形
geoms.push(new THREE.SphereGeometry(2)); //用于生成二十面体几何的类
geoms.push(new THREE.IcosahedronGeometry(4)); //几何/凸面
var points = [
new THREE.Vector3(2, 2, 2),
new THREE.Vector3(2, 2, -2),
new THREE.Vector3(-2, 2, -2),
new THREE.Vector3(-2, 2, 2),
new THREE.Vector3(2, -2, 2),
new THREE.Vector3(2, -2, -2),
new THREE.Vector3(-2, -2, -2),
new THREE.Vector3(-2, -2, 2)
];
geoms.push(new THREE.ConvexGeometry(points)); // create a lathgeometry
//http://en.wikipedia.org/wiki/Lathe_(graphics)
var pts = [];//points array - the path profile points will be stored here
var detail = .1;//half-circle detail - how many angle increments will be used to generate points
var radius = 3;//radius for half_sphere
for (var angle = 0.0; angle < Math.PI; angle += detail)//loop from 0.0 radians to PI (0 - 180 degrees)
pts.push(new THREE.Vector3(Math.cos(angle) * radius, 0, Math.sin(angle) * radius));//angle/radius to x,z
geoms.push(new THREE.LatheGeometry(pts, 12)); //面包圈
geoms.push(new THREE.OctahedronGeometry(3)); // create a geometry based on a function
geoms.push(new THREE.ParametricGeometry(THREE.ParametricGeometries.mobius3d, 20, 10)); //
geoms.push(new THREE.TetrahedronGeometry(3)); geoms.push(new THREE.TorusGeometry(3, 1, 10, 10)); geoms.push(new THREE.TorusKnotGeometry(3, 0.5, 50, 20)); var j = 0;
for (var i = 0; i < geoms.length; i++) {
var cubeMaterial = new THREE.MeshLambertMaterial({wireframe: true, color: Math.random() * 0xffffff}); var materials = [ new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff, shading: THREE.FlatShading}),
new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true}) ]; var mesh = THREE.SceneUtils.createMultiMaterialObject(geoms[i], materials);
mesh.traverse(function (e) {
e.castShadow = true
}); mesh.position.x = -24 + ((i % 4) * 12);
mesh.position.y = 4;
mesh.position.z = -8 + (j * 12); if ((i + 1) % 4 == 0) j++;
scene.add(mesh);
} } function render() {
stats.update();
requestAnimationFrame(render);
renderer.render(scene, camera);
} function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats;
}
}
window.onload = init </script>
</body>
</html>
ParametricGeometries.js
/*
* @author zz85
*
* Experimenting of primitive geometry creation using Surface Parametric equations
*
*/ THREE.ParametricGeometries = { klein: function (v, u) {
u *= Math.PI;
v *= 2 * Math.PI; u = u * 2;
var x, y, z;
if (u < Math.PI) {
x = 3 * Math.cos(u) * (1 + Math.sin(u)) + (2 * (1 - Math.cos(u) / 2)) * Math.cos(u) * Math.cos(v);
z = -8 * Math.sin(u) - 2 * (1 - Math.cos(u) / 2) * Math.sin(u) * Math.cos(v);
} else {
x = 3 * Math.cos(u) * (1 + Math.sin(u)) + (2 * (1 - Math.cos(u) / 2)) * Math.cos(v + Math.PI);
z = -8 * Math.sin(u);
} y = -2 * (1 - Math.cos(u) / 2) * Math.sin(v); return new THREE.Vector3(x, y, z);
}, plane: function (width, height) { return function(u, v) {
var x = u * width;
var y = 0;
var z = v * height; return new THREE.Vector3(x, y, z);
};
}, mobius: function(u, t) { // flat mobius strip
// http://www.wolframalpha.com/input/?i=M%C3%B6bius+strip+parametric+equations&lk=1&a=ClashPrefs_*Surface.MoebiusStrip.SurfaceProperty.ParametricEquations-
u = u - 0.5;
var v = 2 * Math.PI * t; var x, y, z; var a = 2;
x = Math.cos(v) * (a + u * Math.cos(v/2));
y = Math.sin(v) * (a + u * Math.cos(v/2));
z = u * Math.sin(v/2);
return new THREE.Vector3(x, y, z); }, mobius3d: function(u, t) { // volumetric mobius strip
u *= Math.PI;
t *= 2 * Math.PI; u = u * 2;
var phi = u / 2;
var major = 2.25, a = 0.125, b = 0.65;
var x, y, z;
x = a * Math.cos(t) * Math.cos(phi) - b * Math.sin(t) * Math.sin(phi);
z = a * Math.cos(t) * Math.sin(phi) + b * Math.sin(t) * Math.cos(phi);
y = (major + x) * Math.sin(u);
x = (major + x) * Math.cos(u);
return new THREE.Vector3(x, y, z);
} }; /*********************************************
*
* Parametric Replacement for TubeGeometry
*
*********************************************/ THREE.ParametricGeometries.TubeGeometry = function(path, segments, radius, segmentsRadius, closed, debug) { this.path = path;
this.segments = segments || 64;
this.radius = radius || 1;
this.segmentsRadius = segmentsRadius || 8;
this.closed = closed || false;
if (debug) this.debug = new THREE.Object3D(); var scope = this, tangent, normal, binormal, numpoints = this.segments + 1, x, y, z, tx, ty, tz, u, v, cx, cy, pos, pos2 = new THREE.Vector3(),
i, j, ip, jp, a, b, c, d, uva, uvb, uvc, uvd; var frames = new THREE.TubeGeometry.FrenetFrames(path, segments, closed),
tangents = frames.tangents,
normals = frames.normals,
binormals = frames.binormals; // proxy internals
this.tangents = tangents;
this.normals = normals;
this.binormals = binormals; var ParametricTube = function(u, v) {
v *= 2 * Math.PI; i = u * (numpoints - 1);
i = Math.floor(i); pos = path.getPointAt(u); tangent = tangents[i];
normal = normals[i];
binormal = binormals[i]; if (scope.debug) { scope.debug.add(new THREE.ArrowHelper(tangent, pos, radius, 0x0000ff));
scope.debug.add(new THREE.ArrowHelper(normal, pos, radius, 0xff0000));
scope.debug.add(new THREE.ArrowHelper(binormal, pos, radius, 0x00ff00)); } cx = -scope.radius * Math.cos(v); // TODO: Hack: Negating it so it faces outside.
cy = scope.radius * Math.sin(v); pos2.copy(pos);
pos2.x += cx * normal.x + cy * binormal.x;
pos2.y += cx * normal.y + cy * binormal.y;
pos2.z += cx * normal.z + cy * binormal.z; return pos2.clone();
}; THREE.ParametricGeometry.call(this, ParametricTube, segments, segmentsRadius); }; THREE.ParametricGeometries.TubeGeometry.prototype = Object.create( THREE.Geometry.prototype ); /*********************************************
*
* Parametric Replacement for TorusKnotGeometry
*
*********************************************/
THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segmentsR, segmentsT, p, q, heightScale ) { var scope = this; this.radius = radius || 200;
this.tube = tube || 40;
this.segmentsR = segmentsR || 64;
this.segmentsT = segmentsT || 8;
this.p = p || 2;
this.q = q || 3;
this.heightScale = heightScale || 1; var TorusKnotCurve = THREE.Curve.create( function() {
}, function(t) { t *= Math.PI * 2; var r = 0.5; var tx = (1 + r * Math.cos(q * t)) * Math.cos(p * t),
ty = (1 + r * Math.cos(q * t)) * Math.sin(p * t),
tz = r * Math.sin(q * t); return new THREE.Vector3(tx, ty * heightScale, tz).multiplyScalar(radius); } );
var segments = segmentsR;
var radiusSegments = segmentsT;
var extrudePath = new TorusKnotCurve(); THREE.ParametricGeometries.TubeGeometry.call( this, extrudePath, segments, tube, radiusSegments, true, false ); }; THREE.ParametricGeometries.TorusKnotGeometry.prototype = Object.create( THREE.Geometry.prototype ); /*********************************************
*
* Parametric Replacement for SphereGeometry
*
*********************************************/
THREE.ParametricGeometries.SphereGeometry = function(size, u, v) { function sphere(u, v) {
u *= Math.PI;
v *= 2 * Math.PI; var x = size * Math.sin(u) * Math.cos(v);
var y = size * Math.sin(u) * Math.sin(v);
var z = size * Math.cos(u); return new THREE.Vector3(x, y, z);
} THREE.ParametricGeometry.call(this, sphere, u, v, !true); }; THREE.ParametricGeometries.SphereGeometry.prototype = Object.create( THREE.Geometry.prototype ); /*********************************************
*
* Parametric Replacement for PlaneGeometry
*
*********************************************/ THREE.ParametricGeometries.PlaneGeometry = function(width, depth, segmentsWidth, segmentsDepth) { function plane(u, v) { var x = u * width;
var y = 0;
var z = v * depth; return new THREE.Vector3(x, y, z);
} THREE.ParametricGeometry.call(this, plane, segmentsWidth, segmentsDepth); }; THREE.ParametricGeometries.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype );
ConvexGeometry.js
/**
* @author qiao / https://github.com/qiao
* @fileoverview This is a convex hull generator using the incremental method.
* The complexity is O(n^2) where n is the number of vertices.
* O(nlogn) algorithms do exist, but they are much more complicated.
*
* Benchmark:
*
* Platform: CPU: P7350 @2.00GHz Engine: V8
*
* Num Vertices Time(ms)
*
* 10 1
* 20 3
* 30 19
* 40 48
* 50 107
*/ THREE.ConvexGeometry = function( vertices ) { THREE.Geometry.call( this ); var faces = [ [ 0, 1, 2 ], [ 0, 2, 1 ] ]; for ( var i = 3; i < vertices.length; i++ ) { addPoint( i ); } function addPoint( vertexId ) { var vertex = vertices[ vertexId ].clone(); var mag = vertex.length();
vertex.x += mag * randomOffset();
vertex.y += mag * randomOffset();
vertex.z += mag * randomOffset(); var hole = []; for ( var f = 0; f < faces.length; ) { var face = faces[ f ]; // for each face, if the vertex can see it,
// then we try to add the face's edges into the hole.
if ( visible( face, vertex ) ) { for ( var e = 0; e < 3; e++ ) { var edge = [ face[ e ], face[ ( e + 1 ) % 3 ] ];
var boundary = true; // remove duplicated edges.
for ( var h = 0; h < hole.length; h++ ) { if ( equalEdge( hole[ h ], edge ) ) { hole[ h ] = hole[ hole.length - 1 ];
hole.pop();
boundary = false;
break; } } if ( boundary ) { hole.push( edge ); } } // remove faces[ f ]
faces[ f ] = faces[ faces.length - 1 ];
faces.pop(); } else { // not visible f++; }
} // construct the new faces formed by the edges of the hole and the vertex
for ( var h = 0; h < hole.length; h++ ) { faces.push( [
hole[ h ][ 0 ],
hole[ h ][ 1 ],
vertexId
] ); }
} /**
* Whether the face is visible from the vertex
*/
function visible( face, vertex ) { var va = vertices[ face[ 0 ] ];
var vb = vertices[ face[ 1 ] ];
var vc = vertices[ face[ 2 ] ]; var n = normal( va, vb, vc ); // distance from face to origin
var dist = n.dot( va ); return n.dot( vertex ) >= dist; } /**
* Face normal
*/
function normal( va, vb, vc ) { var cb = new THREE.Vector3();
var ab = new THREE.Vector3(); cb.subVectors( vc, vb );
ab.subVectors( va, vb );
cb.cross( ab ); cb.normalize(); return cb; } /**
* Detect whether two edges are equal.
* Note that when constructing the convex hull, two same edges can only
* be of the negative direction.
*/
function equalEdge( ea, eb ) { return ea[ 0 ] === eb[ 1 ] && ea[ 1 ] === eb[ 0 ]; } /**
* Create a random offset between -1e-6 and 1e-6.
*/
function randomOffset() { return ( Math.random() - 0.5 ) * 2 * 1e-6; } /**
* XXX: Not sure if this is the correct approach. Need someone to review.
*/
function vertexUv( vertex ) { var mag = vertex.length();
return new THREE.Vector2( vertex.x / mag, vertex.y / mag ); } // Push vertices into `this.vertices`, skipping those inside the hull
var id = 0;
var newId = new Array( vertices.length ); // map from old vertex id to new id for ( var i = 0; i < faces.length; i++ ) { var face = faces[ i ]; for ( var j = 0; j < 3; j++ ) { if ( newId[ face[ j ] ] === undefined ) { newId[ face[ j ] ] = id++;
this.vertices.push( vertices[ face[ j ] ] ); } face[ j ] = newId[ face[ j ] ]; } } // Convert faces into instances of THREE.Face3
for ( var i = 0; i < faces.length; i++ ) { this.faces.push( new THREE.Face3(
faces[ i ][ 0 ],
faces[ i ][ 1 ],
faces[ i ][ 2 ]
) ); } // Compute UVs
for ( var i = 0; i < this.faces.length; i++ ) { var face = this.faces[ i ]; this.faceVertexUvs[ 0 ].push( [
vertexUv( this.vertices[ face.a ] ),
vertexUv( this.vertices[ face.b ] ),
vertexUv( this.vertices[ face.c ])
] ); } this.computeFaceNormals();
this.computeVertexNormals(); }; THREE.ConvexGeometry.prototype = Object.create( THREE.Geometry.prototype );
07-THREE.JS 各种形状的几何图形的更多相关文章
- three.js自定义形状
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
- JavaScript笔记 #07# 用js写算法
算法盒子初代(为了提高学习算法的热情...) 效果图: 所有代码放在单个html中: <!DOCTYPE html> <html> <head> <meta ...
- 项目总结07:JS图片的上传预览和表单提交(FileReader()方法)
JS图片的上传预览和表单提交(FileReader()方法) 一开始没有搞明白下面这块代码的,今天有时间简单整理下 核心点:FileReader()方法 以下是代码(以JSP文件为例) <!DO ...
- 25-THREE.JS 绘制线框样式几何图形的材质 线材质
<!DOCTYPE html> <html> <head> <title></title> <script src="htt ...
- 07 Node.js安装及环境配置
二.安装Node.js步骤 1.下载对应你系统的Node.js版本:https://nodejs.org/en/download/2.选安装目录进行安装3.环境配置4.测试 开始安装 1.下载完成后, ...
- 07 (H5*) js课程第8天 高阶函数、闭包、沙箱
目录: 1:call和apply方法调用 2:bind方法复制 3:函数中的几个属性值 4:高阶函数,函数作为参数 5:高阶函数,函数作为返回值. 6: 作用域链,作用域,预解析 7:闭包--延长 ...
- 爬虫入门到放弃系列07:js混淆、eval加密、字体加密三大反爬技术
前言 如果再说IP请求次数检测.验证码这种最常见的反爬虫技术,可能大家听得耳朵都出茧子了.当然,也有的同学写了了几天的爬虫,觉得爬虫太简单.没有啥挑战性.所以特地找了三个有一定难度的网站,希望可以有兴 ...
- 07:JS(03)
BOM与DOM操作 # 截至目前为止 我们虽然已经学会了js语法 但是你会发现跟浏览器和html文件还是一点关系没有 """ BOM 浏览器对象模型 Browser Ob ...
- 记录21.07.20 —— js语言回顾
js语言回顾 1.语法 a并没有声明,也可以输出,不会报错. 添加一条语句 则需要声明,称之为严谨语法 2.数组 2.1数组遍历三种方法 for-in与for-of forEach forEach调用 ...
随机推荐
- Python 学习之旅
流程图 第一章 Python简介 第二章 Python基础 第三章 流程控制 第四章 字符编码 第五章 文件处理 第六章 函数 第七章 模块与包 第八章 面向对象 第九章 异常处理 第十章 ...
- Hub,bridge,switch and router的区别
首先说HUB,也就是集线器.它的作用可以简单的理解为将一些机器连接起来组成一个局域网.而交换机(又名交换式集线器)作用与集线器大体相同.但是两者在性能上有区别:集线器采用的式共享带宽的工作方式,而交换 ...
- 用django写个CMS系统
上一篇介绍过django自带的flatpages,能够做简单的CMS.但是对于我们的真正的工作中的使用意义并不大.还是自己动手写一个吧. 不用说,一定是先从models开始的: from django ...
- C# Ajax 技术
Ajax 是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写.下面是 Ajax 应用程序所用到的基本技术:• HTML 用于建立 Web 表单并确定应用程 ...
- python常用模块——time模块
参考博客:http://blog.csdn.net/SeeTheWorld518/article/details/48314501 http://www.jb51.net/article/49325. ...
- JS编写类似弹出窗口样式显示层
JSp中增加div <!-- 提交变更申请 --> <div id="changeWindow" class="easyui-window" ...
- 2015.7.16(小高开忍住没有减仓,大盘涨3.5%,百股涨停——买进中重、中航,指导WXL错误)
1.大智慧轻微高开,按照昨天总结的震荡行情指导操作(pic1) a.震荡行情,开盘5分钟的走势不能指导操作, b.操作一定要等到2峰2谷出现后再做!开盘价不能作为峰.谷! c.只有当通道出现2.0%以 ...
- HDF 文件数据的读取
http://www.cams.cma.gov.cn/cams_973/cheres_docs/cheres_doc_sat.modis.1b.html一. HDF文件格式 1.概述 HDF 是美国国 ...
- 防止基本的XSS攻击 滤掉HTML标签
/** * 防止基本的XSS攻击 滤掉HTML标签 * 将HTML的特殊字符转换为了HTML实体 htmlentities * 将#和%转换为他们对应的实体符号 * 加上了$length参数来限制提交 ...
- SOA 面向服务架构 阅读笔记(二)
SOA并不能保证企业的员工更加轻松,企业的收益更加客观. 6.软件组件 6.1 组件和组件的作用 通过可重用的软件代码-组件,可以构建灵活的软件. 6.2 软件组件又称为应用程序,程序,函数,模 ...