目标
对指定路径
[{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)