课程表

three.js课程

工具箱
速查手册

Three 几何体建模

当前位置:免费教程 » JS/JS库/框架 » three.js

本章节主要是介绍一些绘制二维或三维图形的类,如果大多数类你暂时用不到,也可以不用学习,用到的时候可以来查阅特定的章节。

如果你想通过一系列的顶点数据生成一个轮廓,比如中国地图,如果你想通过一条曲线生成一个管道,如果你想通过一个二维轮廓拉伸或扫描出来一个三维几何体,如果你想绘制一个圆弧轨迹...都可以查阅本节课内容。

1.jpg

2.png

3.png

4.png


常见几何体和曲线API介绍

本节主要内容是对Threejs几何体和曲线相关的API进行一个整体的介绍,更具体的介绍可以查看本章后面几节课程。

几何体

关于Threejs常见的几何体类下面通过一个脑图进行了简单的分类。

几何体本质上就是threejs生成顶点的算法,如果有兴趣你可以打开threejs几何体部分的源码查看threejs具体如何通过程序生成顶点位置、法线方向等顶点数据。

所有几何体的基类分为Geometry和BufferGeometry两大类,两类几何体直接可以相互转化。

1.jpg

曲线

曲线和几何体同样本质上都是用来生成顶点的算法,曲线主要是按照一定的规则生成一系列沿着某条轨迹线分布的顶点。当你把曲线、几何体看成顶点的时候,查考文档很多属性和方法自然很同意理解。

1.jpg


直线、椭圆、圆弧、基类Curve

本节通过介绍直线、圆弧线,以及这些曲线的基类Curve。

圆弧线ArcCurve

圆弧线ArcCurve的基类是椭圆弧线EllipseCurve,关于圆弧线的使用方法可以查看threejs文档中的椭圆弧线。

  1. ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise )


                    参数                    含义
                    aX, aY                    圆弧圆心坐标
                    aRadius                    圆弧半径
                    aStartAngle, aEndAngle                    起始角度
                    aClockwise                    是否顺时针绘制,默认值为false


  1. //参数:0, 0圆弧坐标原点x,y  100:圆弧半径    0, 2 * Math.PI:圆弧起始角度
  2. var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);

曲线Curve方法.getPoints()

.getPoints()是基类Curve的方法,圆弧线ArcCurve的基类是椭圆弧线EllipseCurve,椭圆弧线的基类是曲线Curve,所以圆弧线具有Curve的方法.getPoints()。

通过方法.getPoints()可以从圆弧线按照一定的细分精度返回沿着圆弧线分布的顶点坐标。细分数越高返回的顶点数量越多,自然轮廓越接近于圆形。方法.getPoints()的返回值是一个由二维向量Vector2或三维向量Vector3构成的数组,Vector2表示位于同一平面内的点,Vector3表示三维空间中一点。

  1. var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);
  2. //getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组
  3. var points = arc.getPoints(50);//分段数50,返回51个顶点

几何体方法.setFromPoints()

.setFromPoints()是几何体Geometry的方法,通过该方法可以把数组points中顶点数据提取出来赋值给几何体的顶点位置属性geometry.vertices,数组points的元素是二维向量Vector2或三维向量Vector3。

BufferGeometry和Geometry一样具有方法.setFromPoints(),不过区别是提取顶点数据后赋值给geometry.attributes.position属性。

  1. // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
  2. geometry.setFromPoints(points);
  3. console.log(geometry.vertices);
  4. // 如果几何体是BufferGeometry,setFromPoints方法改变的是.attributes.position属性
  5. // console.log(geometry.attributes.position);

绘制圆弧线案例

使用threejs的API圆弧线ArcCurve绘制一个圆弧轮廓:

  1. var geometry = new THREE.BufferGeometry(); //声明一个几何体对象
  2. //参数:0, 0圆弧坐标原点x,y  100:圆弧半径    0, 2 * Math.PI:圆弧起始角度
  3. var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);
  4. //getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组
  5. var points = arc.getPoints(50);//分段数50,返回51个顶点
  6. // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
  7. geometry.setFromPoints(points);
  8. //材质对象
  9. var material = new THREE.LineBasicMaterial({
  10.   color: 0x000000
  11. });
  12. //线条模型对象
  13. var line = new THREE.Line(geometry, material);
  14. scene.add(line); //线条对象添加到场景中

在线运行案例

和上面绘制圆弧线代码实现的功能相同,不过没有借助圆弧线THREE.ArcCurve,通过三角函数计算生成圆弧线上的顶点。设置这个案例的目的就是,你可以通过对比两个代码案例,明白Threejs一些曲线API本质上就是通过某种算法得到了沿着特定轨迹的顶点数据

  1. var geometry = new THREE.Geometry(); //声明一个几何体对象
  2. var R = 100; //圆弧半径
  3. var N = 50; //分段数量
  4. // 批量生成圆弧上的顶点数据
  5. for (var i = 0; i < N; i++) {
  6.   var angle = 2 * Math.PI / N * i;
  7.   var x = R * Math.sin(angle);
  8.   var y = R * Math.cos(angle);
  9.   geometry.vertices.push(new THREE.Vector3(x, y, 0));
  10. }
  11. // 插入最后一个点,line渲染模式下,产生闭合效果
  12. // geometry.vertices.push(geometry.vertices[0])
  13. //材质对象
  14. var material = new THREE.LineBasicMaterial({
  15.   color: 0x000000
  16. });
  17. //线条模型对象
  18. var line = new THREE.Line(geometry, material);
  19. scene.add(line); //线条对象添加到场景中

绘制直线效果

直接给几何体Geometry设置两个顶点数据。

  1. var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
  2. var p1 = new THREE.Vector3(50, 0, 0); //顶点1坐标
  3. var p2 = new THREE.Vector3(0, 70, 0); //顶点2坐标
  4. //顶点坐标添加到geometry对象
  5. geometry.vertices.push(p1, p2);
  6. var material = new THREE.LineBasicMaterial({
  7.   color: 0xffff00,
  8. });//材质对象
  9. //线条模型对象
  10. var line = new THREE.Line(geometry, material);
  11. scene.add(line); //线条对象添加到场景中

通过LineCurve3绘制一条三维直线:

  1. var geometry = new THREE.BufferGeometry(); //声明一个几何体对象
  2. var p1 = new THREE.Vector3(50, 0, 0); //顶点1坐标
  3. var p2 = new THREE.Vector3(0, 70, 0); //顶点2坐标
  4. // 三维直线LineCurve3
  5. var LineCurve = new THREE.LineCurve3(p1, p2);
  6. // 二维直线LineCurve
  7. var LineCurve = new THREE.LineCurve(new THREE.Vector2(50, 0), new THREE.Vector2(0, 70));
  8. var pointArr = LineCurve.getPoints(10);
  9. geometry.setFromPoints(pointArr);
  10.  
  11. var material = new THREE.LineBasicMaterial({
  12.   color: 0xffff00,
  13. });//材质对象
  14. //线条模型对象
  15. var line = new THREE.Line(geometry, material);
  16. scene.add(line); //线条对象添加到场景中

通过LineCurve绘制一条二维直线:

  1. var geometry2 = new THREE.BufferGeometry(); //声明一个几何体对象Geometry
  2. var p1 = new THREE.Vector2(150, 0); //顶点1坐标
  3. var p2 = new THREE.Vector2(0, 70); //顶点2坐标
  4. // 二维直线LineCurve
  5. var LineCurve = new THREE.LineCurve(p1, p2);
  6. var pointArr = LineCurve.getPoints(10);
  7. geometry2.setFromPoints(pointArr);
  8.  var material2 = new THREE.LineBasicMaterial({
  9.   color: 0xff0000,
  10. });//材质对象
  11. //线条模型对象
  12. var line2 = new THREE.Line(geometry2, material2);
  13. scene.add(line2); //线条对象添加到场景中

在线运行案例


样条曲线、贝赛尔曲线

规则的曲线比如圆、椭圆、抛物线都可以用一个函数去描述,对于不规则的曲线无法使用一个特定的函数去描述,这也就是样条曲线和贝塞尔曲线出现的原因。Threejs提供了这两种曲线的API,不需要自己封装,如果你想深入研究可以学习计算机图形学。

1.jpg

一条光滑样条曲线案例

在三维空间中设置5个顶点,输入三维样条曲线CatmullRomCurve3作为参数,然后返回更多个顶点,通过返回的顶点数据,构建一个几何体,通过Line可以绘制出来一条沿着5个顶点的光滑样条曲线。

  1. var geometry = new THREE.BufferGeometry(); //声明一个几何体对象
  2. // 三维样条曲线  Catmull-Rom算法
  3. var curve = new THREE.CatmullRomCurve3([
  4.   new THREE.Vector3(-50, 20, 90),
  5.   new THREE.Vector3(-10, 40, 40),
  6.   new THREE.Vector3(0, 0, 0),
  7.   new THREE.Vector3(60, -60, 0),
  8.   new THREE.Vector3(70, 0, 80)
  9. ]);
  10. //getPoints是基类Curve的方法,返回一个vector3对象作为元素组成的数组
  11. var points = curve.getPoints(100); //分段数100,返回101个顶点
  12. // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
  13. geometry.setFromPoints(points);
  14. //材质对象
  15. var material = new THREE.LineBasicMaterial({
  16.   color: 0x000000
  17. });
  18. //线条模型对象
  19. var line = new THREE.Line(geometry, material);
  20. scene.add(line); //线条对象添加到场景中

在线运行案例

通过调用threejs样条曲线或贝塞尔曲线的API,你可以输入有限个顶点返回更多顶点,然后绘制一条光滑的轮廓曲线。

贝塞尔曲线

贝塞尔曲线和样条曲线不同,多了一个控制点概念。

二次贝赛尔曲线的参数p1、p3是起始点,p2是控制点,控制点不在贝塞尔曲线上。

  1. var p1 = new THREE.Vector3(-80, 0, 0);
  2. var p2 = new THREE.Vector3(20, 100, 0);
  3. var p3 = new THREE.Vector3(80, 0, 0);
  4. // 三维二次贝赛尔曲线
  5. var curve = new THREE.QuadraticBezierCurve3(p1, p2, p3);

二次贝赛尔曲线的参数p1、p4是起始点,p2、p3是控制点,控制点不在贝塞尔曲线上。

  1. var p1 = new THREE.Vector3(-80, 0, 0);
  2. var p2 = new THREE.Vector3(-40, 100, 0);
  3. var p3 = new THREE.Vector3(40, 100, 0);
  4. var p4 = new THREE.Vector3(80, 0, 0);
  5. // 三维三次贝赛尔曲线
  6. var curve = new THREE.CubicBezierCurve3(p1, p2, p3, p4);

在线运行案例


多个线条组合曲线CurvePath

通过组合曲线CurvePath可以把多个圆弧线、样条曲线、直线等多个曲线合并成一个曲线。

1.jpg

U型案例

  1. var geometry = new THREE.BufferGeometry(); //声明一个几何体对象Geometry
  2. // 绘制一个U型轮廓
  3. var R = 80;//圆弧半径
  4. var arc = new THREE.ArcCurve(0, 0, R, 0, Math.PI, true);
  5. // 半圆弧的一个端点作为直线的一个端点
  6. var line1 = new THREE.LineCurve(new THREE.Vector2(R, 200, 0), new THREE.Vector2(R, 0, 0));
  7. var line2 = new THREE.LineCurve(new THREE.Vector2(-R, 0, 0), new THREE.Vector2(-R, 200, 0));
  8. // 创建组合曲线对象CurvePath
  9. var CurvePath = new THREE.CurvePath();
  10. // 把多个线条插入到CurvePath中
  11. CurvePath.curves.push(line1, arc, line2);
  12. //分段数200
  13. var points = CurvePath.getPoints(200);
  14. // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
  15. geometry.setFromPoints(points);
  16. //材质对象
  17. var material = new THREE.LineBasicMaterial({
  18.   color: 0x000000
  19. });
  20. //线条模型对象
  21. var line = new THREE.Line(geometry, material);
  22. scene.add(line); //线条对象添加到场景中

在线运行案例


曲线路径管道成型TubeGeometry

TubeGeometry的功能就是通过一条曲线生成一个圆管。它的本质就是以曲线上顶点为基准,生成一系列曲线等径分布的顶点数据, 具体算法如何实现的可以查看three.js引擎源码。

构造函数格式:

  1. TubeGeometry(path, tubularSegments, radius, radiusSegments, closed)
                参数                值
                path                扫描路径,基本类是Curve的路径构造函数
                tubularSegments                路径方向细分数,默认64
                radius                管道半径,默认1
                radiusSegments                管道圆弧细分数,默认8
                closed                Boolean值,管道是否闭合

样条曲面生成圆管案例

  1. //创建管道成型的路径(3D样条曲线)
  2. var path = new THREE.CatmullRomCurve3([
  3.   new THREE.Vector3(-10, -50, -50),
  4.   new THREE.Vector3(10, 0, 0),
  5.   new THREE.Vector3(8, 50, 50),
  6.   new THREE.Vector3(-5, 0, 100)
  7. ]);
  8. // path:路径   40:沿着轨迹细分数  10:管道半径   25:管道截面圆细分数
  9. var geometry = new THREE.TubeGeometry(path, 40, 10, 25);

你也可以使用下面直线替换上面的样条曲线查看圆管生成效果:

  1. // LineCurve3创建直线段路径
  2. var path = new THREE.LineCurve3(new THREE.Vector3(0, 100, 0), new THREE.Vector3(0, 0, 0));

在线运行案例

CurvePath多段路径生成管道案例

通过下面代码创建了一段样条曲线和两条直线拼接成的路径,然后通过曲线路径CurvePath把样条曲线和料条曲线合并成为一条路径。

  1. // 创建多段线条的顶点数据
  2. var p1 = new THREE.Vector3(-85.35, -35.36)
  3. var p2 = new THREE.Vector3(-50, 0, 0);
  4. var p3 = new THREE.Vector3(0, 50, 0);
  5. var p4 = new THREE.Vector3(50, 0, 0);
  6. var p5 = new THREE.Vector3(85.35, -35.36);
  7. // 创建线条一:直线
  8. let line1 = new THREE.LineCurve3(p1,p2);
  9. // 重建线条2:三维样条曲线
  10. var curve = new THREE.CatmullRomCurve3([p2, p3, p4]);
  11. // 创建线条3:直线
  12. let line2 = new THREE.LineCurve3(p4,p5);
  13. var CurvePath = new THREE.CurvePath();// 创建CurvePath对象
  14. CurvePath.curves.push(line1, curve, line2);// 插入多段线条
  15. //通过多段曲线路径创建生成管道
  16. //通过多段曲线路径创建生成管道,CCurvePath:管道路径
  17. var geometry2 = new THREE.TubeGeometry(CurvePath, 100, 5, 25, false);

在线运行案例


旋转造型LatheGeometry

3.png

生活中有很多的几何体具备旋转特征,比如球体,常见杯子, three.js提供了一个构造函数LatheGeometry(), LatheGeometry可以利用已有的二维数据生成三维顶点数据,二维数据可以通过二维向量对象Vector2定义,也可以通过3D曲线或2D线条轮廓生成。 LatheGeometry的二维坐标数据默认绕y轴旋转。

格式:

  1. LatheGeometry(points, segments, phiStart, phiLength)


                    参数                    值
                    points                    Vector2表示的坐标数据组成的数组
                    segments                    圆周方向细分数,默认12
                    phiStart                    开始角度,默认0
                    phiLength                    旋转角度,默认2&pi;


  1. /**
  2.  * 创建旋转网格模型
  3.  */
  4. var points = [
  5.     new THREE.Vector2(50,60),
  6.     new THREE.Vector2(25,0),
  7.     new THREE.Vector2(50,-60)
  8. ];
  9. var geometry = new THREE.LatheGeometry(points,30);
  10. var material=new THREE.MeshPhongMaterial({
  11.     color:0x0000ff,//三角面颜色
  12.     side:THREE.DoubleSide//两面可见
  13. });//材质对象
  14. material.wireframe = true;//线条模式渲染(查看细分数)
  15. var mesh=new THREE.Mesh(geometry,material);//旋转网格模型对象
  16. scene.add(mesh);//旋转网格模型添加到场景中

在线运行案例

样条曲线插值计算

借助Shape对象的方法.splineThru(),把上面的三个顶点进行样条插值计算, 可以得到一个光滑的旋转曲面。

  1. var shape = new THREE.Shape();//创建Shape对象
  2. var points = [//定位定点
  3.     new THREE.Vector2(50,60),
  4.     new THREE.Vector2(25,0),
  5.     new THREE.Vector2(50,-60)
  6. ];
  7. shape.splineThru(points);//顶点带入样条插值计算函数
  8. var splinePoints = shape.getPoints(20);//插值计算细分数20
  9. var geometry = new THREE.LatheGeometry(splinePoints,30);//旋转造型

在线运行案例

shape.getPoints(20)的作用是利用已有的顶点插值计算出新的顶点,两个顶点之间插值计算出20个顶点,如果细分数是1不是20,相当于不进行插值计算, 插值计算的规则通过Shape对象的方法.splineThru()定义,几何曲线的角度描述,splineThru的作用就是创建一个样条曲线,除了样条曲线还可以使用贝赛尔等曲线进行插值计算。


Shape对象和轮廓填充ShapeGeometry

1.jpg

填充顶点构成的轮廓

通过下面代码定义了6个顶点坐标,也可以说是5个,最后一个和第一个是重合的,构成一个五边形区域。然后使用这一组二维顶点坐标作为Shape的参数构成一个五边形轮廓。把五边形轮廓Shape作为ShapeGeometry的参数,可以根据轮廓坐标计算出一系列三角形面填充轮廓,形成一个平面几何体。

1.jpg

  1. var points = [
  2.   new THREE.Vector2(-50, -50),
  3.   new THREE.Vector2(-60, 0),
  4.   new THREE.Vector2(0, 50),
  5.   new THREE.Vector2(60, 0),
  6.   new THREE.Vector2(50, -50),
  7.   new THREE.Vector2(-50, -50),
  8. ]
  9. // 通过顶点定义轮廓
  10. var shape = new THREE.Shape(points);
  11. // shape可以理解为一个需要填充轮廓
  12. // 所谓填充:ShapeGeometry算法利用顶点计算出三角面face3数据填充轮廓
  13. var geometry = new THREE.ShapeGeometry(shape, 25);

调用Shape圆弧方法.absarc()绘制一个圆形轮廓,然后通过ShapeGeometry可以把该圆形轮廓填充为一个圆形平面几何体。

你可以尝试更改ShapeGeometry的参数2,参数2表示细分数,然后网格材质设置为wireframe: true查看圆形区域填充三角形的数量变化。

  1. // 通过shpae基类path的方法绘制轮廓(本质也是生成顶点)
  2. var shape = new THREE.Shape();
  3. shape.absarc(0,0,100,0,2*Math.PI);//圆弧轮廓
  4. console.log(shape.getPoints(15));//查看shape顶点数据
  5. var geometry = new THREE.ShapeGeometry(shape, 25);

下面代码是通过shpae绘制了一个矩形区域,更多相关的轮廓绘制方法可以查看Shape文档。

  1. // 通过shpae基类path的方法绘制轮廓(本质也是生成顶点)
  2. var shape = new THREE.Shape();
  3. // 四条直线绘制一个矩形轮廓
  4. shape.moveTo(0,0);//起点
  5. shape.lineTo(0,100);//第2点
  6. shape.lineTo(100,100);//第3点
  7. shape.lineTo(100,0);//第4点
  8. shape.lineTo(0,0);//第5点

shape外轮廓和内轮廓

shape可以用来绘制外轮廓,也可以用来绘制内轮廓,ShapeGeometry会使用三角形自动填充shape内轮廓和外轮廓中间的中部。

下面给出了几个通过shape绘制的轮廓图案。

  1. // 圆弧与直线连接
  2. var shape = new THREE.Shape(); //Shape对象
  3. var R = 50;
  4. // 绘制一个半径为R、圆心坐标(0, 0)的半圆弧
  5. shape.absarc(0, 0, R, 0, Math.PI);
  6. //从圆弧的一个端点(-R, 0)到(-R, -200)绘制一条直线
  7. shape.lineTo(-R, -200);
  8. // 绘制一个半径为R、圆心坐标(0, -200)的半圆弧
  9. shape.absarc(0, -200, R, Math.PI, 2 * Math.PI);
  10. //从圆弧的一个端点(R, -200)到(-R, -200)绘制一条直线
  11. shape.lineTo(R, 0);
  12. var geometry = new THREE.ShapeGeometry(shape, 30);

在线运行案例

一个带孔的原型图案:

  1. // 一个外轮廓圆弧嵌套三个内圆弧轮廓
  2. var shape = new THREE.Shape(); //Shape对象
  3. //外轮廓
  4. shape.arc(0, 0, 100, 0, 2 * Math.PI);
  5. // 内轮廓1
  6. var path1 = new THREE.Path();
  7. path1.arc(0, 0, 40, 0, 2 * Math.PI);
  8. // 内轮廓2
  9. var path2 = new THREE.Path();
  10. path2.arc(80, 0, 10, 0, 2 * Math.PI);
  11. // 内轮廓3
  12. var path3 = new THREE.Path();
  13. path3.arc(-80, 0, 10, 0, 2 * Math.PI);
  14. //三个内轮廓分别插入到holes属性中
  15. shape.holes.push(path1, path2, path3);

1.jpg

一个正方形的框子:

  1. // 矩形嵌套矩形或圆弧
  2. var shape=new THREE.Shape();//Shape对象
  3. //外轮廓
  4. shape.moveTo(0,0);//起点
  5. shape.lineTo(0,100);//第2点
  6. shape.lineTo(100,100);//第3点
  7. shape.lineTo(100,0);//第4点
  8. shape.lineTo(0,0);//第5点
  9.  
  10. //内轮廓
  11. var path=new THREE.Path();//path对象
  12. // path.arc(50,50,40,0,2*Math.PI);//圆弧
  13. path.moveTo(20,20);//起点
  14. path.lineTo(20,80);//第2点
  15. path.lineTo(80,80);//第3点
  16. path.lineTo(80,20);//第4点
  17. path.lineTo(20,20);//第5点
  18. shape.holes.push(path);//设置内轮廓

1.jpg

多个轮廓同时填充:

  1. // 轮廓对象1
  2.  var shape=new THREE.Shape();
  3.  shape.arc(-50,0,30,0,2*Math.PI);
  4.  // 轮廓对象2
  5.  var shape2=new THREE.Shape();
  6.  shape2.arc(50,0,30,0,2*Math.PI);
  7.  // 轮廓对象3
  8.  var shape3=new THREE.Shape();
  9.  shape3.arc(0,50,30,0,2*Math.PI);
  10. // 多个shape作为元素组成数组,每一个shpae可以理解为一个要填充的轮廓
  11. var geometry = new THREE.ShapeGeometry([shape,shape2,shape3], 30);

1.jpg

根据河南边界坐标填充轮廓:

  1. // 河南边界轮廓坐标
  2. let arr = [
  3.   [110.3906, 34.585],
  4.   [110.8301, 34.6289],
  5. ...
  6. ...
  7. ...
  8.   [110.6543, 34.1455],
  9.   [110.4785, 34.2334],
  10.   [110.3906, 34.585]
  11. ]
  12. var points = [];
  13. // 转化为Vector2构成的顶点数组
  14. arr.forEach(elem => {
  15.   points.push(new THREE.Vector2(elem[0],elem[1]))
  16. });
  17. // 样条曲线生成更多的点
  18. var SplineCurve = new THREE.SplineCurve(points)
  19. var shape = new THREE.Shape(SplineCurve.getPoints(300));
  20. // var shape = new THREE.Shape(points);
  21. var geometry = new THREE.ShapeGeometry(shape);
  22. geometry.center();//几何体居中
  23. geometry.scale(30,30,30);//几何体缩放
  24. var material = new THREE.MeshPhongMaterial({
  25.   color: 0x0000ff,
  26.   side: THREE.DoubleSide //两面可见
  27. }); //材质对象
  28. var mesh = new THREE.Mesh(geometry, material); //网格模型对象

1.jpg


拉伸扫描成型ExtrudeGeometry

2.png

构造函数ExtrudeGeometry()和ShapeGeometry一样是利用Shape对象生成几何体对象,区别在于ExtrudeGeometry()可以利用2D轮廓生成3D模型, 如果你使用任何三维软件都知道可以先绘制一个二维的轮廓图,然后拉伸成型得到三维模型。ExtrudeGeometry()第二个参数是拉伸参数,数据类型是对象, 属性amount表示拉伸长度,bevelEnabled表示拉伸是否产生倒角,其它参数见下表。

构造函数ExtrudeGeometry()拉伸参数


                参数                含义
                amount                拉伸长度,默认100
                bevelEnabled                是否使用倒角
                bevelSegments                倒角细分数,默认3
                bevelThickness                倒角尺寸(经向)
                curveSegments                拉伸轮廓细分数
                steps                拉伸方向细分数
                extrudePath                扫描路径THREE.CurvePath,默认Z轴方向
                material                前后面材质索引号
                extrudeMaterial                拉伸面、倒角面材质索引号
                bevelSize                倒角尺寸(拉伸方向)


  1. /**
  2.  * 创建拉伸网格模型
  3.  */
  4. var shape = new THREE.Shape();
  5. /**四条直线绘制一个矩形轮廓*/
  6. shape.moveTo(0,0);//起点
  7. shape.lineTo(0,100);//第2点
  8. shape.lineTo(100,100);//第3点
  9. shape.lineTo(100,0);//第4点
  10. shape.lineTo(0,0);//第5点
  11. var geometry = new THREE.ExtrudeGeometry(//拉伸造型
  12.     shape,//二维轮廓
  13.     //拉伸参数
  14.     {
  15.         amount:150,//拉伸长度
  16.         bevelEnabled:false//无倒角
  17.     }
  18.     );

通过使用点模式渲染上面的几何体,可以看出几何体拉伸的本质效果就是空间分布顶点数据的产生。

  1. var material=new THREE.PointsMaterial({
  2.     color:0x0000ff,
  3.     size:5.0//点对象像素尺寸
  4. });//材质对象
  5. var mesh=new THREE.Points(geometry,material);//点模型对象
  6. scene.add(mesh);//点模型添加到场景中

在线运行案例

扫描

4.png

拉伸和扫描一样都是三维造型建模方法,three.js提供了一个共同的构造函数来实现扫描和拉伸,对于扫描而言不需要定义amount属性设置拉伸距离,设置扫描路径即可, 定义属性extrudePath,extrudePath的值是路径THREE.CurvePath,可以通过样条曲线、贝赛尔曲线构造函数创建不规则曲线扫描轨迹。

  1. /**
  2. * 创建扫描网格模型
  3. */
  4. var shape = new THREE.Shape();
  5. /**四条直线绘制一个矩形轮廓*/
  6. shape.moveTo(0,0);//起点
  7. shape.lineTo(0,10);//第2点
  8. shape.lineTo(10,10);//第3点
  9. shape.lineTo(10,0);//第4点
  10. shape.lineTo(0,0);//第5点
  11. // 三维样条曲线  Catmull-Rom算法
  12. var curve = new THREE.CatmullRomCurve3([
  13.   new THREE.Vector3(-50, 20, 90),
  14.   new THREE.Vector3(-10, 40, 40),
  15.   new THREE.Vector3(0, 0, 0),
  16.   new THREE.Vector3(60, -60, 0),
  17.   new THREE.Vector3(70, 0, 80)
  18. ]);
  19. var geometry = new THREE.ExtrudeGeometry(//拉伸造型
  20.    shape,//二维轮廓
  21.    //拉伸参数
  22.    {
  23.        bevelEnabled:false,//无倒角
  24.        extrudePath:curve,//选择扫描轨迹
  25.        steps:50//扫描方向细分数
  26.    }
  27. );

在线运行案例

转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号