This commit is contained in:
walker 2023-08-01 18:33:33 +08:00
commit 50f465b24f

View File

@ -2,6 +2,7 @@ import {
Container, Container,
DisplayObject, DisplayObject,
IPointData, IPointData,
Matrix,
Point, Point,
Rectangle, Rectangle,
} from 'pixi.js'; } from 'pixi.js';
@ -693,3 +694,44 @@ export function splitLineEvenly(
]; ];
}); });
} }
export function getParallelOfPolyline(
points: IPointData[],
offset: number,
side: 'L' | 'R'
): IPointData[] {
const { PI, cos, acos } = Math;
const angleBase = side === 'L' ? -PI / 2 : PI / 2;
return points.map((p, i) => {
let baseUnitVec: Vector2; //上一段的基准单位向量
let angle: number; //偏转角度
let len: number; //结合偏转角度的实际偏移量
if (!points[i - 1] || !points[i + 1]) {
angle = angleBase;
len = offset;
baseUnitVec = points[i - 1]
? new Vector2([
p.x - points[i - 1].x,
p.y - points[i - 1].y,
]).normalize()
: new Vector2([
points[i + 1].x - p.x,
points[i + 1].y - p.y,
]).normalize();
} else {
const vp = new Vector2([p.x - points[i - 1].x, p.y - points[i - 1].y]);
const vn = new Vector2([points[i + 1].x - p.x, points[i + 1].y - p.y]);
const cosTheta = Vector2.dot(vn, vp) / (vp.length() * vn.length());
const direction = vp.x * vn.y - vp.y * vn.x > 0; //det(vp|vn)>0?
const theta = direction ? acos(cosTheta) : -acos(cosTheta);
angle = angleBase + theta / 2;
len = offset / cos(theta / 2);
baseUnitVec = Vector2.from(vp).normalize();
}
return new Matrix()
.scale(len, len)
.rotate(angle)
.translate(p.x, p.y)
.apply(baseUnitVec);
});
}