UNPKG

jakke-graphics-ts

Version:

My common graphics utils for building my aec apps.

136 lines 5.27 kB
"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