Explorar o código

Prevent exception when path has only one object

Raanan Weber %!s(int64=4) %!d(string=hai) anos
pai
achega
49162cd40e
Modificáronse 1 ficheiros con 65 adicións e 63 borrados
  1. 65 63
      src/Maths/math.path.ts

+ 65 - 63
src/Maths/math.path.ts

@@ -1,7 +1,7 @@
-import { DeepImmutable, Nullable } from '../types';
-import { Scalar } from './math.scalar';
-import { Vector2, Vector3, Quaternion, Matrix } from './math.vector';
-import { Epsilon } from './math.constants';
+import { DeepImmutable, Nullable } from "../types";
+import { Scalar } from "./math.scalar";
+import { Vector2, Vector3, Quaternion, Matrix } from "./math.vector";
+import { Epsilon } from "./math.constants";
 
 /**
  * Defines potential orientation for back face culling
@@ -12,7 +12,7 @@ export enum Orientation {
      */
     CW = 0,
     /** Counter clockwise */
-    CCW = 1
+    CCW = 1,
 }
 
 /** Class used to represent a Bezier curve */
@@ -27,7 +27,6 @@ export class BezierCurve {
      * @returns the interpolated value
      */
     public static Interpolate(t: number, x1: number, y1: number, x2: number, y2: number): number {
-
         // Extract X (which is equal to time here)
         var f0 = 1 - 3 * x2 + 3 * x1;
         var f1 = 3 * x2 - 6 * x1;
@@ -42,13 +41,10 @@ export class BezierCurve {
             var slope = 1.0 / (3.0 * f0 * refinedT2 + 2.0 * f1 * refinedT + f2);
             refinedT -= (x - t) * slope;
             refinedT = Math.min(1, Math.max(0, refinedT));
-
         }
 
         // Resolve cubic bezier for the given x
-        return 3 * Math.pow(1 - refinedT, 2) * refinedT * y1 +
-            3 * (1 - refinedT) * Math.pow(refinedT, 2) * y2 +
-            Math.pow(refinedT, 3);
+        return 3 * Math.pow(1 - refinedT, 2) * refinedT * y1 + 3 * (1 - refinedT) * Math.pow(refinedT, 2) * y2 + Math.pow(refinedT, 3);
     }
 }
 
@@ -64,7 +60,9 @@ export class Angle {
      */
     constructor(radians: number) {
         this._radians = radians;
-        if (this._radians < 0.0) { this._radians += (2.0 * Math.PI); }
+        if (this._radians < 0.0) {
+            this._radians += 2.0 * Math.PI;
+        }
     }
 
     /**
@@ -72,7 +70,7 @@ export class Angle {
      * @returns the Angle value in degrees (float)
      */
     public degrees() {
-        return this._radians * 180.0 / Math.PI;
+        return (this._radians * 180.0) / Math.PI;
     }
 
     /**
@@ -109,7 +107,7 @@ export class Angle {
      * @returns a new Angle
      */
     public static FromDegrees(degrees: number): Angle {
-        return new Angle(degrees * Math.PI / 180.0);
+        return new Angle((degrees * Math.PI) / 180.0);
     }
 }
 
@@ -150,17 +148,14 @@ export class Arc2 {
         /** Defines the mid point of the arc */
         public midPoint: Vector2,
         /** Defines the end point of the arc */
-        public endPoint: Vector2) {
-
+        public endPoint: Vector2
+    ) {
         var temp = Math.pow(midPoint.x, 2) + Math.pow(midPoint.y, 2);
-        var startToMid = (Math.pow(startPoint.x, 2) + Math.pow(startPoint.y, 2) - temp) / 2.;
-        var midToEnd = (temp - Math.pow(endPoint.x, 2) - Math.pow(endPoint.y, 2)) / 2.;
+        var startToMid = (Math.pow(startPoint.x, 2) + Math.pow(startPoint.y, 2) - temp) / 2;
+        var midToEnd = (temp - Math.pow(endPoint.x, 2) - Math.pow(endPoint.y, 2)) / 2;
         var det = (startPoint.x - midPoint.x) * (midPoint.y - endPoint.y) - (midPoint.x - endPoint.x) * (startPoint.y - midPoint.y);
 
-        this.centerPoint = new Vector2(
-            (startToMid * (midPoint.y - endPoint.y) - midToEnd * (startPoint.y - midPoint.y)) / det,
-            ((startPoint.x - midPoint.x) * midToEnd - (midPoint.x - endPoint.x) * startToMid) / det
-        );
+        this.centerPoint = new Vector2((startToMid * (midPoint.y - endPoint.y) - midToEnd * (startPoint.y - midPoint.y)) / det, ((startPoint.x - midPoint.x) * midToEnd - (midPoint.x - endPoint.x) * startToMid) / det);
 
         this.radius = this.centerPoint.subtract(this.startPoint).length();
 
@@ -171,12 +166,20 @@ export class Arc2 {
         var a3 = Angle.BetweenTwoPoints(this.centerPoint, this.endPoint).degrees();
 
         // angles correction
-        if (a2 - a1 > +180.0) { a2 -= 360.0; }
-        if (a2 - a1 < -180.0) { a2 += 360.0; }
-        if (a3 - a2 > +180.0) { a3 -= 360.0; }
-        if (a3 - a2 < -180.0) { a3 += 360.0; }
+        if (a2 - a1 > +180.0) {
+            a2 -= 360.0;
+        }
+        if (a2 - a1 < -180.0) {
+            a2 += 360.0;
+        }
+        if (a3 - a2 > +180.0) {
+            a3 -= 360.0;
+        }
+        if (a3 - a2 < -180.0) {
+            a3 += 360.0;
+        }
 
-        this.orientation = (a2 - a1) < 0 ? Orientation.CW : Orientation.CCW;
+        this.orientation = a2 - a1 < 0 ? Orientation.CW : Orientation.CCW;
         this.angle = Angle.FromDegrees(this.orientation === Orientation.CW ? a1 - a3 : a3 - a1);
     }
 }
@@ -239,7 +242,9 @@ export class Path2 {
         var arc = new Arc2(startPoint, midPoint, endPoint);
 
         var increment = arc.angle.radians() / numberOfSegments;
-        if (arc.orientation === Orientation.CW) { increment *= -1; }
+        if (arc.orientation === Orientation.CW) {
+            increment *= -1;
+        }
         var currentAngle = arc.startAngle.radians() + increment;
 
         for (var i = 0; i < numberOfSegments; i++) {
@@ -268,7 +273,7 @@ export class Path2 {
         if (this.closed) {
             var lastPoint = this._points[this._points.length - 1];
             var firstPoint = this._points[0];
-            result += (firstPoint.subtract(lastPoint).length());
+            result += firstPoint.subtract(lastPoint).length();
         }
         return result;
     }
@@ -301,15 +306,12 @@ export class Path2 {
             var b = this._points[j];
             var bToA = b.subtract(a);
 
-            var nextOffset = (bToA.length() + previousOffset);
+            var nextOffset = bToA.length() + previousOffset;
             if (lengthPosition >= previousOffset && lengthPosition <= nextOffset) {
                 var dir = bToA.normalize();
                 var localOffset = lengthPosition - previousOffset;
 
-                return new Vector2(
-                    a.x + (dir.x * localOffset),
-                    a.y + (dir.y * localOffset)
-                );
+                return new Vector2(a.x + dir.x * localOffset, a.y + dir.y * localOffset);
             }
             previousOffset = nextOffset;
         }
@@ -354,14 +356,14 @@ export class Path3D {
     };
 
     /**
-    * new Path3D(path, normal, raw)
-    * Creates a Path3D. A Path3D is a logical math object, so not a mesh.
-    * please read the description in the tutorial : https://doc.babylonjs.com/how_to/how_to_use_path3d
-    * @param path an array of Vector3, the curve axis of the Path3D
-    * @param firstNormal (options) Vector3, the first wanted normal to the curve. Ex (0, 1, 0) for a vertical normal.
-    * @param raw (optional, default false) : boolean, if true the returned Path3D isn't normalized. Useful to depict path acceleration or speed.
-    * @param alignTangentsWithPath (optional, default false) : boolean, if true the tangents will be aligned with the path.
-    */
+     * new Path3D(path, normal, raw)
+     * Creates a Path3D. A Path3D is a logical math object, so not a mesh.
+     * please read the description in the tutorial : https://doc.babylonjs.com/how_to/how_to_use_path3d
+     * @param path an array of Vector3, the curve axis of the Path3D
+     * @param firstNormal (options) Vector3, the first wanted normal to the curve. Ex (0, 1, 0) for a vertical normal.
+     * @param raw (optional, default false) : boolean, if true the returned Path3D isn't normalized. Useful to depict path acceleration or speed.
+     * @param alignTangentsWithPath (optional, default false) : boolean, if true the tangents will be aligned with the path.
+     */
     constructor(
         /**
          * an array of Vector3, the curve axis of the Path3D
@@ -517,7 +519,7 @@ export class Path3D {
             let point = this._curve[i + 0];
             let tangent = this._curve[i + 1].subtract(point).normalize();
             let subLength = this._distances[i + 1] - this._distances[i + 0];
-            let subPosition = Math.min(Math.max(Vector3.Dot(tangent, target.subtract(point).normalize()), 0.0) * Vector3.Distance(point, target) / subLength, 1.0);
+            let subPosition = Math.min((Math.max(Vector3.Dot(tangent, target.subtract(point).normalize()), 0.0) * Vector3.Distance(point, target)) / subLength, 1.0);
             let distance = Vector3.Distance(point.add(tangent.scale(subPosition * subLength)), target);
 
             if (distance < smallestDistance) {
@@ -536,10 +538,10 @@ export class Path3D {
      */
     public slice(start: number = 0.0, end: number = 1.0) {
         if (start < 0.0) {
-            start = 1 - (start * -1.0) % 1.0;
+            start = 1 - ((start * -1.0) % 1.0);
         }
         if (end < 0.0) {
-            end = 1 - (end * -1.0) % 1.0;
+            end = 1 - ((end * -1.0) % 1.0);
         }
         if (start > end) {
             let _start = start;
@@ -586,7 +588,11 @@ export class Path3D {
 
     // private function compute() : computes tangents, normals and binormals
     private _compute(firstNormal: Nullable<Vector3>, alignTangentsWithPath = false): void {
-        var l = this._curve.length;
+        const l = this._curve.length;
+
+        if (l < 2) {
+            return;
+        }
 
         // first and last tangents
         this._tangents[0] = this._getFirstNonNullVector(0);
@@ -612,12 +618,12 @@ export class Path3D {
         this._distances[0] = 0.0;
 
         // normals and binormals : next points
-        var prev: Vector3;        // previous vector (segment)
-        var cur: Vector3;         // current vector (segment)
-        var curTang: Vector3;     // current tangent
+        var prev: Vector3; // previous vector (segment)
+        var cur: Vector3; // current vector (segment)
+        var curTang: Vector3; // current tangent
         // previous normal
-        var prevNor: Vector3;    // previous normal
-        var prevBinor: Vector3;   // previous binormal
+        var prevNor: Vector3; // previous normal
+        var prevBinor: Vector3; // previous binormal
 
         for (var i = 1; i < l; i++) {
             // tangents
@@ -686,21 +692,18 @@ export class Path3D {
 
         if (va === undefined || va === null) {
             var point: Vector3;
-            if (!Scalar.WithinEpsilon(Math.abs(vt.y) / tgl, 1.0, Epsilon)) {     // search for a point in the plane
+            if (!Scalar.WithinEpsilon(Math.abs(vt.y) / tgl, 1.0, Epsilon)) {
+                // search for a point in the plane
                 point = new Vector3(0.0, -1.0, 0.0);
-            }
-            else if (!Scalar.WithinEpsilon(Math.abs(vt.x) / tgl, 1.0, Epsilon)) {
+            } else if (!Scalar.WithinEpsilon(Math.abs(vt.x) / tgl, 1.0, Epsilon)) {
                 point = new Vector3(1.0, 0.0, 0.0);
-            }
-            else if (!Scalar.WithinEpsilon(Math.abs(vt.z) / tgl, 1.0, Epsilon)) {
+            } else if (!Scalar.WithinEpsilon(Math.abs(vt.z) / tgl, 1.0, Epsilon)) {
                 point = new Vector3(0.0, 0.0, 1.0);
-            }
-            else {
+            } else {
                 point = Vector3.Zero();
             }
             normal0 = Vector3.Cross(vt, point);
-        }
-        else {
+        } else {
             normal0 = Vector3.Cross(vt, va);
             Vector3.CrossToRef(normal0, vt, normal0);
         }
@@ -893,8 +896,7 @@ export class Curve3 {
                 }
             }
             catmullRom.push(catmullRom[0]);
-        }
-        else {
+        } else {
             var totalPoints = new Array<Vector3>();
             totalPoints.push(points[0].clone());
             Array.prototype.push.apply(totalPoints, points);
@@ -958,8 +960,8 @@ export class Curve3 {
     private _computeLength(path: DeepImmutable<Vector3[]>): number {
         var l = 0;
         for (var i = 1; i < path.length; i++) {
-            l += (path[i].subtract(path[i - 1])).length();
+            l += path[i].subtract(path[i - 1]).length();
         }
         return l;
     }
-}
+}