Skip to content

一、Shape对象和轮廓填充ShapeGeometry

curve-12.png

1. 填充顶点构成的轮廓

  • 通过下面代码定义了6个顶点坐标,也可以说是5个,最后一个和第一个是重合的, 构成一个五边形区域。然后使用这一组二维顶点坐标作为Shape的参数构成一个五边形轮廓。 把五边形轮廓Shape作为ShapeGeometry的参数,可以根据轮廓坐标计算出一系列三角形面填充轮廓, 形成一个平面几何体。
    javascript
      const points = [
        new THREE.Vector2(-50, -50),
        new THREE.Vector2(-60, 0),
        new THREE.Vector2(0, 50),
        new THREE.Vector2(60, 0),
        new THREE.Vector2(50, -50),
        new THREE.Vector2(-50, -50),
      ]
      // 通过顶点定义轮廓
      const shape = new THREE.Shape(points);
      // shape可以理解为一个需要填充轮廓
      // 所谓填充:ShapeGeometry算法利用顶点计算出三角面face3数据填充轮廓
      const geometry = new THREE.ShapeGeometry(shape, 25);
  • 调用Shape圆弧方法.absarc()绘制一个圆形轮廓,然后通过ShapeGeometry可以把该圆形轮廓填充为一个圆形平面几何体。
  • 可以尝试更改ShapeGeometry的参数2,参数2表示细分数,然后网格材质设置为wireframe: true查看圆形区域填充三角形的数量变化。
    javascript
      // 通过shpae基类path的方法绘制轮廓(本质也是生成顶点)
      const shape = new THREE.Shape();
      shape.absarc(0,0,100,0,2*Math.PI);//圆弧轮廓
      console.log(shape.getPoints(15));//查看shape顶点数据
      const geometry = new THREE.ShapeGeometry(shape, 25);

2. shape外轮廓和内轮廓

  • shape可以用来绘制外轮廓,也可以用来绘制内轮廓,ShapeGeometry会使用三角形自动填充shape内轮廓和外轮廓中间的中部。
    javascript
     // 圆弧与直线连接
     const shape = new THREE.Shape(); //Shape对象
     const R = 50;
     // 绘制一个半径为R、圆心坐标(0, 0)的半圆弧
     shape.absarc(0, 0, R, 0, Math.PI);
     //从圆弧的一个端点(-R, 0)到(-R, -200)绘制一条直线
     shape.lineTo(-R, -200);
     // 绘制一个半径为R、圆心坐标(0, -200)的半圆弧
     shape.absarc(0, -200, R, Math.PI, 2 * Math.PI);
     //从圆弧的一个端点(R, -200)到(-R, -200)绘制一条直线
     shape.lineTo(R, 0);
     const geometry = new THREE.ShapeGeometry(shape, 30);
    javascript
     // 一个外轮廓圆弧嵌套三个内圆弧轮廓
     const shape = new THREE.Shape(); //Shape对象
     //外轮廓
     shape.arc(0, 0, 100, 0, 2 * Math.PI);
     // 内轮廓1
     const path1 = new THREE.Path();
     path1.arc(0, 0, 40, 0, 2 * Math.PI);
     // 内轮廓2
     const path2 = new THREE.Path();
     path2.arc(80, 0, 10, 0, 2 * Math.PI);
     // 内轮廓3
     const path3 = new THREE.Path();
     path3.arc(-80, 0, 10, 0, 2 * Math.PI);
     //三个内轮廓分别插入到holes属性中
     shape.holes.push(path1, path2, path3);
    javascript
     // 矩形嵌套矩形或圆弧
     const shape = new THREE.Shape();//Shape对象
     //外轮廓
     shape.moveTo(0,0);//起点
     shape.lineTo(0,100);//第2点
     shape.lineTo(100,100);//第3点
     shape.lineTo(100,0);//第4点
     shape.lineTo(0,0);//第5点
     //内轮廓
     const path = new THREE.Path();//path对象
     // path.arc(50,50,40,0,2*Math.PI);//圆弧
     path.moveTo(20,20);//起点
     path.lineTo(20,80);//第2点
     path.lineTo(80,80);//第3点
     path.lineTo(80,20);//第4点
     path.lineTo(20,20);//第5点
     shape.holes.push(path);//设置内轮廓
    javascript
     // 轮廓对象1
     const shape=new THREE.Shape();
     shape.arc(-50,0,30,0,2*Math.PI);
     // 轮廓对象2
     const shape2=new THREE.Shape();
     shape2.arc(50,0,30,0,2*Math.PI);
     // 轮廓对象3
     const shape3=new THREE.Shape();
     shape3.arc(0,50,30,0,2*Math.PI);
     // 多个shape作为元素组成数组,每一个shpae可以理解为一个要填充的轮廓
     const geometry = new THREE.ShapeGeometry([shape,shape2,shape3], 30);
    javascript
     // 河南边界轮廓坐标
     const arr = [
     [110.3906, 34.585],
     [110.8301, 34.6289],
     [110.6543, 34.1455],
     [110.4785, 34.2334],
     [110.3906, 34.585]
     ]
     const points = [];
     // 转化为Vector2构成的顶点数组
     arr.forEach(elem => {
         points.push(new THREE.Vector2(elem[0],elem[1]))
     });
     // 样条曲线生成更多的点
     const SplineCurve = new THREE.SplineCurve(points)
     const shape = new THREE.Shape(SplineCurve.getPoints(300));
     // const shape = new THREE.Shape(points);
     const geometry = new THREE.ShapeGeometry(shape);
     geometry.center();//几何体居中
     geometry.scale(30,30,30);//几何体缩放
     const material = new THREE.MeshPhongMaterial({
         color: 0x0000ff,
         side: THREE.DoubleSide //两面可见
     }); //材质对象
     const mesh = new THREE.Mesh(geometry, material); //网格模型对象

Released under the MIT License.