Versions
@thatopen/components 3.4.8 (verified against the published dist/index.mjs; source: packages/core/src/core/OrthoPerspectiveCamera/src/projections.ts).
What happens
getPerspectiveDims() computes:
const height = depth * 2 * Math.atan((camera.fov * (Math.PI / 180)) / 2);
and getDistance() uses the same inverted form backwards. The half-height of a perspective frustum at distance d is d * tan(fov/2), not d * atan(fov/2).
Numbers
- fov 60:
2·atan(0.5236) = 0.9647 vs 2·tan(0.5236) = 1.1547 → factor 0.8354, i.e. the ortho view shows 16.5 % less height than the perspective view it replaces.
- fov 50: factor 0.8826 (−11.7 %).
- The error vanishes as fov → 0 (
atan(x) ≈ tan(x) ≈ x) — strong evidence of a typo rather than intent, since the switch is only size-consistent for narrow FOVs.
Visible symptom
Every perspective→ortho toggle zooms IN slightly; because getDistance() inverts with the same wrong function, round-tripping with matchOrthoDistanceEnabled compounds the error.
Suggested fix
Replace Math.atan with Math.tan in both methods.
Versions
@thatopen/components3.4.8 (verified against the publisheddist/index.mjs; source:packages/core/src/core/OrthoPerspectiveCamera/src/projections.ts).What happens
getPerspectiveDims()computes:and
getDistance()uses the same inverted form backwards. The half-height of a perspective frustum at distancedisd * tan(fov/2), notd * atan(fov/2).Numbers
2·atan(0.5236) = 0.9647vs2·tan(0.5236) = 1.1547→ factor 0.8354, i.e. the ortho view shows 16.5 % less height than the perspective view it replaces.atan(x) ≈ tan(x) ≈ x) — strong evidence of a typo rather than intent, since the switch is only size-consistent for narrow FOVs.Visible symptom
Every perspective→ortho toggle zooms IN slightly; because
getDistance()inverts with the same wrong function, round-tripping withmatchOrthoDistanceEnabledcompounds the error.Suggested fix
Replace
Math.atanwithMath.tanin both methods.