All files / tools/src/utilities getEllipseWorldCoordinates.ts

100% Statements 17/17
100% Branches 0/0
100% Functions 1/1
100% Lines 16/16

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                                                                9x         9x 9x   9x 9x     9x 9x 9x 9x   9x 27x 27x 27x 27x     9x           9x    
import type { Types } from '@cornerstonejs/core';
import { vec3 } from 'gl-matrix';
 
import getViewportICamera from './getViewportICamera';
 
/**
 * Computes the ellipse boundary points (top, bottom, left, right) based on two
 * given world-space points and the viewport's camera orientation.
 *
 * Depending on the `returnWorldCoordinates` flag, it returns either:
 * - The ellipse boundary points in world coordinates or
 * - The corresponding points in canvas coordinates (projected using the viewport).
 *
 * This function:
 * - Uses the camera's `viewUp` and `viewPlaneNormal` to derive the orientation.
 * - Computes the perpendicular `viewRight` vector via cross product.
 * - Calculates top, bottom, left, and right points relative to the ellipse center.
 *
 * @param points Array containing:
 *   - `[0]`: The center of the ellipse in world coordinates.
 *   - `[1]`: A point on the ellipse radius in world coordinates.
 * @param viewport  The viewport instance
 * @returns Returns an array of world-space coordinates representing:
 *   1. Bottom
 *   2. Top
 *   3. Left
 *   4. Right
 */
export default function getEllipseWorldCoordinates(
  points: [Types.Point3, Types.Point3],
  viewport: Types.IViewport
): Types.Point3[] {
  const { viewUp, viewPlaneNormal } = getViewportICamera(
    viewport
  ) as Types.ICamera;
 
  // Calculate view right vector
  const viewRight = vec3.create();
  vec3.cross(viewRight, viewUp, viewPlaneNormal);
 
  const [centerWorld, endWorld] = points;
  const centerToEndDistance = vec3.distance(centerWorld, endWorld);
 
  // Calculate the four boundary points in world coordinates
  const bottomWorld = vec3.create();
  const topWorld = vec3.create();
  const leftWorld = vec3.create();
  const rightWorld = vec3.create();
 
  for (let i = 0; i <= 2; i++) {
    bottomWorld[i] = centerWorld[i] - viewUp[i] * centerToEndDistance;
    topWorld[i] = centerWorld[i] + viewUp[i] * centerToEndDistance;
    leftWorld[i] = centerWorld[i] - viewRight[i] * centerToEndDistance;
    rightWorld[i] = centerWorld[i] + viewRight[i] * centerToEndDistance;
  }
 
  const ellipseWorldCoordinates = [
    bottomWorld,
    topWorld,
    leftWorld,
    rightWorld,
  ] as [Types.Point3, Types.Point3, Types.Point3, Types.Point3];
  return ellipseWorldCoordinates;
}