jsxgraph 1.4.2 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/math/clip.js CHANGED
@@ -1888,7 +1888,6 @@ define([
1888
1888
 
1889
1889
  // Collect all points into clip array C
1890
1890
  C = this._getPath(clip, board);
1891
-
1892
1891
  len = C.length;
1893
1892
  if (len > 0 && Geometry.distance(C[0].coords.usrCoords, C[len - 1].coords.usrCoords, 3) < Mat.eps * Mat.eps) {
1894
1893
  C.pop();
@@ -1101,6 +1101,30 @@ define([
1101
1101
  return that.meetCurveLine(el1, el2, i, el1.board, alwaysintersect);
1102
1102
  };
1103
1103
 
1104
+ } else if (el1.type === Const.OBJECT_TYPE_POLYGON || el2.type === Const.OBJECT_TYPE_POLYGON) {
1105
+ // polygon - other
1106
+ // Uses the Greiner-Hormann clipping algorithm
1107
+ // Not implemented: polygon - point
1108
+
1109
+ if (el1.elementClass === Const.OBJECT_CLASS_LINE) {
1110
+ // line - path
1111
+ /** @ignore */
1112
+ func = function () {
1113
+ return that.meetPolygonLine(el2, el1, i, el1.board, alwaysintersect);
1114
+ };
1115
+ } else if (el2.elementClass === Const.OBJECT_CLASS_LINE) {
1116
+ // path - line
1117
+ func = function () {
1118
+ return that.meetPolygonLine(el1, el2, i, el1.board, alwaysintersect);
1119
+ };
1120
+ } else {
1121
+ // path - path
1122
+ /** @ignore */
1123
+ func = function () {
1124
+ return that.meetPathPath(el1, el2, i, el1.board);
1125
+ };
1126
+ }
1127
+
1104
1128
  } else if (el1.elementClass === Const.OBJECT_CLASS_LINE && el2.elementClass === Const.OBJECT_CLASS_LINE) {
1105
1129
  // line - line, lines may also be segments.
1106
1130
  /** @ignore */
@@ -1516,6 +1540,8 @@ define([
1516
1540
  * @param {JXG.Line} li Line
1517
1541
  * @param {Number} nr Will return the nr-th intersection point.
1518
1542
  * @param {JXG.Board} board
1543
+ * @param {Boolean} testSegment Test if intersection has to be inside of the segment or somewhere on the
1544
+ * line defined by the segment
1519
1545
  * @returns {JXG.Coords} Coords object containing the intersection.
1520
1546
  */
1521
1547
  meetCurveLineContinuous: function (cu, li, nr, board, testSegment) {
@@ -1580,7 +1606,6 @@ define([
1580
1606
  return (new Coords(Const.COORDS_BY_USER, [z, cu.X(t), cu.Y(t)], board));
1581
1607
  },
1582
1608
 
1583
-
1584
1609
  /**
1585
1610
  * Intersection of line and curve, discrete case.
1586
1611
  * Segments are treated as lines.
@@ -1767,6 +1792,87 @@ define([
1767
1792
  return [c, t, u];
1768
1793
  },
1769
1794
 
1795
+ /**
1796
+ * Find the n-th intersection point of two pathes, usually given by polygons. Uses parts of the
1797
+ * Greiner-Hormann algorithm in JXG.Math.Clip.
1798
+ *
1799
+ * @param {JXG.Circle|JXG.Curve|JXG.Polygon} path1
1800
+ * @param {JXG.Circle|JXG.Curve|JXG.Polygon} path2
1801
+ * @param {Number} n
1802
+ * @param {JXG.Board} board
1803
+ *
1804
+ * @returns {JXG.Coords} Intersection point. In case no intersection point is detected,
1805
+ * the ideal point [0,0,0] is returned.
1806
+ *
1807
+ */
1808
+ meetPathPath: function(path1, path2, nr, board) {
1809
+ var S, C, len, intersections;
1810
+
1811
+ S = JXG.Math.Clip._getPath(path1, board);
1812
+ len = S.length;
1813
+ if (len > 0 && this.distance(S[0].coords.usrCoords, S[len - 1].coords.usrCoords, 3) < Mat.eps) {
1814
+ S.pop();
1815
+ }
1816
+
1817
+ C = JXG.Math.Clip._getPath(path2, board);
1818
+ len = C.length;
1819
+ if (len > 0 && this.distance(C[0].coords.usrCoords, C[len - 1].coords.usrCoords, 3) < Mat.eps * Mat.eps) {
1820
+ C.pop();
1821
+ }
1822
+
1823
+ // Handle cases where at least one of the paths is empty
1824
+ if (nr < 0 || JXG.Math.Clip.isEmptyCase(S, C, 'intersection')) {
1825
+ return (new Coords(Const.COORDS_BY_USER, [0, 0, 0], board));
1826
+ }
1827
+
1828
+ JXG.Math.Clip.makeDoublyLinkedList(S);
1829
+ JXG.Math.Clip.makeDoublyLinkedList(C);
1830
+
1831
+ intersections = JXG.Math.Clip.findIntersections(S, C, board)[0];
1832
+ if (nr < intersections.length) {
1833
+ return intersections[nr].coords;
1834
+ }
1835
+ return (new Coords(Const.COORDS_BY_USER, [0, 0, 0], board));
1836
+ },
1837
+
1838
+ /**
1839
+ * Find the n-th intersection point between a polygon and a line.
1840
+ * @param {JXG.Polygon} path
1841
+ * @param {JXG.Line} line
1842
+ * @param {Number} nr
1843
+ * @param {JXG.Board} board
1844
+ * @param {Boolean} alwaysIntersect If false just the segment between the two defining points of the line are tested for intersection.
1845
+ *
1846
+ * @returns {JXG.Coords} Intersection point. In case no intersection point is detected,
1847
+ * the ideal point [0,0,0] is returned.
1848
+ */
1849
+ meetPolygonLine: function(path, line, nr, board, alwaysIntersect) {
1850
+ var i, res, border,
1851
+ crds = [0,0,0],
1852
+ len = path.borders.length,
1853
+ intersections = [];
1854
+
1855
+ for (i = 0; i < len; i++) {
1856
+ border = path.borders[i];
1857
+ res = this.meetSegmentSegment(
1858
+ border.point1.coords.usrCoords,
1859
+ border.point2.coords.usrCoords,
1860
+ line.point1.coords.usrCoords,
1861
+ line.point2.coords.usrCoords);
1862
+
1863
+ if (
1864
+ (!alwaysIntersect || (res[2] >= 0 && res[2] < 1)) &&
1865
+ res[1] >= 0 && res[1] < 1) {
1866
+ intersections.push(res[0]);
1867
+ }
1868
+ }
1869
+
1870
+ if (nr >= 0 && nr < intersections.length) {
1871
+ crds = intersections[nr];
1872
+ }
1873
+ return (new Coords(Const.COORDS_BY_USER, crds, board));
1874
+ },
1875
+
1770
1876
  /****************************************/
1771
1877
  /**** BEZIER CURVE ALGORITHMS ****/
1772
1878
  /****************************************/
@@ -2707,7 +2813,86 @@ define([
2707
2813
  };
2708
2814
 
2709
2815
  return [makeFct('X', 'cos'), makeFct('Y', 'sin'), 0, pi2];
2710
- }
2816
+ },
2817
+
2818
+
2819
+ meet3Planes: function (n1, d1, n2, d2, n3, d3) {
2820
+ var p = [0, 0, 0],
2821
+ n31, n12, n23, denom,
2822
+ i;
2823
+
2824
+ n31 = Mat.crossProduct(n3, n1);
2825
+ n12 = Mat.crossProduct(n1, n2);
2826
+ n23 = Mat.crossProduct(n2, n3);
2827
+ denom = Mat.innerProduct(n1, n23, 3);
2828
+ for (i = 0; i < 3; i++) {
2829
+ p[i] = (d1 * n23[i] + d2 * n31[i] + d3 * n12[i]) / denom;
2830
+ }
2831
+ return p;
2832
+ },
2833
+
2834
+
2835
+ meetPlanePlane: function (v11, v12, v21, v22) {
2836
+ var i, no1, no2,
2837
+ v = [0, 0, 0],
2838
+ w = [0, 0, 0];
2839
+
2840
+ for (i = 0; i < 3; i++) {
2841
+ v[i] = Type.evaluate(v11[i]);
2842
+ w[i] = Type.evaluate(v12[i]);
2843
+ }
2844
+ no1 = Mat.crossProduct(v, w);
2845
+
2846
+ for (i = 0; i < 3; i++) {
2847
+ v[i] = Type.evaluate(v21[i]);
2848
+ w[i] = Type.evaluate(v22[i]);
2849
+ }
2850
+ no2 = Mat.crossProduct(v, w);
2851
+
2852
+ return Mat.crossProduct(no1, no2);
2853
+ },
2854
+
2855
+ project3DTo3DPlane: function (point, normal, foot) {
2856
+ // TODO: homogeneous 3D coordinates
2857
+ var sol = [0, 0, 0],
2858
+ le, d1, d2, lbda;
2859
+
2860
+ foot = foot || [0, 0, 0];
2861
+
2862
+ le = Mat.norm(normal);
2863
+ d1 = Mat.innerProduct(point, normal, 3);
2864
+ d2 = Mat.innerProduct(foot, normal, 3);
2865
+ // (point - lbda * normal / le) * normal / le == foot * normal / le
2866
+ // => (point * normal - foot * normal) == lbda * le
2867
+ lbda = (d1 - d2) / le;
2868
+ sol = Mat.axpy(-lbda, normal, point);
2869
+
2870
+ return sol;
2871
+ },
2872
+
2873
+ getPlaneBounds: function (v1, v2, q, s, e) {
2874
+ var s1, s2, e1, e2, mat, rhs, sol;
2875
+
2876
+ if (v1[2] + v2[0] !== 0) {
2877
+ mat = [
2878
+ [v1[0], v2[0]],
2879
+ [v1[1], v2[1]]
2880
+ ];
2881
+ rhs = [s - q[0], s - q[1]];
2882
+
2883
+ sol = Numerics.Gauss(mat, rhs);
2884
+ s1 = sol[0];
2885
+ s2 = sol[1];
2886
+
2887
+ rhs = [e - q[0], e - q[1]];
2888
+ sol = Numerics.Gauss(mat, rhs);
2889
+ e1 = sol[0];
2890
+ e2 = sol[1];
2891
+ return [s1, e1, s2, e2];
2892
+ }
2893
+ return null;
2894
+ },
2895
+
2711
2896
  });
2712
2897
 
2713
2898
  return Mat.Geometry;
package/src/math/math.js CHANGED
@@ -466,6 +466,15 @@ define(['jxg', 'utils/type'], function (JXG, Type) {
466
466
  return Math.sqrt(sum);
467
467
  },
468
468
 
469
+ axpy: function (a, x, y) {
470
+ var i, le = x.length,
471
+ p = [];
472
+ for (i = 0; i < le; i++) {
473
+ p[i] = a * x[i] + y[i];
474
+ }
475
+ return p;
476
+ },
477
+
469
478
  /**
470
479
  * Compute the factorial of a positive integer. If a non-integer value
471
480
  * is given, the fraction will be ignored.