**
在 3D 图形的世界里,三角形就像是乐高积木里最基础的那块小方块 ------ 简单、可靠,几乎所有复杂模型都能由它堆砌而成。但有时候,我们需要更 "大气" 的形状来完成设计,比如四边形。今天我们就来看看,在 Three.js 的魔法世界里,三角形是如何摇身一变成为四边形的,这背后又藏着哪些几何的小秘密。
从三角形说起:3D 世界的 "原子"
想象一下,你手里有一张三角形的纸,三个顶点就像是三个固定的钉子,牢牢地把这张纸钉在空间中。在 Three.js 里,这三个顶点就是我们定义三角形的关键。让我们用代码来创建一个最简单的三角形:
javascript
// 定义三角形的三个顶点坐标
const triangleVertices = new Float32Array([
0, 1, 0, // 顶部顶点,像山峰的顶端
-1, -1, 0, // 左下顶点,脚踏实地
1, -1, 0 // 右下顶点,与左顶点遥遥相对
]);
// 创建几何体并设置顶点
const triangleGeometry = new THREE.BufferGeometry();
triangleGeometry.setAttribute('position', new THREE.BufferAttribute(triangleVertices, 3));
这段代码就像是在 3D 空间里钉下了三个点,然后用线把它们连起来,形成了一个稳定的三角形。这里的每个顶点都有三个数字来描述它的位置 ------ 分别对应 X 轴、Y 轴和 Z 轴,就像是空间中的经纬度加上海拔高度。
为什么三角形这么重要?因为三个点确定一个平面,就像相机的三脚架永远不会晃动一样,三角形在 3D 世界里也是最稳定的结构。但当我们需要更宽敞的 "舞台" 时,四边形就该登场了。
四边形的诞生:多一个顶点的自由
四边形比三角形多了一个顶点,这可不是简单地多画一条线那么简单。如果说三角形是被三个钉子固定的纸,那四边形就像是被四个钉子固定的布 ------ 它有了更多的褶皱和伸展的可能,这也意味着我们需要更聪明的方法来控制它的形状。
要把三角形变成四边形,最直接的办法就是 "加一个点"。但这个点加在哪里,怎么加,可是门大学问。我们不能随便找个地方戳个钉子,那样可能会让整个形状变得扭曲怪异。
让我们先创建一个四边形的基础结构:
javascript
// 四边形的四个顶点坐标
const quadVertices = new Float32Array([
-1, 1, 0, // 左上顶点
1, 1, 0, // 右上顶点
1, -1, 0, // 右下顶点
-1, -1, 0 // 左下顶点
]);
// 创建四边形几何体
const quadGeometry = new THREE.BufferGeometry();
quadGeometry.setAttribute('position', new THREE.BufferAttribute(quadVertices, 3));
看,这就是一个标准的四边形,四个顶点像站岗的士兵一样,分别守在左上、右上、右下、左下四个位置,形成了一个规则的矩形。但如果我们想从之前的三角形变换过来,事情就没这么简单了。
顶点变换的核心:坐标的舞蹈
三角形有三个顶点,四边形有四个顶点,这意味着我们需要 "创造" 出一个新的顶点。这个新顶点从哪里来呢?其实它就藏在三角形的某个位置,等待我们把它 "拉" 出来。
想象一下,三角形的三个顶点就像三个好朋友,分别站在 (0,1,0)、(-1,-1,0) 和 (1,-1,0) 这三个位置。现在我们要邀请第四个朋友加入,让他们四个站成一个四边形。最自然的做法,就是在三角形的一条边上找一个点,把它 "拽" 出去,形成一个新的顶点。
让我们用代码来模拟这个过程。假设我们有一个三角形的顶点数组,现在要通过计算得到第四个顶点:
arduino
// 原始三角形顶点
const triangleVerts = [
new THREE.Vector3(0, 1, 0), // 顶部
new THREE.Vector3(-1, -1, 0), // 左下
new THREE.Vector3(1, -1, 0) // 右下
];
// 我们在左下和右下顶点之间"插入"一个新顶点
// 先算出左下到右下的中点
const midPoint = new THREE.Vector3();
midPoint.x = (triangleVerts[1].x + triangleVerts[2].x) / 2;
midPoint.y = (triangleVerts[1].y + triangleVerts[2].y) / 2;
midPoint.z = 0; // z轴保持不变
// 把这个中点向上"拉"一点,形成新的顶点
const newVertex = new THREE.Vector3(
midPoint.x,
midPoint.y + 0.5, // 向上移动0.5单位
midPoint.z
);
// 现在我们有了四个顶点,可以组成四边形了
const quadVerts = [
triangleVerts[0], // 顶部
triangleVerts[1], // 左下
newVertex, // 新顶点
triangleVerts[2] // 右下
];
这里的关键就像是在折纸 ------ 我们找到三角形底边的中点,然后把它向上折起,原本的一条边就变成了两条边,三角形也就变成了一个四边形。这个过程中,每个顶点的坐标都在按照我们的意愿进行调整,就像指挥家指挥着音符的跳动。
底层的几何魔法:向量与空间变换
你可能会好奇,为什么移动一个点就能改变整个形状?这就要从 3D 图形的底层原理说起了。在计算机的世界里,每个顶点都是一个 "向量"------ 既有大小又有方向的数学精灵。当我们改变顶点的坐标时,其实是在改变这些向量的方向或长度。
比如,在上面的例子中,新顶点的 x 坐标和中点一样,这意味着它在水平方向上处于左下和右下顶点的正中间;而 y 坐标比中点高,这就像是把这个点向上 "拉" 了一把,让原本平坦的底边凸起,形成了一个新的角。
Three.js 为我们提供了很多方便的方法来操作这些向量。比如,我们可以用add方法来计算两个点的和,用multiplyScalar来缩放一个点的位置:
ini
// 另一种创建新顶点的方法:向量运算
const vectorFromLeftToRight = new THREE.Vector3();
vectorFromLeftToRight.subVectors(triangleVerts[2], triangleVerts[1]); // 右下减左下,得到方向向量
// 取一半长度,就是中点到左下的向量
const halfVector = vectorFromLeftToRight.clone().multiplyScalar(0.5);
// 从左下顶点出发,加上这个一半向量,再向上移动
const newVertex2 = triangleVerts[1].clone().add(halfVector).add(new THREE.Vector3(0, 0.5, 0));
这段代码做的事情和之前差不多,但更能体现向量的思想 ------ 我们不是直接计算坐标,而是通过向量的加减来 "移动" 点的位置。这就像是告诉计算机:"从左下顶点出发,向右走一半的距离,再向上走 0.5 单位,那里就是新顶点的位置。"
从三角形到四边形:拓扑的奥秘
除了顶点的位置,形状的 "拓扑结构" 也很重要。拓扑就像是图形的 "连接方式"------ 哪些顶点连在一起,形成什么样的面。在 Three.js 中,我们需要明确告诉计算机这些连接关系。
对于三角形,我们只需要说 "三个顶点连在一起形成一个面";而对于四边形,我们需要定义两个三角形来组成它(因为 GPU 通常只认三角形):
arduino
// 定义四边形的面(由两个三角形组成)
const indices = [
0, 1, 2, // 第一个三角形:顶部、左下、新顶点
0, 2, 3 // 第二个三角形:顶部、新顶点、右下
];
// 创建索引缓冲区
quadGeometry.setIndex(new THREE.Uint16BufferAttribute(indices, 1));
这就像是告诉计算机:"你看,这个四边形其实是由两个小三角形拼起来的,你只要分别画出这两个三角形,看起来就像是一个四边形了。" 这种把复杂形状分解成三角形的过程,在 3D 图形学中叫做 "三角剖分",是计算机处理复杂图形的基本技巧。
让形状动起来:动画中的顶点变换
顶点变换不仅仅用于创建静态形状,更重要的是在动画中让物体 "活" 起来。比如,我们可以让一个三角形逐渐变成四边形,就像花朵慢慢绽放:
ini
// 动画函数:让三角形逐渐变成四边形
function animate() {
requestAnimationFrame(animate);
// 计算动画进度(0到1之间)
const progress = (Math.sin(Date.now() * 0.001) + 1) / 2;
// 根据进度更新新顶点的位置
const currentY = -1 + progress * 0.5; // 从-1逐渐升到-0.5
quadVerts[2].y = currentY;
// 更新几何体的顶点数据
quadGeometry.attributes.position.needsUpdate = true;
renderer.render(scene, camera);
}
这段代码就像是给形状装上了 "关节",通过不断改变新顶点的 y 坐标,让它从底边慢慢升起,三角形也就逐渐变成了四边形。这里的进度计算用了正弦函数,让变化看起来更平滑自然,就像呼吸一样有节奏。
总结:几何的魅力在于创造
从三角形到四边形的顶点变换,看似简单,却包含了 3D 图形学的许多基本原理:顶点坐标的表示、向量的运算、拓扑结构的定义,以及动画中的插值计算。就像用积木搭房子,我们通过移动一个个小小的顶点,就能创造出千变万化的形状。
下次当你在 Three.js 中创建模型时,不妨多留意这些隐藏在代码背后的几何奥秘。也许有一天,你会发现自己能用这些简单的原理,创造出令人惊叹的 3D 世界 ------ 毕竟,再复杂的模型,追根溯源,都只是一个个顶点在空间中的优雅舞蹈。
记住,在 3D 的世界里,没有绝对的固定形状,只有无限的可能。只要你愿意,三角形可以变成四边形,四边形可以变成更复杂的多边形,而这一切,都从理解每个顶点的小小移动开始。