awv3
Version:
⚡ AWV3 embedded CAD
154 lines (124 loc) • 5.33 kB
JavaScript
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;
}