目的
- 记录 threejs 中常用几何体
- 记录 threejs 提供的比较奇葩的主题
- 记录心得
几何体
1、定义顶点
在 Threejs 中,根据 前章:点线面 中所说,点是由一组向量表示,代码为:THREE.Vector3( x, y, z )。
2、常用几何体
常用的几种几何体,Threejs 给与了定义:
(1)立方体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
THREE.CubeGeometry( width, height, depth, widthSegments, heightSegmenets, depthSegments ); // width :x轴方向上的长度 // height :y轴方向上的长度 // depth :z轴方向上的长度 // widthSegments :x轴方向上的分段数 // heightSegments :y轴方向上的分段数 // depthSegments :z轴方向上的分段数 // 分段的意思是对六个面进行分段,而不是对立方体的体素分段,因此在立方体的中间是不分段的 // 只有立方体的六个面进行分段 // example var cube = new THREE.CubeGeometry( 1, 2, 3 ); // 创建一个 宽1个单位 高2个单位 深3个单位 的立方体 |
(2)平面
1 2 3 4 5 6 7 8 9 |
THREE.PlaneGeometry( width, height, widthSegments, heightSegments ); // width :x轴方向上的长度 // height :y轴方向上的长度 // widthSegments :x轴方向上的分段数 // heightSegments :y轴方向上的分段数 // example var plane = new THREE.PlaneGeometry( 2, 4 ); // 创建一个 宽2个单位 高4个单位 的平面 |
(3)球体
1 2 3 4 5 6 7 8 9 10 11 12 13 |
THREE.SphereGeometry( radius, segmentsWidth, segmentsHeight, phiStart, phiLength, thetaStart, thetaLength ); // radius :球的半径 // segmentsWidth :经度上的切片数 // segmentsHeight :纬度上的切片数 // phiStart :经度开始的弧度 // phiLength :经度跨过的弧度 // thetaStart :纬度开始的弧度 // thetaLength :纬度跨过的弧度 // example var sphere = new THREE.SphereGeometry( 3, 8, 6 ); // 创建一个 半径为3 经度划分8份 纬度划分6份 的球体 var sphere = new THREE.SphereGeometry( 3, 8, 6, Math.PI / 2, Math.PI, Math.PI / 6, Math.PI / 2); |
(4)圆形
1 2 3 4 5 6 7 8 9 |
THREE.CircleGeometry( radius, segmenets, thetaStart, thetaLength ); // radius :圆的半径 // segmentsWidth :经度上的切片数 // thetaStart :纬度开始的弧度 // thetaLength :纬度跨过的弧度 // example var circle = new THREE.CircleGeometry( 3, 18, Math.PI / 3, Math.Pi / 3 * 4 ); // 创建一个在x轴和y轴所在平面的60°~240°三分之二圆的扇形 |
(5)圆柱体
1 2 3 4 5 6 7 8 9 10 11 12 13 |
THREE.CylinderGeometry( radiusTop, radiusBottom, height, radiusSegments, heightSegments. openEnded ); // radiusTop :顶面半径 // radiusBottom :底面半径 // height :圆柱体高度 // radiusSegments :顶面分段 // heightSegments :高度分段 // openEnded :boolean 是否没有顶面和底面 // example var cylinder = new THREE.CylinderGeometry( 2, 2, 4, 18, 3 ); // 创建一个 顶面和底面半径都为2 高度为4 的圆柱体 var cylinder = new THREE.CylinderGeometry( 2, 3, 4, 18, 3 ); // 创建一个 顶面半径为2 底面半径为3 高度为4 的圆台 var cylinder = new THREE.CylinderGeometry( 2, 3, 4, 18, 3, true ); // 创建一个 顶面半径为2 底面半径为3 高度为4 但是没有顶面和底面的圆台(去掉两个面) |
(6)正四面体、正八面体、正二十面体
1 2 3 4 5 6 7 8 9 10 11 |
THREE.TetrahedronGeometry(radius, detail); // 正四面体 THREE.OctahedronGeometry(radius, detail); // 正八面体 THREE.IcosahedronGeometry(radius, detail); // 正二十面体 // radius :半径 // detail :细节层次(Level of Detail)的层数 // example var tetrahedron = new THREE.TetrahedronGeometry( 3 ); // 创建一个半径为3的正四面体 var octchedron = new THREE.OctahedronGeometry( 3 ); // 创建一个半径为3的正八面体 var icosahedron = new THREE.IcosahedronGeometry( 3 ); // 创建一个半径为3的正二十面体 |
(7)圆环面
1 2 3 4 5 6 7 8 9 10 11 12 |
THREE.TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ); // radius :圆环半径 // tube :管道半径 // radialSegments :圆环半径分段数 // tubularSegments :管道半径分段数 // arc :圆环面的弧度 // example var torus = new THREE.TorusGeometry( 3, 1, 4, 8 ); // 创建一个粗糙的圆环面 var torus = new THREE.TorusGeometry( 3, 1, 12, 18 ); // 创建一个较为精细的圆环面 var torus = new THREE.TorusGeometry( 3, 1, 4, 8, Math.PI / 3 * 2); // 创建部分圆环面 |
(8)圆环结
1 2 3 4 5 6 7 8 9 10 11 12 |
THREE.TorusKnotGeometry( radius, tube, radialSegments, tubularSegments, p, g, heightScale ); // radius :圆环半径 // tube :管道半径 // radialSegments :圆环半径分段数 // tubularSegments :管道半径分段数 // p :p和q是样式控制参数,一般可以缺省 // q // heightScale :z轴方向上的缩放 // example var torusknot = new THREE.TorusKnotGeometry( 2, 0.5, 32, 8 ); |
(9)文字形状
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
THREE.TextGeometry(text, parameters); THREE.TextGeometry(text, { size :字号大小,一般为大写字母的高度, height :文字的厚度, curveSegments :弧线分段数,使得文字的曲线更加光滑, font :字体,默认是'helvetiker',需对应引用的字体文件, weight :值为'normal'或'bold',表示是否加粗, style :'值为'normal'或'italics',表示是否斜体', bevelEnabled :'布尔值,是否使用倒角,意为在边缘处斜切', bevelThickness :'倒角厚度', bevelSize :'倒角宽度' }); // example var text = new TextGeometry( 'Hello', { size : 1, height : 1 } ); // 三维文字 |
(10)自定义!!!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// 初始化几何形状 var w = 60, h = 200, d = 100, b = 5; var geometry = new THREE.Geometry(); // 设置顶点位置 // 左上开始顺时针:左上 → 右上 → 右下 → 左下 的顺序 // 顶部 4 顶点 geometry.vertices.push( new THREE.Vector3( -(w/2), 5, -(d/2) ) ); geometry.vertices.push( new THREE.Vector3( (w/2), 5, -(d/2) ) ); geometry.vertices.push( new THREE.Vector3( (w/2), 5, (d/2) ) ); geometry.vertices.push( new THREE.Vector3( -(w/2), 5, (d/2) ) ); // 底部 4 顶点 - 底面顺时针要注意顶点连接情况要与顶部相反,否则面朝向会为“里” geometry.vertices.push( new THREE.Vector3( -(w/2+b), 0, -(d/2+b) ) ); geometry.vertices.push( new THREE.Vector3( (w/2+b), 0, -(d/2+b) ) ); geometry.vertices.push( new THREE.Vector3( (w/2+b), 0, (d/2+b) ) ); geometry.vertices.push( new THREE.Vector3( -(w/2+b), 0, (d/2+b) ) ); // 设置顶点连接情况 // 根据 p1, p2, p3 的顺序,若这三个点的创建顺序相对与摄像机是顺时针的,那么这个面就是面向摄像机的 // 反之,若是逆时针,那么这个面就是背向摄像机的 // 这里是面向摄像机的,就是向外 // 顶面 geometry.faces.push( new THREE.Face3( 3, 1, 0 ) ); geometry.faces.push( new THREE.Face3( 3, 2, 1 ) ); // 底面 geometry.faces.push( new THREE.Face3( 4, 5, 6 ) ); geometry.faces.push( new THREE.Face3( 6, 7, 4 ) ); // 四个侧面 geometry.faces.push( new THREE.Face3( 6, 5, 1 ) ); geometry.faces.push( new THREE.Face3( 1, 2, 6 ) ); geometry.faces.push( new THREE.Face3( 7, 6, 2 ) ); geometry.faces.push( new THREE.Face3( 2, 3, 7 ) ); geometry.faces.push( new THREE.Face3( 0, 7, 3 ) ); geometry.faces.push( new THREE.Face3( 0, 4, 7 ) ); geometry.faces.push( new THREE.Face3( 5, 4, 0 ) ); geometry.faces.push( new THREE.Face3( 1, 5, 0 ) ); |
3、几何体相关理论以及感悟
建立 3D 图形的时候,可以通过对 物体 画一个工程图纸,画出三视图(正视图、侧视图、俯视图),根据三视图建立平面图形,然后在 3D 世界中通过旋转平移得到最终要的图形,进而构建出物体。
建立平面图形/立体图形时候,根据坐标原点作为中心点进行构建是最好的,因为这样方便在 x轴、y轴、z轴上 直接旋转,“姿态”摆好了之后再通过平移去移动物体。
例如:我建立一个柜子,每一个面都是一个正梯体作为部件,上面的自定义几何体例子就是柜子顶部和底部面的部件构建。