utils增加计算折线的平行线

This commit is contained in:
Yuan 2023-08-01 16:34:20 +08:00
parent 3cb91d10ad
commit 809876ea5d

View File

@ -695,33 +695,43 @@ export function splitLineEvenly(
}); });
} }
/** 计算直线的平行线 */ export function getParallelOfPolyline(
export function getParallelOfLine(
points: IPointData[], points: IPointData[],
direction: 'L' | 'R', offset: number,
offset: number side: 'L' | 'R'
) { ): IPointData[] {
if (points.length !== 2) throw Error('直线点的个数需为2'); const { PI, cos, acos } = Math;
const normalVecs = points.map((p, i) => { const angleBase = side === 'L' ? -PI / 2 : PI / 2;
let point; return points.map((p, i) => {
if (points[i + 1]) { let baseUnitVec: Vector2; //上一段的基准单位向量
point = new Vector2([ let angle: number; //偏转角度
points[i + 1].x - p.x, let len: number; //结合偏转角度的实际偏移量
points[i + 1].y - p.y, if (!points[i - 1] || !points[i + 1]) {
]).normalize(); 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 { } else {
point = new Vector2([ const vp = new Vector2([p.x - points[i - 1].x, p.y - points[i - 1].y]);
p.x - points[i - 1].x, const vn = new Vector2([points[i + 1].x - p.x, points[i + 1].y - p.y]);
p.y - points[i - 1].y, const cosTheta = Vector2.dot(vn, vp) / (vp.length() * vn.length());
]).normalize(); 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();
} }
const rotate = new Matrix().rotate( return new Matrix()
(direction === 'L' ? Math.PI : -Math.PI) / 2 .scale(len, len)
); .rotate(angle)
return rotate.apply(point); .translate(p.x, p.y)
.apply(baseUnitVec);
}); });
return points.map((p, i) => ({
x: p.x + offset * normalVecs[i]?.x,
y: p.y + offset * normalVecs[i]?.y,
}));
} }