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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 1x 17x 17x 17x 17x 17x 17x 17x 17x 68x 68x 68x 68x 68x 68x 68x 68x 17x 9x 9x 9x 9x 9x 9x 9x 8x 17x 9x 8x | import type { Types } from '@cornerstonejs/core';
import { CONSTANTS } from '@cornerstonejs/core';
const { EPSILON } = CONSTANTS;
/** Bounding box type */
type BoundingBox =
| [Types.Point2, Types.Point2, null]
| [Types.Point2, Types.Point2, Types.Point2];
function calculateBoundingBox(
points,
dimensions,
isWorld = false
): BoundingBox {
let xMin = Infinity;
let xMax = isWorld ? -Infinity : 0;
let yMin = Infinity;
let yMax = isWorld ? -Infinity : 0;
let zMin = Infinity;
let zMax = isWorld ? -Infinity : 0;
const is3D = points[0]?.length === 3;
// use for loop for performance
for (let i = 0; i < points.length; i++) {
const p = points[i];
xMin = Math.min(p[0], xMin);
xMax = Math.max(p[0], xMax);
yMin = Math.min(p[1], yMin);
yMax = Math.max(p[1], yMax);
Eif (is3D) {
zMin = Math.min(p[2] ?? zMin, zMin);
zMax = Math.max(p[2] ?? zMax, zMax);
}
}
if (dimensions) {
xMin = Math.max(isWorld ? dimensions[0] + EPSILON : 0, xMin);
xMax = Math.min(
isWorld ? dimensions[0] - EPSILON : dimensions[0] - 1,
xMax
);
yMin = Math.max(isWorld ? dimensions[1] + EPSILON : 0, yMin);
yMax = Math.min(
isWorld ? dimensions[1] - EPSILON : dimensions[1] - 1,
yMax
);
Eif (is3D && dimensions.length === 3) {
zMin = Math.max(isWorld ? dimensions[2] + EPSILON : 0, zMin);
zMax = Math.min(
isWorld ? dimensions[2] - EPSILON : dimensions[2] - 1,
zMax
);
}
} else Iif (!isWorld) {
// still need to bound to 0 and Infinity if no dimensions are provided for ijk
xMin = Math.max(0, xMin);
xMax = Math.min(Infinity, xMax);
yMin = Math.max(0, yMin);
yMax = Math.min(Infinity, yMax);
if (is3D) {
zMin = Math.max(0, zMin);
zMax = Math.min(Infinity, zMax);
}
}
return is3D
? [
[xMin, xMax],
[yMin, yMax],
[zMin, zMax],
]
: [[xMin, xMax], [yMin, yMax], null];
}
/**
* With a given vertices (points) coordinates in 2D or 3D in IJK, it calculates the minimum and maximum
* coordinate in each axis, and returns them. If clipBounds are provided it also
* clip the min, max to the provided width, height and depth
*
* @param points - shape corner points coordinates either in IJK (image coordinate)
* @param dimensions - bounds to clip the min, max
* @returns [[xMin,xMax],[yMin,yMax], [zMin,zMax]]
*/
export function getBoundingBoxAroundShapeIJK(
points: Types.Point2[] | Types.Point3[],
dimensions?: Types.Point2 | Types.Point3
): BoundingBox {
return calculateBoundingBox(points, dimensions, false);
}
/**
* With a given vertices (points) coordinates in 2D or 3D in World Coordinates, it calculates the minimum and maximum
* coordinate in each axis, and returns them. If clipBounds are provided it also
* clip the min, max to the provided width, height and depth
*
* @param points - shape corner points coordinates either in IJK (image coordinate)
* @param clipBounds - bounds to clip the min, max
* @returns [[xMin,xMax],[yMin,yMax], [zMin,zMax]]
*/
export function getBoundingBoxAroundShapeWorld(
points: Types.Point2[] | Types.Point3[],
clipBounds?: Types.Point2 | Types.Point3
): BoundingBox {
return calculateBoundingBox(points, clipBounds, true);
}
|