diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..750e145 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +screenshots/ diff --git a/src/geometry.js b/src/geometry.js index c739d51..d1b4a18 100644 --- a/src/geometry.js +++ b/src/geometry.js @@ -65,11 +65,13 @@ export function mechanismBounds() { maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y); } - const pad = 30; + // Increase padding to account for full range of motion and potential parameter changes + const padX = 50; + const padY = 60; return { - minX: minX - pad, - minY: minY - pad, - maxX: maxX + pad, - maxY: maxY + pad, + minX: minX - padX, + minY: minY - padY, + maxX: maxX + padX, + maxY: maxY + padY, }; } diff --git a/src/renderer3d.js b/src/renderer3d.js index 91a0bc1..87b0592 100644 --- a/src/renderer3d.js +++ b/src/renderer3d.js @@ -201,7 +201,24 @@ export function create3DRenderer(mountEl) { const width = Math.max(1, mountEl.clientWidth || 1); const height = Math.max(1, mountEl.clientHeight || 1); renderer.setSize(width, height, false); - camera.aspect = width / height; + + const aspect = width / height; + camera.aspect = aspect; + + // Adjust FOV for portrait mode to keep the subject in view + // Base FOV is 42 degrees for landscape (aspect >= 1) + // For portrait, we increase FOV to maintain horizontal coverage + if (aspect < 1) { + const baseFovRad = (42 * Math.PI) / 180; + // Calculate horizontal FOV for aspect=1 + const hFov = 2 * Math.atan(Math.tan(baseFovRad / 2) * 1); + // Calculate new vertical FOV to match that horizontal coverage + const newVFovRad = 2 * Math.atan(Math.tan(hFov / 2) / aspect); + camera.fov = (newVFovRad * 180) / Math.PI; + } else { + camera.fov = 42; + } + camera.updateProjectionMatrix(); }