<!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 各种形状的几何图形的更多相关文章

  1. three.js自定义形状

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  2. JavaScript笔记 #07# 用js写算法

    算法盒子初代(为了提高学习算法的热情...) 效果图: 所有代码放在单个html中: <!DOCTYPE html> <html> <head> <meta ...

  3. 项目总结07:JS图片的上传预览和表单提交(FileReader()方法)

    JS图片的上传预览和表单提交(FileReader()方法) 一开始没有搞明白下面这块代码的,今天有时间简单整理下 核心点:FileReader()方法 以下是代码(以JSP文件为例) <!DO ...

  4. 25-THREE.JS 绘制线框样式几何图形的材质 线材质

    <!DOCTYPE html> <html> <head> <title></title> <script src="htt ...

  5. 07 Node.js安装及环境配置

    二.安装Node.js步骤 1.下载对应你系统的Node.js版本:https://nodejs.org/en/download/2.选安装目录进行安装3.环境配置4.测试 开始安装 1.下载完成后, ...

  6. 07 (H5*) js课程第8天 高阶函数、闭包、沙箱

    目录: 1:call和apply方法调用 2:bind方法复制 3:函数中的几个属性值 4:高阶函数,函数作为参数 5:高阶函数,函数作为返回值. 6:   作用域链,作用域,预解析 7:闭包--延长 ...

  7. 爬虫入门到放弃系列07:js混淆、eval加密、字体加密三大反爬技术

    前言 如果再说IP请求次数检测.验证码这种最常见的反爬虫技术,可能大家听得耳朵都出茧子了.当然,也有的同学写了了几天的爬虫,觉得爬虫太简单.没有啥挑战性.所以特地找了三个有一定难度的网站,希望可以有兴 ...

  8. 07:JS(03)

    BOM与DOM操作 # 截至目前为止 我们虽然已经学会了js语法 但是你会发现跟浏览器和html文件还是一点关系没有 """ BOM 浏览器对象模型 Browser Ob ...

  9. 记录21.07.20 —— js语言回顾

    js语言回顾 1.语法 a并没有声明,也可以输出,不会报错. 添加一条语句 则需要声明,称之为严谨语法 2.数组 2.1数组遍历三种方法 for-in与for-of forEach forEach调用 ...

随机推荐

  1. Python 学习之旅

    流程图 第一章  Python简介 第二章  Python基础 第三章  流程控制 第四章  字符编码 第五章  文件处理 第六章  函数 第七章 模块与包 第八章 面向对象 第九章 异常处理 第十章 ...

  2. Hub,bridge,switch and router的区别

    首先说HUB,也就是集线器.它的作用可以简单的理解为将一些机器连接起来组成一个局域网.而交换机(又名交换式集线器)作用与集线器大体相同.但是两者在性能上有区别:集线器采用的式共享带宽的工作方式,而交换 ...

  3. 用django写个CMS系统

    上一篇介绍过django自带的flatpages,能够做简单的CMS.但是对于我们的真正的工作中的使用意义并不大.还是自己动手写一个吧. 不用说,一定是先从models开始的: from django ...

  4. C# Ajax 技术

    Ajax 是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写.下面是 Ajax 应用程序所用到的基本技术:• HTML 用于建立 Web 表单并确定应用程 ...

  5. python常用模块——time模块

    参考博客:http://blog.csdn.net/SeeTheWorld518/article/details/48314501 http://www.jb51.net/article/49325. ...

  6. JS编写类似弹出窗口样式显示层

    JSp中增加div <!-- 提交变更申请 --> <div id="changeWindow" class="easyui-window" ...

  7. 2015.7.16(小高开忍住没有减仓,大盘涨3.5%,百股涨停——买进中重、中航,指导WXL错误)

    1.大智慧轻微高开,按照昨天总结的震荡行情指导操作(pic1) a.震荡行情,开盘5分钟的走势不能指导操作, b.操作一定要等到2峰2谷出现后再做!开盘价不能作为峰.谷! c.只有当通道出现2.0%以 ...

  8. HDF 文件数据的读取

    http://www.cams.cma.gov.cn/cams_973/cheres_docs/cheres_doc_sat.modis.1b.html一. HDF文件格式 1.概述 HDF 是美国国 ...

  9. 防止基本的XSS攻击 滤掉HTML标签

    /** * 防止基本的XSS攻击 滤掉HTML标签 * 将HTML的特殊字符转换为了HTML实体 htmlentities * 将#和%转换为他们对应的实体符号 * 加上了$length参数来限制提交 ...

  10. SOA 面向服务架构 阅读笔记(二)

    SOA并不能保证企业的员工更加轻松,企业的收益更加客观. 6.软件组件 6.1  组件和组件的作用  通过可重用的软件代码-组件,可以构建灵活的软件. 6.2  软件组件又称为应用程序,程序,函数,模 ...