一、Shape
对象和轮廓填充ShapeGeometry
1. 填充顶点构成的轮廓
- 通过下面代码定义了
6
个顶点坐标,也可以说是5
个,最后一个和第一个是重合的, 构成一个五边形区域。然后使用这一组二维顶点坐标作为Shape的参数构成一个五边形轮廓。 把五边形轮廓Shape
作为ShapeGeometry
的参数,可以根据轮廓坐标计算出一系列三角形面填充轮廓, 形成一个平面几何体。javascriptconst 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); //网格模型对象