形状(Shape)

person 少陵野老    watch_later 2024-10-27 12:50:51
visibility 88    class Shape    bookmark 专栏

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


1. Shape 基础概念

Shape 是一种特殊的二维路径,能够定义封闭轮廓并形成填充区域。可以使用 moveTolineTobezierCurveTo 等方法创建形状的轮廓,结合 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,通过 moveTolineTo 方法定义形状的边界。

3. Shape 的方法

3.1 moveTo(x, y)

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

3.2 lineTo(x, y)

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

3.3 quadraticCurveTo(cpX, cpY, x, y)

绘制二次贝塞尔曲线,cpXcpY 为控制点坐标,xy 为终点坐标。

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);

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

示例 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 的高级使用:创建自定义图标和标志

通过组合 ShapePathExtrudeGeometry 和材质,可以在 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