Search code examples
graphicsthree.jsgeometrycoordinate-transformation

How to stretch geometry so its bounding box fits precisely the screen in Three.js


I am looking for the way of stretching a geometry (with all vertices z = 0) into visible screen (HTML Canvas Element).

For now I have worked out how to fit the geometry to the screen, like this:

geometry fitting the canvas

with following code that basically adjusts camera.z to fit geometry to the height of canvas.

    geometry.computeBoundingBox();

    const bbox = geometry.boundingBox;
    const geometryCenter = bbox.getCenter(new THREE.Vector3());
    const geometrySize = bbox.getSize(new THREE.Vector3())

    const cameraZ = getZFromGeometrySize(camera.fov, geometrySize);

    const scale = getScaleFromZ(height, camera.fov, cameraZ);

    const zoomTransform = d3.zoomIdentity
      .translate(width * 0.5, height * 0.5)
      .scale(scale);

    zoom.transform(canvasSelection, zoomTransform);

    camera.position.set(geometryCenter.x, geometryCenter.y, cameraZ)

    camera.updateProjectionMatrix();

with below definitions of functions:

  function getZFromGeometrySize(fov, geometrySize) {
    const maxSize = Math.max( geometrySize.x, geometrySize.y );

    const halfFOVRadians = toRadians(fov * 0.5);

    return maxSize / ( 2 * Math.tan( halfFOVRadians ) );
  }


  function getScaleFromZ (height, fov, z) {

    const halfFOVRadians = toRadians(fov * 0.5);

    return height / (2 * Math.tan(halfFOVRadians) * z);
  }

This however is using camera position so geometry will fit the view. However, I am looking for the way to stretch the geometry so its bounding box precisely fits the screen, ideally with some predefined padding. Since this is not related to camera settings I need to manipulate geometry vertices values to stretch it horizontally. How to achieve this? I want to retain values of vertices as they relate to underlying data.

I assume this would need to be a function of canvas dimensions (width, height), geometry coordinates, and camera settings returning new geometry coordinates? Any hint is appreciated.


Solution

  • A short answer to this question is: to set camera's aspect ratio to 1.0.

    This will work if geometry bounds are in clip space already [-1, 1 ]. If not they have to be converted to clip space first.