Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 18x 26x 1188x 51x 51x 5736x 385x 51x 3x 3x 2x 293x 293x 293x 272x 293x 2x 2x 1x 1x 1x 1x 1x 1x 3x 8800x 8800x 1x 8799x 8799x 12132x 7901x 7901x 8799x 12132x 12132x 1x 9x 3x 9x 1x 3x 1x 1x 1x 1x 62x 62x 62x 62x | export class VectorHelperService { private readonly tolerance = 0.00001; degToRad(degrees: number) { return degrees * (Math.PI / 180); } remap(value: number, from1: number, to1: number, from2: number, to2: number): number { 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: number[][], tolerance = 1e-7): number[][] { const cleanVectors: number[][] = []; 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: number[][], checkFirstAndLast = true): number[][] { const vectorsRemaining: number[][] = []; 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]; Eif (this.vectorsTheSame(firstVector, lastVector, this.tolerance)) { vectorsRemaining.pop(); } } } else Eif (vectors.length === 1) { vectorsRemaining.push(...vectors); } return vectorsRemaining; } vectorsTheSame(vec1: number[], vec2: number[], tolerance: number) { 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: number, num2: number, tolerance: number): boolean { const res = Math.abs(num1 - num2) < tolerance; return res; } averageVector(vectors: number[][]): number[] { 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: number[]): number { return Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0)); } normalize(vector: number[]): number[] { const magnitude = this.magnitude(vector); return vector.map(v => v / magnitude); } translatePoint(point: [number, number, number], vector: [number, number, number], distance: number): [number, number, number] { 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: [number, number, number], vector2: [number, number, number]): number { 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: [number, number, number], point2: [number, number, number]): number { 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); } } |