UNPKG

jakke-graphics-ts

Version:

My common graphics utils for building my aec apps.

85 lines 3.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pointEvaluationOnLine = pointEvaluationOnLine; exports.getPointOnTrianglePlane = getPointOnTrianglePlane; const vertex3d_1 = require("../models/basic/vertex3d"); /** * Evaluate the parameter of given line and point. * @param p0 Start point of Line * @param p1 End point of Line * @param ptTest Point to test * @returns {number|undefined} * When the given point is on the line between endpoints, the result will be 0 ~ 1. * When it is on the line but outside the endpoints, the result will be negative float or larger than 1. * When it is determined that the point actually not placed on the line, it will return undefined. */ const DIRECTION_TOLERANCE = 1e-6; function pointEvaluationOnLine(p0, p1, ptTest) { const direction = { x: p1.x - p0.x, y: p1.y - p0.y, z: p1.z - p0.z }; const directionNorm = getNormalizedVector(direction); const p0p2 = { x: ptTest.x - p0.x, y: ptTest.y - p0.y, z: ptTest.z - p0.z }; const testNorm = getNormalizedVector(p0p2); const dotResult = dot(directionNorm, testNorm); const directionFactor = dotResult >= 0 ? 1 : -1; const isAlmostParallel = Math.abs((Math.abs(dotResult) - 1)) < DIRECTION_TOLERANCE; const lineLength = getDist(p0, p1); const dist = getDist(p0, ptTest); if (!isAlmostParallel) { return; } return directionFactor * (dist / lineLength); } function getNormalizedVector(v) { const size = Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2) + Math.pow(v.z, 2)); return { x: v.x / size, y: v.y / size, z: v.z / size }; } function dot(v0, v1) { return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z; } function getDist(p0, p1) { const dxOnLine = Math.abs(p1.x - p0.x); const dyOnLine = Math.abs(p1.y - p0.y); const dzOnLine = Math.abs(p1.z - p0.z); return Math.sqrt(Math.pow(dxOnLine, 2) + Math.pow(dyOnLine, 2) + Math.pow(dzOnLine, 2)); } /** * Get intersection of line and triangle. * @param line Line's endpoints. * @param triangle Triangle * @returns When intersection point exists, returns it. If not, returned undefined. */ function getPointOnTrianglePlane(line, triangle) { if (isDetZero(line, triangle)) return; const v0 = new vertex3d_1.Vertex3dWrapped(triangle.p0); const v1 = new vertex3d_1.Vertex3dWrapped(triangle.p1); const v2 = new vertex3d_1.Vertex3dWrapped(triangle.p2); const p0 = new vertex3d_1.Vertex3dWrapped(line.p0); const p1 = new vertex3d_1.Vertex3dWrapped(line.p1); const v0v1 = v1.subtract(v0); const v0v2 = v2.subtract(v0); const v1p1 = p0.subtract(v0); const d = p1.subtract(p0).normalized(); const det = v0v1.dot(d.cross(v0v2)); const v = d.dot(v0v2.cross(v1p1)) / det; const w = d.dot(v1p1.cross(v0v1)) / det; const u = 1 - (v + w); const result = v0.multiply(u).add(v1.multiply(v)).add(v2.multiply(w)); const validParams = [u, v, w].every(val => val >= 0 && val <= 1); return validParams ? result : undefined; } function isDetZero(line, triangle) { const v0 = new vertex3d_1.Vertex3dWrapped(triangle.p0); const v1 = new vertex3d_1.Vertex3dWrapped(triangle.p1); const v2 = new vertex3d_1.Vertex3dWrapped(triangle.p2); const v0v1 = v1.subtract(v0); const v0v2 = v2.subtract(v0); const d = new vertex3d_1.Vertex3dWrapped(line.p1).subtract(new vertex3d_1.Vertex3dWrapped(line.p0)).normalized(); const det = v0v1.dot(d.cross(v0v2)); return det === 0; } //# sourceMappingURL=pointEvaluationUtils.js.map