UNPKG

awv3

Version:
154 lines (124 loc) 5.33 kB
import * as THREE from 'three'; // set global tolerance var distanceToleranceDigits = 3; var distanceTolerance = Math.pow(10, -distanceToleranceDigits); export function round(value, digit) { var offset = Math.pow(10, -(digit + 2)); var roundFactor = Math.pow(10, digit); return Math.round((value + offset) * roundFactor) / roundFactor; } export function roundVector(vector) { var roundedVector = new THREE.Vector3(); Object.getOwnPropertyNames(vector).forEach(function (prop) { roundedVector[prop] = round(vector[prop], distanceToleranceDigits); }); return roundedVector; } export function areParallel(v1, v2) { var crossProduct = v1.clone().cross(v2); return crossProduct.length() < distanceTolerance; } export function areSkew(p1, v1, p2, v2) { var normal = v1.clone().cross(v2).clone().normalize(); var vectorBetweenStartPoints = p1.clone().sub(p2); var distanceBetweenLines = Math.abs(normal.clone().dot(vectorBetweenStartPoints)); return distanceBetweenLines > distanceTolerance; } export function calculateIntersection(p11, p12, p21, p22) { var v1 = p12.clone().sub(p11); var v2 = p22.clone().sub(p21); // parallel check if (areParallel(v1, v2)) return undefined; // skew check if (areSkew(p11, v1, p21, v2)) return undefined; // create plane lie on 1st line normal to 2nd line var vectorInPlane = v1.clone().cross(p11.clone().add(v1).sub(p21)); var planeNormal = v1.clone().cross(vectorInPlane); var plane = new THREE.Plane().setFromNormalAndCoplanarPoint(planeNormal, p11); // intersect plane with 2nd line (using ray in both directions) var intersectionPoint = new THREE.Vector3(); var ray = new THREE.Ray(p21, v2); if (!ray.intersectPlane(plane, intersectionPoint)) { ray = new THREE.Ray(p21, v2.clone().negate()); if (!ray.intersectPlane(plane, intersectionPoint)) { return undefined; } } return intersectionPoint; } export function areCoplanar(pointsArray) { var a = unique(pointsArray); if (a.length <= 3) return true; var plane = new THREE.Plane().setFromCoplanarPoints(a[0], a[1], a[2]); for (var i = 3; i < a.length; i++) { if (Math.abs(plane.distanceToPoint(a[i])) > distanceTolerance) return false; } return true; } export function unique(pointsArray) { var uniqueArray = []; for (var _iterator = pointsArray, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var _point = _ref; var isUnique = true; for (var _i2 = 0; _i2 < uniqueArray.length; _i2++) { var p = uniqueArray[_i2]; if (_point.equals(p)) isUnique = false; } if (isUnique) uniqueArray.push(_point); } return uniqueArray; } export function calculateInCenter(pa1, pa2, pb1, pb2, pc1, pc2) { // caluclate direction vector for all three lines var v1 = pa2.clone().sub(pa1); var v2 = pb2.clone().sub(pb1); var v3 = pc2.clone().sub(pc1); // line a&b and b&c should create an intersection, if a&b or b&c are parallel, switch them var p11 = pa1, p12 = pa2, p21 = pb1, p22 = pb2, p31 = pc1, p32 = pc2; if (areParallel(v1, v2)) { // switch line b and c p21 = pc1; p22 = pc2; p31 = pb1; p32 = pb2; } else if (areParallel(v2, v3)) { // switch line a and b p11 = pb1; p12 = pb2; p21 = pa1; p22 = pa2; } // coplanar check if (!areCoplanar([p11, p12, p21, p22, p31, p32])) { return undefined; } // calculate intersection of two lines each var intersection1 = calculateIntersection(p11, p12, p21, p22); var intersection2 = calculateIntersection(p21, p22, p31, p32); // intersection of a&b and b&c check if (intersection1 === undefined || intersection2 === undefined) return undefined; // point on line AND not equals to intersection var pe1 = p11.equals(intersection1) ? p12 : p11; var pe2 = p21.equals(intersection1) ? p22 : p21; var pe3 = p21.equals(intersection2) ? p22 : p21; var pe4 = p31.equals(intersection2) ? p32 : p31; // angle bisector (Winkelhalbierende) = ||u||v + ||v||u var i1a = pe1.clone().sub(intersection1); // u of first intersection var i1b = pe2.clone().sub(intersection1); // v of first intersection var i2b = pe3.clone().sub(intersection2); // u of second intersection var i2c = pe4.clone().sub(intersection2); // v of second intersection // angle bisector vectors var w1 = i1b.clone().multiplyScalar(i1a.length()).add(i1a.clone().multiplyScalar(i1b.length())); var w2 = i2c.clone().multiplyScalar(i2b.length()).add(i2b.clone().multiplyScalar(i2c.length())); // intersection of both angel bisector vectors var inCenter = calculateIntersection(intersection1, intersection1.clone().add(w1), intersection2, intersection2.clone().add(w2)); return inCenter; } export function calculateRotationMatrix(whichAxis, direction) { var axis = whichAxis === 'x' ? new THREE.Vector3(1, 0, 0) : new THREE.Vector3(0, 1, 0); var rotAxis = axis.clone().cross(direction).normalize(); var rotationMatrix = new THREE.Matrix4().makeRotationAxis(rotAxis, axis.angleTo(direction)); return rotationMatrix; }