本章主要学习知识点
- 学习如何生成圆弧
- 了解立方体和直线之间的关系
- 了解曲线的基本概念
- 使用曲线在场景中创建圆和椭圆
- 了解什么是样条曲线,并使用样条曲线绘制不同的线条
- 使用贝塞尔曲线创建线条
生成圆弧顶点
通过顶点生成圆弧,首先要选定圆心和半径,确定要生成的顶点数量,这决定了圆弧的平滑程度
js
// 设置圆心坐标
const cx = 5;
const cy = 5;
const R = 10; // 圆的半径
const N = 100; // 顶点数量
const sp = 2*Math.PI / N; // 每个顶点之间的弧度
这里设置顶点数为100,要如何获取到每个顶点的坐标呢,可以通过三角函数计算出每个顶点的坐标
js
const arr = [];
for (let i = 0; i <= N; i++) {
const angle = sp*i;
const x = cx+ R * Math.cos(angle)
const y = cy+ R * Math.sin(angle)
arr.push(x,y, 0)
}
设置几何体的顶点,通过使用LineLoop
连接各个顶点
js
geometry.setAttribute('position', new THREE.Float32BufferAttribute(arr, 3))
const material = new THREE.LineBasicMaterial({
color: 'deepskyblue'
})
const line = new THREE.LineLoop(geometry, material)
scene.add(line)

调整cx
和cy
圆心值,我们可以任意移动该圆弧
几何体方法
还记的在BufferGeometry
那一章节,通过设置顶点坐标,我们绘制了一个矩形平面吗,这里我们使用setFromPoints
快速设置顶点,然后使用Line
方法来进行连接,看看效果如何
js
const geometry = new THREE.BufferGeometry()
const pointsArr = [
// 三维向量Vector3表示的坐标值
new THREE.Vector3(0,0,0),
new THREE.Vector3(0,3,0),
new THREE.Vector3(0,3,3),
new THREE.Vector3(0,0,3),
];
geometry.setFromPoints(pointsArr); // 设置顶点
const material = new THREE.LineBasicMaterial({color: 'deepskyblue'})
const line = new THREE.Line(geometry,material)
scene.add(line)

曲线简介
曲线是生成3D路径的核心工具,可以理解为"用数学公式自动画线"。
常见曲线类型
基础圆弧曲线 ArcCurve
用来画标准圆弧,如车轮、钟表刻度等,其核心参数为:圆心
、半径
、起始/结束角度
椭圆曲线 EllipseCurve
用来绘制椭圆或椭圆弧,如行星轨道, 其核心参数为:X轴半径
、Y轴半径
贝塞尔曲线 CubicBezierCurve3
用于创建平滑的复杂曲线,如心形、波浪等,其核心参数为:起点
、两个锚点
、终点
样条曲线 CatmullRomCurve3
用于通过多个点生成平滑路径,如管道、流动轨迹,相机漫游等
实践上手下
通过EllipseCurve
创建一个椭圆曲线,并获取曲线上的顶点,这里获取了曲线上100个顶点坐标
js
const arc = new THREE.EllipseCurve(0,0,10,5)
// const pointsArr = arc.getSpacedPoints(100) // 等间距
const pointsArr = arc.getPoints(100) // 非等间距
设置几何体的顶点,并使用点模型呈现,效果如下
js
const geometry = new THREE.BufferGeometry().setFromPoints(pointsArr)
const material = new THREE.PointsMaterial({color: 'skyblue',size: 0.2})
const line = new THREE.Points(geometry,material)
scene.add(line)

圆、椭圆
圆
通过使用ArcCurve
生成圆弧,当x/y轴半径相同时就是圆。
椭圆
通过使用EllipseCurve
生成椭圆,当x/y轴半径不同时就是椭圆
创建一个圆弧
JS
const arcCurve = new THREE.ArcCurve(0,0,5,0,Math.PI/4 )
const points = arcCurve.getPoints(100)
const geometry = new THREE.BufferGeometry().setFromPoints(points)
const material = new THREE.LineBasicMaterial({color: 'deeppink'})
const ellipse = new THREE.Line(geometry,material)
scene.add(ellipse)

样条曲线
样条曲线(Spline Curve) 是一种通过多个控制点自动生成平滑路径的工具,可以理解为"用一系列坐标点自动画出一条自然流畅的曲线"。
创建三维样条曲线
样条曲线至少需要2个控制点,但通常建议4个或4个以上点效果会比较好
js
const arr = [
new THREE.Vector3(-5, 2, 9),
new THREE.Vector3(-1, 4, 4),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(6, -6, 0),
new THREE.Vector3(7, 0, 8)
]
// 三维样条曲线
const curve = new THREE.CatmullRomCurve3(arr)
// 创建样条曲线
const geometry = new THREE.BufferGeometry().setFromPoints(curve.getPoints(50))
const material = new THREE.PointsMaterial({ color: 'skyblue' ,size: 0.1})
const curveObject = new THREE.Points(geometry, material)
// 将模型添加至场景中
scene.add(curveObject)

创建二维样条曲线
所谓的二维,即曲线始终是在一个平面上绘制
js
const curve= new THREE.SplineCurve(arr);
// 创建一个BufferGeometry对象,并设置其顶点为curve.getPoints(100)返回的数组
const geometry = new THREE.BufferGeometry().setFromPoints(curve.getPoints(100))
const material = new THREE.LineBasicMaterial({
color: 'deepskyblue'
})
const curveObject = new THREE.Line(geometry, material)
scene.add(curveObject)

物体沿曲线运动
通过不断修改小球的位置来实现小球沿着曲线运动
js
function animation() {
t += 0.001; // 时间递增
if (t >= 1) { // 当时间超过1时,重置为0
t = 0;
}
const index = Math.floor(t % 1 * 100); // 计算当前点的索引
mesh.position.copy(points[index]); // 将mesh的位置设置为当前点的位置
// 渲染场景和相机
renderer.render( scene, camera );
requestAnimationFrame( animation );
}

贝塞尔曲线
贝塞尔曲线是一种通过控制点生成平滑曲线的数学工具,可以理解为「用几个关键点自动画出复杂曲线」。
贝塞尔曲线的类型
-
二次贝塞尔曲线 QuadraticBezierCurve
- 控制点数量: 1个控制点
- 适用场景:简单曲线,如抛物线、水滴形状等
-
三次贝塞尔曲线 CubicBezierCurve
- 控制点数量: 2个控制点
- 适用场景:复杂曲线、如心形、波浪线等
二维二次贝塞尔
js
const p1 = new THREE.Vector2(-8, 0);
const p2 = new THREE.Vector2(2, 10);
const p3 = new THREE.Vector2(8, 0);
const curve = new THREE.QuadraticBezierCurve(p1,p2,p3)
const pointsArr = curve.getPoints(100)
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr)
const material = new THREE.LineBasicMaterial({color: 'skyblue'})
const material2 = new THREE.PointsMaterial({color: 'green', size: 0.1})
const curveObject = new THREE.Line(geometry, material)
const pointObject = new THREE.Points(geometry, material2)
scene.add(curveObject, pointObject)

三维三次贝塞尔
js
const p1 = new THREE.Vector3(-8, 0, 0);
const p2 = new THREE.Vector3(-4, 5, 0);
const p3 = new THREE.Vector3(15, 3, 0);
const p4 = new THREE.Vector3(8, 0, -3);
// 创建一个三次贝塞尔曲线,参数为四个点p1,p2,p3,p4
const curve = new THREE.CubicBezierCurve3(p1,p2,p3,p4)
const pointsArr = curve.getPoints(100)
// 创建一个BufferGeometry对象
const geometry = new THREE.BufferGeometry();
// 将pointsArr数组中的点设置为几何体的顶点
geometry.setFromPoints(pointsArr)
const material = new THREE.LineBasicMaterial({color: 'skyblue'})
const curveObject = new THREE.Line(geometry, material)
scene.add(curveObject)

以上案例均可在案例中心查看体验
