形状(Shape)

class Shape

Three.js 的 Shape 类是一个创建二维形状的强大工具,特别适用于生成轮廓复杂的几何图形,如自定义的 2D 图形和 3D 立体对象。Shape 继承自 Path,因此除了绘制路径的基本方法,还提供了一些用于构建和操作形状的功能。本文将深入探讨 Shape 的使用方法和示例,覆盖其属性和方法,并演示如何与其他 Three.js 组件结合使用,实现更复杂的三维效果。


1. Shape 基础概念

Shape 是一种特殊的二维路径,能够定义封闭轮廓并形成填充区域。可以使用 moveTo、lineTo、bezierCurveTo 等方法创建形状的轮廓,结合 ShapeGeometry 生成二维图案,或者使用 ExtrudeGeometry 转化为三维对象。

2. 创建 Shape

基本用法

const shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.lineTo(5, 0);
shape.lineTo(5, 5);
shape.lineTo(0, 5);
shape.lineTo(0, 0); // 闭合形状

此代码创建了一个简单的正方形 Shape,通过 moveTo 和 lineTo 方法定义形状的边界。

3. Shape 的方法

3.1 moveTo(x, y)

设置形状的起始点,适用于定义形状的起点。

3.2 lineTo(x, y)

在当前路径位置与指定的 (x, y) 坐标之间绘制直线。

3.3 quadraticCurveTo(cpX, cpY, x, y)

绘制二次贝塞尔曲线,cpX 和 cpY 为控制点坐标,x 和 y 为终点坐标。

3.4 bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, x, y)

用于绘制三次贝塞尔曲线,适合创建更流畅的曲线路径。

3.5 arc(x, y, radius, startAngle, endAngle, clockwise)

绘制圆弧或圆的一部分,提供圆心、半径和角度。

3.6 splineThru(points)

生成样条曲线,使路径平滑过渡,用于连接多个点。

3.7 holes

holes 是一个数组,可以通过 Shape 类添加内部孔洞,实现更复杂的几何形状。

const hole = new THREE.Path();
hole.moveTo(1, 1);
hole.lineTo(4, 1);
hole.lineTo(4, 4);
hole.lineTo(1, 4);
hole.lineTo(1, 1);

shape.holes.push(hole);

4. Shape 的应用示例

以下示例展示了如何使用 Shape 创建不同的图形和几何体。

示例 1:基本形状绘制

const shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.lineTo(5, 0);
shape.lineTo(5, 5);
shape.lineTo(0, 5);
shape.lineTo(0, 0);

const geometry = new THREE.ShapeGeometry(shape);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

该示例创建了一个简单的二维矩形形状,并将其添加到场景中。

示例 2:绘制带有贝塞尔曲线的形状

const shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.quadraticCurveTo(5, 10, 10, 0);
shape.lineTo(10, -10);
shape.bezierCurveTo(5, -15, -5, -15, -10, -10);
shape.lineTo(0, 0);

const geometry = new THREE.ShapeGeometry(shape);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

此示例通过 quadraticCurveTo 和 bezierCurveTo 方法绘制了复杂曲线,形成一个独特的二维形状。

示例 3:在形状中添加孔洞

孔洞可以通过 holes 属性来创建,并使用 Path 对象定义孔洞的路径。

const shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.lineTo(10, 0);
shape.lineTo(10, 10);
shape.lineTo(0, 10);
shape.lineTo(0, 0);

const holePath = new THREE.Path();
holePath.moveTo(3, 3);
holePath.lineTo(7, 3);
holePath.lineTo(7, 7);
holePath.lineTo(3, 7);
holePath.lineTo(3, 3);

shape.holes.push(holePath);

const geometry = new THREE.ShapeGeometry(shape);
const material = new THREE.MeshBasicMaterial({ color: 0x0000ff, side: THREE.DoubleSide });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

5. 结合 ExtrudeGeometry 创建三维形状

Shape 可以和 ExtrudeGeometry 结合使用,轻松生成三维对象。

const extrudeSettings = {
    steps: 2,
    depth: 5,
    bevelEnabled: true,
    bevelThickness: 1,
    bevelSize: 1,
    bevelSegments: 2
};

const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

此示例将二维 Shape 形状通过 ExtrudeGeometry 转化为一个具有深度的三维对象。

示例 6:结合动画效果

可以结合 Shape 和动画效果,使得物体在场景中呈现动态效果。下面的示例展示了一个沿着 Shape 定义路径的动画:

let t = 0;
const points = shape.getPoints(50); // 获取形状上的点
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: 0xffffff });
const line = new THREE.Line(geometry, material);
scene.add(line);

const animate = function () {
    requestAnimationFrame(animate);

    const point = points[Math.floor(t)];
    mesh.position.set(point.x, point.y, 0);

    t += 0.1;
    if (t >= points.length) t = 0;

    renderer.render(scene, camera);
};
animate();

6. Shape 的高级使用:创建自定义图标和标志

通过组合 Shape、Path、ExtrudeGeometry 和材质,可以在 Three.js 中实现自定义标志、图标等图形。

const shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.arc(0, 0, 5, 0, Math.PI * 2, false);

const textShape = new THREE.Shape();
textShape.moveTo(1, 2);
textShape.quadraticCurveTo(3, 3, 5, 5);

// 添加孔洞
shape.holes.push(textShape);

const geometry = new THREE.ExtrudeGeometry(shape, { depth: 1, bevelEnabled: false });
const material = new THREE.MeshStandardMaterial({ color: 0x00aa00, metalness: 0.5, roughness: 0.1 });
const icon = new THREE.Mesh(geometry, material);
scene.add(icon);

总结

Three.js 的 Shape 是创建和处理二维形状的一个非常强大的类,通过其丰富的方法和属性,可以构建出复杂的几何图形。在实际应用中,Shape 可用于创建三维图标、徽章和动态路径对象,结合动画效果和其他 Three.js 组件,可以实现丰富的交互和动态效果。希望通过本文的讲解和示例代码,您能熟练掌握 Shape 的用法,为项目增添更多创意与实用功能。

评论区
评论列表
menu