MCPcopy Create free account
hub / github.com/CNCKitchen/stlTexturizer / trianglesIntersectSAT

Function trianglesIntersectSAT

js/meshValidation.js:199–317  ·  view source on GitHub ↗

* Separating Axis Theorem test for two triangles. * Tests 13 axes: 2 face normals + 9 edge cross products. * Also handles coplanar case via 2D edge-normal axes.

(pos, tA, tB)

Source from the content-addressed store, hash-verified

197}
198
199/**
200 * Separating Axis Theorem test for two triangles.
201 * Tests 13 axes: 2 face normals + 9 edge cross products.
202 * Also handles coplanar case via 2D edge-normal axes.
203 */
204function trianglesIntersectSAT(pos, tA, tB) {
205 const bA = tA * 9, bB = tB * 9;
206
207 // Triangle A vertices
208 const a0x = pos[bA], a0y = pos[bA+1], a0z = pos[bA+2];
209 const a1x = pos[bA+3], a1y = pos[bA+4], a1z = pos[bA+5];
210 const a2x = pos[bA+6], a2y = pos[bA+7], a2z = pos[bA+8];
211
212 // Triangle B vertices
213 const b0x = pos[bB], b0y = pos[bB+1], b0z = pos[bB+2];
214 const b1x = pos[bB+3], b1y = pos[bB+4], b1z = pos[bB+5];
215 const b2x = pos[bB+6], b2y = pos[bB+7], b2z = pos[bB+8];
216
217 // Edge vectors for A
218 const eA0x = a1x-a0x, eA0y = a1y-a0y, eA0z = a1z-a0z;
219 const eA1x = a2x-a1x, eA1y = a2y-a1y, eA1z = a2z-a1z;
220 const eA2x = a0x-a2x, eA2y = a0y-a2y, eA2z = a0z-a2z;
221
222 // Edge vectors for B
223 const eB0x = b1x-b0x, eB0y = b1y-b0y, eB0z = b1z-b0z;
224 const eB1x = b2x-b1x, eB1y = b2y-b1y, eB1z = b2z-b1z;
225 const eB2x = b0x-b2x, eB2y = b0y-b2y, eB2z = b0z-b2z;
226
227 // Face normals
228 const nAx = eA0y*eA2z - eA0z*eA2y; // eA0 x (-eA2) = eA0 x (a0-a2)
229 const nAy = eA0z*eA2x - eA0x*eA2z;
230 const nAz = eA0x*eA2y - eA0y*eA2x;
231
232 const nBx = eB0y*eB2z - eB0z*eB2y;
233 const nBy = eB0z*eB2x - eB0x*eB2z;
234 const nBz = eB0x*eB2y - eB0y*eB2x;
235
236 // Helper: project 6 vertices onto axis, return true if separated
237 function separated(ax, ay, az) {
238 const lenSq = ax*ax + ay*ay + az*az;
239 if (lenSq < 1e-20) return false; // degenerate axis, skip
240
241 const pA0 = a0x*ax + a0y*ay + a0z*az;
242 const pA1 = a1x*ax + a1y*ay + a1z*az;
243 const pA2 = a2x*ax + a2y*ay + a2z*az;
244 const pB0 = b0x*ax + b0y*ay + b0z*az;
245 const pB1 = b1x*ax + b1y*ay + b1z*az;
246 const pB2 = b2x*ax + b2y*ay + b2z*az;
247
248 const minA = Math.min(pA0, pA1, pA2), maxA = Math.max(pA0, pA1, pA2);
249 const minB = Math.min(pB0, pB1, pB2), maxB = Math.max(pB0, pB1, pB2);
250
251 // Use a relative epsilon for the overlap test
252 const eps = 1e-8 * Math.max(Math.abs(maxA), Math.abs(maxB), Math.abs(minA), Math.abs(minB), 1);
253 return maxA < minB - eps || maxB < minA - eps;
254 }
255
256 // Test face normal of A

Callers 1

Calls 1

separatedFunction · 0.85

Tested by

no test coverage detected