All files / engine/Source/Core barycentricCoordinates.js

95.74% Statements 45/47
88.88% Branches 16/18
100% Functions 1/1
95.74% Lines 45/47

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            1x 1x 1x                                               3823807x 3823805x 3823803x 3823801x     3823799x 11x                         3823799x 6x 1x   5x     5x       5x 5x 5x   5x 5x 5x 5x 5x   3823793x 1270327x   2553466x 1271104x   1282362x 1270578x     11784x 11784x 11784x   11784x 11784x 11784x 11784x 11784x     11789x 11789x 11789x     11789x 1x     11788x 11788x 11788x 11788x      
import Cartesian2 from "./Cartesian2.js";
import Cartesian3 from "./Cartesian3.js";
import Check from "./Check.js";
import defined from "./defined.js";
import CesiumMath from "./Math.js";
 
const scratchCartesian1 = new Cartesian3();
const scratchCartesian2 = new Cartesian3();
const scratchCartesian3 = new Cartesian3();
 
/**
 * Computes the barycentric coordinates for a point with respect to a triangle.
 *
 * @function
 *
 * @param {Cartesian2|Cartesian3} point The point to test.
 * @param {Cartesian2|Cartesian3} p0 The first point of the triangle, corresponding to the barycentric x-axis.
 * @param {Cartesian2|Cartesian3} p1 The second point of the triangle, corresponding to the barycentric y-axis.
 * @param {Cartesian2|Cartesian3} p2 The third point of the triangle, corresponding to the barycentric z-axis.
 * @param {Cartesian3} [result] The object onto which to store the result.
 * @returns {Cartesian3|undefined} The modified result parameter or a new Cartesian3 instance if one was not provided. If the triangle is degenerate the function will return undefined.
 *
 * @example
 * // Returns Cartesian3.UNIT_X
 * const p = new Cesium.Cartesian3(-1.0, 0.0, 0.0);
 * const b = Cesium.barycentricCoordinates(p,
 *   new Cesium.Cartesian3(-1.0, 0.0, 0.0),
 *   new Cesium.Cartesian3( 1.0, 0.0, 0.0),
 *   new Cesium.Cartesian3( 0.0, 1.0, 1.0));
 */
function barycentricCoordinates(point, p0, p1, p2, result) {
  //>>includeStart('debug', pragmas.debug);
  Check.defined("point", point);
  Check.defined("p0", p0);
  Check.defined("p1", p1);
  Check.defined("p2", p2);
  //>>includeEnd('debug');
 
  if (!defined(result)) {
    result = new Cartesian3();
  }
 
  // Implementation based on http://www.blackpawn.com/texts/pointinpoly/default.html.
  let v0;
  let v1;
  let v2;
  let dot00;
  let dot01;
  let dot02;
  let dot11;
  let dot12;
 
  if (!defined(p0.z)) {
    if (Cartesian2.equalsEpsilon(point, p0, CesiumMath.EPSILON14)) {
      return Cartesian3.clone(Cartesian3.UNIT_X, result);
    }
    Iif (Cartesian2.equalsEpsilon(point, p1, CesiumMath.EPSILON14)) {
      return Cartesian3.clone(Cartesian3.UNIT_Y, result);
    }
    Iif (Cartesian2.equalsEpsilon(point, p2, CesiumMath.EPSILON14)) {
      return Cartesian3.clone(Cartesian3.UNIT_Z, result);
    }
 
    v0 = Cartesian2.subtract(p1, p0, scratchCartesian1);
    v1 = Cartesian2.subtract(p2, p0, scratchCartesian2);
    v2 = Cartesian2.subtract(point, p0, scratchCartesian3);
 
    dot00 = Cartesian2.dot(v0, v0);
    dot01 = Cartesian2.dot(v0, v1);
    dot02 = Cartesian2.dot(v0, v2);
    dot11 = Cartesian2.dot(v1, v1);
    dot12 = Cartesian2.dot(v1, v2);
  } else {
    if (Cartesian3.equalsEpsilon(point, p0, CesiumMath.EPSILON14)) {
      return Cartesian3.clone(Cartesian3.UNIT_X, result);
    }
    if (Cartesian3.equalsEpsilon(point, p1, CesiumMath.EPSILON14)) {
      return Cartesian3.clone(Cartesian3.UNIT_Y, result);
    }
    if (Cartesian3.equalsEpsilon(point, p2, CesiumMath.EPSILON14)) {
      return Cartesian3.clone(Cartesian3.UNIT_Z, result);
    }
 
    v0 = Cartesian3.subtract(p1, p0, scratchCartesian1);
    v1 = Cartesian3.subtract(p2, p0, scratchCartesian2);
    v2 = Cartesian3.subtract(point, p0, scratchCartesian3);
 
    dot00 = Cartesian3.dot(v0, v0);
    dot01 = Cartesian3.dot(v0, v1);
    dot02 = Cartesian3.dot(v0, v2);
    dot11 = Cartesian3.dot(v1, v1);
    dot12 = Cartesian3.dot(v1, v2);
  }
 
  result.y = dot11 * dot02 - dot01 * dot12;
  result.z = dot00 * dot12 - dot01 * dot02;
  const q = dot00 * dot11 - dot01 * dot01;
 
  // Triangle is degenerate
  if (q === 0) {
    return undefined;
  }
 
  result.y /= q;
  result.z /= q;
  result.x = 1.0 - result.y - result.z;
  return result;
}
export default barycentricCoordinates;