All files / core/src/utilities updatePlaneRestriction.ts

30.76% Statements 8/26
33.33% Branches 4/12
100% Functions 1/1
32% Lines 8/25

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                    428x                             28x     28x           28x   28x 28x 28x 28x                                                                      
import type { Point3, ViewReference } from '../types';
import { isEqual } from '../utilities/isEqual';
import { vec3 } from 'gl-matrix';
 
/**
 * A value to compare how orthogonal two vectors are.  As long as the dot
 * product of the previous in-plane vector and the new vector as unit vectors,
 * this vector will be considered for using for testing for orthogonality with
 * view plane normals.
 */
const ORTHOGONAL_TEST_VALUE = 0.95;
 
/**
 * Updates the planeRestriction(s) inside the view reference
 * This will create a reference containing a point and up to two non-collinear
 * in-plane vectors, selected from the set of points provided.
 *
 * This type of reference restricts the allowed camera views to those
 * which contain the point, and whose view plane normal is orthogonal to the in
 * plane vectors.
 */
export function updatePlaneRestriction(
  points: Point3[],
  reference: ViewReference
) {
  Iif (!points?.length || !reference.FrameOfReferenceUID) {
    return;
  }
  reference.planeRestriction ||= {
    FrameOfReferenceUID: reference.FrameOfReferenceUID,
    point: points[0],
    inPlaneVector1: null,
    inPlaneVector2: null,
  };
  const { planeRestriction } = reference;
 
  Eif (points.length === 1) {
    planeRestriction.inPlaneVector1 = null;
    planeRestriction.inPlaneVector2 = null;
    return planeRestriction;
  }
 
  const v1 = vec3.sub(
    vec3.create(),
    points[0],
    points[Math.floor(points.length / 2)]
  );
  vec3.normalize(v1, v1);
  planeRestriction.inPlaneVector1 = <Point3>v1;
 
  planeRestriction.inPlaneVector2 = null;
  const n = points.length;
  if (n > 2) {
    // Try to find a second vector that isn't colinear with the first one
    // to form a plane specifier.
    for (let i = Math.floor(n / 3); i < n; i++) {
      const testVector = vec3.sub(vec3.create(), points[i], points[0]);
      const length = vec3.length(testVector);
      if (isEqual(length, 0)) {
        continue;
      }
      if (
        vec3.dot(testVector, planeRestriction.inPlaneVector1) <
        length * ORTHOGONAL_TEST_VALUE
      ) {
        vec3.normalize(testVector, testVector);
        planeRestriction.inPlaneVector2 = <Point3>testVector;
        return planeRestriction;
      }
    }
  }
 
  return planeRestriction;
}