目标
对指定路径
[
{x,y,z},{x,y,z},{x,y,z},{x,y,z}.........
]
沿着边缘向内或向外扩张,达到放大或缩小一定范围的效果,这里我们获取每个点(这里是Vector3(x,y,z)),获取前后两个点和当前点的坐标,计算前后两点的向量,旋转90度向内或向外,然后获取单位向量
方法
import { Vector3 } from "three";
export default function explandPath(points, scale) {
// 初始化扩张路径点数组
var expandedPath = [];
// 计算扩张路径
for (var i = 0; i < points.length; i++) {
// 获取当前点、前一个点和后一个点
var currentPoint = points[i];
var previousPoint = points[(i - 1 + points.length) % points.length]; // 取余确保循环闭合
var nextPoint = points[(i + 1) % points.length];
// 计算相邻向量
var prevVector = currentPoint.clone().sub(previousPoint).normalize(); // 当前点到前一个点的向量,并归一化
var nextVector = nextPoint.clone().sub(currentPoint).normalize(); // 当前点到后一个点的向量,并归一化
// 计算切线
var tangent = prevVector.clone().add(nextVector).normalize(); // 相邻向量的平均值,并归一化
// 沿着切线的垂直方向向外扩张一个单位长度
var expansion = tangent.clone().applyAxisAngle(new Vector3(0, 0, 1), Math.PI / 2); // 以切线为轴旋转90度得到垂直方向向量
expansion.multiplyScalar(scale * -1)
var expandedPoint = currentPoint.clone().add(expansion); // 当前点向外扩张一个单位向量
// 添加扩张点到数组中
expandedPath.push(expandedPoint);
}
// 闭合曲线
let forward = new Vector3().copy(points[points.length - 1]).sub(points[points.length - 2])
forward.normalize()
forward.multiplyScalar(scale)
expandedPath.push(new Vector3().copy(points[points.length - 1]).add(forward))
expandedPath.push(new Vector3().copy(expandedPath[0]))
return expandedPath
}
使用
let path1 = explandPath(path, 30)