UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

279 lines (225 loc) 9.21 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import { s as subtract, d as dot, j as cross, k as add } from '../Core/Math/index.js'; import macro from '../../macros.js'; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } var PLANE_TOLERANCE = 1.0e-6; var COINCIDE = 'coincide'; var DISJOINT = 'disjoint'; // ---------------------------------------------------------------------------- // Global methods // ---------------------------------------------------------------------------- function evaluate(normal, origin, x) { return normal[0] * (x[0] - origin[0]) + normal[1] * (x[1] - origin[1]) + normal[2] * (x[2] - origin[2]); } function distanceToPlane(x, origin, normal) { var distance = normal[0] * (x[0] - origin[0]) + normal[1] * (x[1] - origin[1]) + normal[2] * (x[2] - origin[2]); return Math.abs(distance); } function projectPoint(x, origin, normal, xproj) { var xo = []; subtract(x, origin, xo); var t = dot(normal, xo); xproj[0] = x[0] - t * normal[0]; xproj[1] = x[1] - t * normal[1]; xproj[2] = x[2] - t * normal[2]; } function projectVector(v, normal, vproj) { var t = dot(v, normal); var n2 = dot(normal, normal); if (n2 === 0) { n2 = 1.0; } vproj[0] = v[0] - t * normal[0] / n2; vproj[1] = v[1] - t * normal[1] / n2; vproj[2] = v[2] - t * normal[2] / n2; return vproj; } function generalizedProjectPoint(x, origin, normal, xproj) { var xo = []; subtract(x, origin, xo); var t = dot(normal, xo); var n2 = dot(normal, normal); if (n2 !== 0) { xproj[0] = x[0] - t * normal[0] / n2; xproj[1] = x[1] - t * normal[1] / n2; xproj[2] = x[2] - t * normal[2] / n2; } else { xproj[0] = x[0]; xproj[1] = x[1]; xproj[2] = x[2]; } } function intersectWithLine(p1, p2, origin, normal) { var outObj = { intersection: false, betweenPoints: false, t: Number.MAX_VALUE, x: [] }; var p21 = []; var p1Origin = []; // Compute line vector subtract(p2, p1, p21); subtract(origin, p1, p1Origin); // Compute denominator. If ~0, line and plane are parallel. // const num = vtkMath.dot(normal, origin) - vtkMath.dot(normal, p1); var num = dot(normal, p1Origin); var den = dot(normal, p21); // If denominator with respect to numerator is "zero", then the line and // plane are considered parallel. var fabsden; var fabstolerance; // Trying to avoid an expensive call to fabs() if (den < 0.0) { fabsden = -den; } else { fabsden = den; } if (num < 0.0) { fabstolerance = -num * PLANE_TOLERANCE; } else { fabstolerance = num * PLANE_TOLERANCE; } if (fabsden <= fabstolerance) { return outObj; } // Where on the line between p1 and p2 is the intersection // If between 0 and 1, it is between the two points. If < 0 it's before p1, if > 1 it's after p2 outObj.t = num / den; outObj.x[0] = p1[0] + outObj.t * p21[0]; outObj.x[1] = p1[1] + outObj.t * p21[1]; outObj.x[2] = p1[2] + outObj.t * p21[2]; outObj.intersection = true; outObj.betweenPoints = outObj.t >= 0.0 && outObj.t <= 1.0; return outObj; } function intersectWithPlane(plane1Origin, plane1Normal, plane2Origin, plane2Normal) { var outObj = { intersection: false, l0: [], l1: [], error: null }; var cross$1 = []; cross(plane1Normal, plane2Normal, cross$1); var absCross = cross$1.map(function (n) { return Math.abs(n); }); // test if the two planes are parallel if (absCross[0] + absCross[1] + absCross[2] < PLANE_TOLERANCE) { // test if disjoint or coincide var v = []; subtract(plane1Origin, plane2Origin, v); if (dot(plane1Normal, v) === 0) { outObj.error = COINCIDE; } else { outObj.error = DISJOINT; } return outObj; } // Plane1 and Plane2 intersect in a line // first determine max abs coordinate of the cross product var maxc; if (absCross[0] > absCross[1] && absCross[0] > absCross[2]) { maxc = 'x'; } else if (absCross[1] > absCross[2]) { maxc = 'y'; } else { maxc = 'z'; } // To get a point on the intersect line, zero the max coord, and solve for the other two var iP = []; // intersectionPoint // the constants in the 2 plane equations var d1 = -dot(plane1Normal, plane1Origin); var d2 = -dot(plane2Normal, plane2Origin); // eslint-disable-next-line default-case switch (maxc) { case 'x': // intersect with x=0 iP[0] = 0; iP[1] = (d2 * plane1Normal[2] - d1 * plane2Normal[2]) / cross$1[0]; iP[2] = (d1 * plane2Normal[1] - d2 * plane1Normal[1]) / cross$1[0]; break; case 'y': // intersect with y=0 iP[0] = (d1 * plane2Normal[2] - d2 * plane1Normal[2]) / cross$1[1]; iP[1] = 0; iP[2] = (d2 * plane1Normal[0] - d1 * plane2Normal[0]) / cross$1[1]; break; case 'z': // intersect with z=0 iP[0] = (d2 * plane1Normal[1] - d1 * plane2Normal[1]) / cross$1[2]; iP[1] = (d1 * plane2Normal[0] - d2 * plane1Normal[0]) / cross$1[2]; iP[2] = 0; break; } outObj.l0 = iP; add(iP, cross$1, outObj.l1); outObj.intersection = true; return outObj; } // ---------------------------------------------------------------------------- // Static API // ---------------------------------------------------------------------------- var STATIC = { evaluate: evaluate, distanceToPlane: distanceToPlane, projectPoint: projectPoint, projectVector: projectVector, generalizedProjectPoint: generalizedProjectPoint, intersectWithLine: intersectWithLine, intersectWithPlane: intersectWithPlane, DISJOINT: DISJOINT, COINCIDE: COINCIDE }; // ---------------------------------------------------------------------------- // vtkPlane methods // ---------------------------------------------------------------------------- function vtkPlane(publicAPI, model) { // Set our className model.classHierarchy.push('vtkPlane'); publicAPI.distanceToPlane = function (x) { return distanceToPlane(x, model.origin, model.normal); }; publicAPI.projectPoint = function (x, xproj) { projectPoint(x, model.origin, model.normal, xproj); }; publicAPI.projectVector = function (v, vproj) { return projectVector(v, model.normal, vproj); }; publicAPI.push = function (distance) { if (distance === 0.0) { return; } for (var i = 0; i < 3; i++) { model.origin[i] += distance * model.normal[i]; } }; publicAPI.generalizedProjectPoint = function (x, xproj) { generalizedProjectPoint(x, model.origin, model.normal, xproj); }; publicAPI.evaluateFunction = function (x, y, z) { if (!Array.isArray(x)) { return model.normal[0] * (x - model.origin[0]) + model.normal[1] * (y - model.origin[1]) + model.normal[2] * (z - model.origin[2]); } return model.normal[0] * (x[0] - model.origin[0]) + model.normal[1] * (x[1] - model.origin[1]) + model.normal[2] * (x[2] - model.origin[2]); }; publicAPI.evaluateGradient = function (xyz) { var retVal = [model.normal[0], model.normal[1], model.normal[2]]; return retVal; }; publicAPI.intersectWithLine = function (p1, p2) { return intersectWithLine(p1, p2, model.origin, model.normal); }; publicAPI.intersectWithPlane = function (planeOrigin, planeNormal) { return intersectWithPlane(planeOrigin, planeNormal, model.origin, model.normal); }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { normal: [0.0, 0.0, 1.0], origin: [0.0, 0.0, 0.0] }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Object methods macro.obj(publicAPI, model); macro.setGetArray(publicAPI, model, ['normal', 'origin'], 3); vtkPlane(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = macro.newInstance(extend, 'vtkPlane'); // ---------------------------------------------------------------------------- var vtkPlane$1 = _objectSpread({ newInstance: newInstance, extend: extend }, STATIC); export { STATIC, vtkPlane$1 as default, extend, newInstance, vtkPlane };