All files / packages/tools/src/utilities/math/rectangle distanceToPoint.ts

95.23% Statements 20/21
83.33% Branches 5/6
100% Functions 3/3
95.23% Lines 20/21

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                                                    9x 9x   9x 9x   9x 9x   9x 9x   9x             9x                             9x           45x   9x 9x   9x 108x 36x   36x 21x       9x    
import type { Types } from '@cornerstonejs/core';
import * as lineSegment from '../line';
 
type rectLineSegments = {
  top: Types.Point2[];
  right: Types.Point2[];
  bottom: Types.Point2[];
  left: Types.Point2[];
};
 
/**
 * Given a rectangle left, top, width and height, return an object containing the
 * line segments that make up the rectangle's four sides
 * @param left - The x-coordinate of the left edge of the rectangle.
 * @param top - The y-coordinate of the top edge of the rectangle.
 * @param width - The width of the rectangle.
 * @param height - The height of the rectangle.
 * @returns An object with four keys, each of which contains an array of two
 * points.
 */
function rectToLineSegments(
  left: number,
  top: number,
  width: number,
  height: number
): rectLineSegments {
  const topLineStart: Types.Point2 = [left, top];
  const topLineEnd: Types.Point2 = [left + width, top];
 
  const rightLineStart: Types.Point2 = [left + width, top];
  const rightLineEnd: Types.Point2 = [left + width, top + height];
 
  const bottomLineStart: Types.Point2 = [left + width, top + height];
  const bottomLineEnd: Types.Point2 = [left, top + height];
 
  const leftLineStart: Types.Point2 = [left, top + height];
  const leftLineEnd: Types.Point2 = [left, top];
 
  const lineSegments = {
    top: [topLineStart, topLineEnd],
    right: [rightLineStart, rightLineEnd],
    bottom: [bottomLineStart, bottomLineEnd],
    left: [leftLineStart, leftLineEnd],
  };
 
  return lineSegments;
}
 
/**
 * Calculates distance of the point to the rectangle. It calculates the minimum
 * distance between the point and each line segment of the rectangle.
 *
 * @param rect - coordinates of the rectangle [left, top, width, height]
 * @param point - [x,y] coordinates of a point
 * @returns
 */
export default function distanceToPoint(
  rect: number[],
  point: Types.Point2
): number {
  Iif (rect.length !== 4 || point.length !== 2) {
    throw Error(
      'rectangle:[left, top, width, height] or point: [x,y] not defined correctly'
    );
  }
 
  const [left, top, width, height] = rect;
 
  let minDistance = 655535;
  const lineSegments = rectToLineSegments(left, top, width, height);
 
  Object.keys(lineSegments).forEach((segment) => {
    const [lineStart, lineEnd] = lineSegments[segment];
    const distance = lineSegment.distanceToPoint(lineStart, lineEnd, point);
 
    if (distance < minDistance) {
      minDistance = distance;
    }
  });
 
  return minDistance;
}