(cls: ProjectionClass, overrides: Partial<CameraIntrinsics>)
| 268 | const TOL = 1e-4; |
| 269 | |
| 270 | function assertParity(cls: ProjectionClass, overrides: Partial<CameraIntrinsics>): void { |
| 271 | const i: CameraIntrinsics = { ...BASE_I, ...overrides }; |
| 272 | for (const p of GRID) { |
| 273 | const canonical = DISTORTION_STRATEGIES[cls].forward(p, i); |
| 274 | const glslRef = glslForwardReference(cls, p, i); |
| 275 | const errX = Math.abs(glslRef.x - canonical.x); |
| 276 | const errY = Math.abs(glslRef.y - canonical.y); |
| 277 | expect( |
| 278 | errX, |
| 279 | `cls='${cls}' p={${p.x},${p.y}}: ` + |
| 280 | `glslRef.x=${glslRef.x.toFixed(8)} canonical.x=${canonical.x.toFixed(8)} errX=${errX.toExponential(2)}`, |
| 281 | ).toBeLessThan(TOL); |
| 282 | expect( |
| 283 | errY, |
| 284 | `cls='${cls}' p={${p.x},${p.y}}: ` + |
| 285 | `glslRef.y=${glslRef.y.toFixed(8)} canonical.y=${canonical.y.toFixed(8)} errY=${errY.toExponential(2)}`, |
| 286 | ).toBeLessThan(TOL); |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | it("'perspective-radial' (FULL_OPENCV: rational radial + tangential) matches canonical", () => { |
| 291 | assertParity('perspective-radial', { |
no test coverage detected