All files / packages/tools/src/utilities/math/polyline getAABB.ts

65.62% Statements 21/32
59.09% Branches 13/22
100% Functions 1/1
67.85% Lines 19/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75                                      2x 2x 2x   2x                                             2x 2x 2x 2x 2x 2x   2x   2x 10x     10x 10x 10x 10x   10x           2x        
import { Types } from '@cornerstonejs/core';
 
/**
 * Calculates the axis-aligned bounding box (AABB) of a polyline.
 *
 * @param polyline - The polyline represented as an array of points.
 * @param options - Additional options for calculating the AABB.
 * @param options.isWorld - Indicates whether the polyline represents points in 3D space (true) or 2D space (false).
 *
 * @returns The AABB of the polyline. If the polyline represents points in 3D space, returns an AABB3 object with properties minX, maxX, minY, maxY, minZ, and maxZ. If the polyline represents points in 2D space, returns an AABB2 object with properties minX, maxX, minY, and maxY.
 */
export default function getAABB(
  polyline: Types.Point2[] | Types.Point3[] | number[],
  options?: {
    numDimensions: number;
  }
): Types.AABB2 | Types.AABB3 {
  // need to check if the polyline is array of arrays or just
  // a flat array of numbers
  let polylineToUse = polyline;
  const numDimensions = options?.numDimensions || 2;
  const is3D = numDimensions === 3;
 
  Iif (!Array.isArray(polyline[0])) {
    const currentPolyline = polyline as number[];
    // check the isWorld flag is provided or not which means every
    // 3 elements in the array represent a point in 3D space
    // otherwise, every 2 elements in the array represent a point in 2D space
    const totalPoints = currentPolyline.length / numDimensions;
 
    polylineToUse = new Array(currentPolyline.length / numDimensions) as
      | Types.Point2[]
      | Types.Point3[];
 
    for (let i = 0, len = totalPoints; i < len; i++) {
      polylineToUse[i] = [
        currentPolyline[i * numDimensions],
        currentPolyline[i * numDimensions + 1],
      ];
 
      if (is3D) {
        polylineToUse[i].push(currentPolyline[i * numDimensions + 2]);
      }
    }
  }
 
  let minX = Infinity;
  let minY = Infinity;
  let maxX = -Infinity;
  let maxY = -Infinity;
  let minZ = Infinity;
  let maxZ = -Infinity;
 
  polylineToUse = polylineToUse as Types.Point2[] | Types.Point3[];
 
  for (let i = 0, len = polylineToUse.length; i < len; i++) {
    const [x, y, z] = polylineToUse[i];
 
    // No Math.min/max calls for better performance
    minX = minX < x ? minX : x;
    minY = minY < y ? minY : y;
    maxX = maxX > x ? maxX : x;
    maxY = maxY > y ? maxY : y;
 
    Iif (is3D) {
      minZ = minZ < z ? minZ : z;
      maxZ = maxZ > z ? maxZ : z;
    }
  }
 
  return is3D
    ? { minX, maxX, minY, maxY, minZ, maxZ } // AABB3
    : { minX, maxX, minY, maxY }; // AABB2
}