jakke-graphics-ts
Version:
My common graphics utils for building my aec apps.
136 lines • 5.27 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PolylineUtils = void 0;
const lineEvaluationUtils_1 = require("./lineEvaluationUtils");
const vectorUtils_1 = require("./vectorUtils");
const POLYLINE_CLOSED_TOLERANCE = 1e-6;
const POLYLINE_ZERO_LENGTH = 1e-6;
function footingPointOnPolyline2d(polyline, pt, withinCurve = false) {
// Filter when polyline is actually a point or line.
if (polyline.length < 2)
return;
// Filter when polyline is actually no length.
const polylineLength = getLengthPolyline2d(polyline);
if (polylineLength < POLYLINE_ZERO_LENGTH)
return;
// Loop the polyline
const factors = [];
const ptFrom = vectorUtils_1.VectorUtils.to3d(pt);
let lengthSum = 0;
for (let i = 0; i < polyline.length - 1; i++) {
const p0 = vectorUtils_1.VectorUtils.to3d(polyline[i]);
const p1 = vectorUtils_1.VectorUtils.to3d(polyline[i + 1]);
if (i > 0) {
const pFormer = vectorUtils_1.VectorUtils.to3d(polyline[i - 1]);
lengthSum += vectorUtils_1.VectorUtils.getDist(pFormer, p0);
}
const lineSegment = { p0: p0, p1: p1 };
const param = lineEvaluationUtils_1.LineEvaluation.getFootPointOnLine(lineSegment, ptFrom);
if (!param)
continue;
const distOnSegment = vectorUtils_1.VectorUtils.getDist(lineSegment.p0, param.pt);
if (withinCurve) {
if (0 <= param.t && param.t <= 1) {
factors.push({
travelDistanceOnPolyline: lengthSum + distOnSegment,
distToFooting: vectorUtils_1.VectorUtils.getDist(ptFrom, param.pt),
pt: param.pt,
t: (lengthSum + distOnSegment) / polylineLength,
lineSegment
});
}
}
else {
factors.push({
travelDistanceOnPolyline: lengthSum + distOnSegment,
distToFooting: vectorUtils_1.VectorUtils.getDist(ptFrom, param.pt),
pt: param.pt,
t: (lengthSum + distOnSegment) / polylineLength,
lineSegment
});
}
}
factors.sort((a, b) => a.distToFooting - b.distToFooting
|| a.t - b.t);
const target = factors[0];
return {
pt: target.pt,
t: target.travelDistanceOnPolyline / polylineLength,
lineSegment: target.lineSegment,
availableFactors: factors
};
}
function footingPointOnPolyline3d(polyline, pt, includeEnds = false) {
// Filter when polyline is actually a point or line.
if (polyline.length < 2)
return;
// Filter when polyline is actually no length.
const poylineLength = getLengthPolyline3d(polyline);
if (poylineLength < POLYLINE_ZERO_LENGTH)
return;
// Loop the polyline
const factors = [];
let lengthSum = 0;
for (let i = 0; i < polyline.length - 1; i++) {
if (i > 0) {
lengthSum += vectorUtils_1.VectorUtils.getDist(polyline[i - 1], polyline[i]);
}
const lineSegment = { p0: polyline[i], p1: polyline[i + 1] };
const param = lineEvaluationUtils_1.LineEvaluation.getFootPointOnLine(lineSegment, pt);
if (!param)
continue;
const distOnSegment = vectorUtils_1.VectorUtils.getDist(lineSegment.p0, param.pt);
factors.push({
travelDistanceOnPolyline: lengthSum + distOnSegment,
distToFooting: vectorUtils_1.VectorUtils.getDist(pt, param.pt),
pt: param.pt,
t: param.t,
lineSegment
});
}
factors.sort((a, b) => a.distToFooting - b.distToFooting
|| a.travelDistanceOnPolyline - b.travelDistanceOnPolyline
|| a.t - b.t);
const target = factors[0];
return {
pt: target.pt,
t: target.travelDistanceOnPolyline / poylineLength,
lineSegment: target.lineSegment
};
}
function getLengthPolyline2d(polyline) {
let sum = 0;
for (let i = 0; i < polyline.length - 1; i++) {
const p0 = Object.assign(Object.assign({}, polyline[i]), { z: 0 });
const p1 = Object.assign(Object.assign({}, polyline[i + 1]), { z: 0 });
sum += vectorUtils_1.VectorUtils.getDist(p0, p1);
}
return sum;
}
function getLengthPolyline3d(polyline) {
let sum = 0;
for (let i = 0; i < polyline.length - 1; i++) {
sum += vectorUtils_1.VectorUtils.getDist(polyline[i], polyline[i + 1]);
}
return sum;
}
function getIntersectionWithLine(polyline, line) {
const pts = [];
for (let i = 0; i < polyline.length - 1; i++) {
const segment = { p0: polyline[i], p1: polyline[i + 1] };
const test = lineEvaluationUtils_1.LineEvaluation.getIntersection(segment, line);
if (test.result && test.pt) {
const t = lineEvaluationUtils_1.LineEvaluation.getParameterOnLine(line.p0, line.p1, test.pt);
pts.push({ pt: test.pt, t });
}
}
return pts.sort((a, b) => a.t - b.t);
}
exports.PolylineUtils = {
footingPointOnPolyline2d,
footingPointOnPolyline3d,
getLengthPolyline2d,
getLengthPolyline3d,
getIntersectionWithLine,
};
//# sourceMappingURL=polylineUtils.js.map