UNPKG

@bitbybit-dev/occt

Version:

Bit By Bit Developers CAD algorithms using OpenCascade Technology kernel. Run in Node and in Browser.

101 lines (100 loc) 3.78 kB
export class VectorHelperService { constructor() { this.tolerance = 0.00001; } degToRad(degrees) { return degrees * (Math.PI / 180); } remap(value, from1, to1, from2, to2) { return (value - from1) / (to1 - from1) * (to2 - from2) + from2; } // Algorithm works with arbitrary length numeric vectors. This algorithm is more costly for longer arrays of vectors removeAllDuplicateVectors(vectors, tolerance = 1e-7) { const cleanVectors = []; vectors.forEach(vector => { // when there are no vectors in cleanVectors array that match the current vector, push it in. if (!cleanVectors.some(s => this.vectorsTheSame(vector, s, tolerance))) { cleanVectors.push(vector); } }); return cleanVectors; } // Algorithm works with arbitrary length numeric vectors. removeConsecutiveDuplicates(vectors, checkFirstAndLast = true) { const vectorsRemaining = []; if (vectors.length > 1) { for (let i = 1; i < vectors.length; i++) { const currentVector = vectors[i]; const previousVector = vectors[i - 1]; if (!this.vectorsTheSame(currentVector, previousVector, this.tolerance)) { vectorsRemaining.push(previousVector); } if (i === vectors.length - 1) { vectorsRemaining.push(currentVector); } } if (checkFirstAndLast) { const firstVector = vectorsRemaining[0]; const lastVector = vectorsRemaining[vectorsRemaining.length - 1]; if (this.vectorsTheSame(firstVector, lastVector, this.tolerance)) { vectorsRemaining.pop(); } } } else if (vectors.length === 1) { vectorsRemaining.push(...vectors); } return vectorsRemaining; } vectorsTheSame(vec1, vec2, tolerance) { let result = false; if (vec1.length !== vec2.length) { return result; } else { result = true; for (let i = 0; i < vec1.length; i++) { if (!this.approxEq(vec1[i], vec2[i], tolerance)) { result = false; break; } } } return result; } approxEq(num1, num2, tolerance) { const res = Math.abs(num1 - num2) < tolerance; return res; } averageVector(vectors) { const average = vectors.reduce((acc, val) => { return acc.map((a, i) => a + val[i]); }, [0, 0, 0]); return average.map(a => a / vectors.length); } magnitude(vector) { return Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0)); } normalize(vector) { const magnitude = this.magnitude(vector); return vector.map(v => v / magnitude); } translatePoint(point, vector, distance) { const x = point[0] + vector[0] * distance; const y = point[1] + vector[1] * distance; const z = point[2] + vector[2] * distance; return [x, y, z]; } angleBetweenVectors(vector1, vector2) { const dotProduct = vector1[0] * vector2[0] + vector1[1] * vector2[1] + vector1[2] * vector2[2]; const magnitude1 = this.magnitude(vector1); const magnitude2 = this.magnitude(vector2); return Math.acos(dotProduct / (magnitude1 * magnitude2)); } distanceBetweenPoints(point1, point2) { const x = point2[0] - point1[0]; const y = point2[1] - point1[1]; const z = point2[2] - point1[2]; return Math.sqrt(x * x + y * y + z * z); } }