jsxgraph 1.3.1 → 1.4.2

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.
Files changed (90) hide show
  1. package/README.md +2 -2
  2. package/distrib/README.md +2 -2
  3. package/distrib/geogebra.min.js +3 -3
  4. package/distrib/geonext.min.js +3 -3
  5. package/distrib/index.d.ts +4964 -4627
  6. package/distrib/intergeo.min.js +3 -3
  7. package/distrib/jsxgraph.css +10 -15
  8. package/distrib/jsxgraphcore.js +9 -25
  9. package/distrib/jsxgraphsrc.js +28437 -25331
  10. package/distrib/sketch.min.js +3 -3
  11. package/package.json +11 -22
  12. package/src/base/board.js +555 -427
  13. package/src/base/chart.js +1 -1
  14. package/src/base/circle.js +23 -1
  15. package/src/base/composition.js +1 -1
  16. package/src/base/constants.js +33 -11
  17. package/src/base/coords.js +4 -4
  18. package/src/base/coordselement.js +47 -20
  19. package/src/base/curve.js +308 -117
  20. package/src/base/element.js +80 -51
  21. package/src/base/foreignobject.js +463 -0
  22. package/src/base/group.js +2 -2
  23. package/src/base/image.js +12 -15
  24. package/src/base/line.js +1 -1
  25. package/src/base/point.js +20 -41
  26. package/src/base/polygon.js +75 -18
  27. package/src/base/text.js +116 -63
  28. package/src/base/ticks.js +35 -12
  29. package/src/base/transformation.js +1 -1
  30. package/src/base/turtle.js +1 -1
  31. package/src/element/arc.js +1 -1
  32. package/src/element/button.js +29 -2
  33. package/src/element/checkbox.js +31 -1
  34. package/src/element/comb.js +5 -2
  35. package/src/element/composition.js +27 -6
  36. package/src/element/conic.js +46 -5
  37. package/src/element/input.js +32 -1
  38. package/src/element/locus.js +2 -2
  39. package/src/element/measure.js +9 -4
  40. package/src/element/sector.js +46 -12
  41. package/src/element/slider.js +17 -12
  42. package/src/element/slopetriangle.js +1 -1
  43. package/src/jsxgraph.js +28 -9
  44. package/src/jxg.js +4 -3
  45. package/src/loadjsxgraph.js +3 -2
  46. package/src/math/bst.js +1 -1
  47. package/src/math/clip.js +550 -345
  48. package/src/math/complex.js +1 -1
  49. package/src/math/extrapolate.js +1 -1
  50. package/src/math/geometry.js +109 -128
  51. package/src/math/ia.js +290 -21
  52. package/src/math/math.js +30 -1
  53. package/src/math/metapost.js +1 -1
  54. package/src/math/nlp.js +25 -5
  55. package/src/math/numerics.js +183 -4
  56. package/src/math/plot.js +4 -4
  57. package/src/math/poly.js +1 -1
  58. package/src/math/probfuncs.js +2 -1
  59. package/src/math/qdt.js +68 -62
  60. package/src/math/statistics.js +58 -7
  61. package/src/math/symbolic.js +1 -1
  62. package/src/options.js +393 -115
  63. package/src/parser/ca.js +1297 -1291
  64. package/src/parser/datasource.js +1 -1
  65. package/src/parser/geonext.js +6 -6
  66. package/src/parser/jessiecode.js +378 -79
  67. package/src/parser/jessiescript.js +1 -1
  68. package/src/reader/cinderella.js +1 -1
  69. package/src/reader/file.js +1 -1
  70. package/src/reader/geogebra.js +1 -1
  71. package/src/reader/geonext.js +1 -1
  72. package/src/reader/graph.js +1 -1
  73. package/src/reader/intergeo.js +1 -1
  74. package/src/reader/sketch.js +25 -17
  75. package/src/renderer/abstract.js +25 -7
  76. package/src/renderer/canvas.js +20 -15
  77. package/src/renderer/no.js +11 -4
  78. package/src/renderer/svg.js +68 -49
  79. package/src/renderer/vml.js +36 -32
  80. package/src/server/server.js +1 -1
  81. package/src/utils/base64.js +2 -2
  82. package/src/utils/color.js +147 -3
  83. package/src/utils/dump.js +20 -14
  84. package/src/utils/env.js +26 -62
  85. package/src/utils/event.js +1 -1
  86. package/src/utils/expect.js +1 -1
  87. package/src/utils/type.js +30 -19
  88. package/src/utils/xml.js +1 -1
  89. package/src/utils/zip.js +1 -1
  90. package/CHANGELOG.md +0 -1305
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -499,20 +499,30 @@ define([
499
499
  * Affine ratio of three collinear points a, b, c: (c - a) / (b - a).
500
500
  * If r > 1 or r < 0 then c is outside of the segment ab.
501
501
  *
502
- * @param {JXG.Coords} a
503
- * @param {JXG.Coords} b
504
- * @param {JXG.Coords} c
502
+ * @param {Array|JXG.Coords} a
503
+ * @param {Array|JXG.Coords} b
504
+ * @param {Array|JXG.Coords} c
505
505
  * @returns {Number} affine ratio (c - a) / (b - a)
506
506
  */
507
507
  affineRatio: function(a, b, c) {
508
- var r = 0.0,
509
- dx = b.usrCoords[1] - a.usrCoords[1];
508
+ var r = 0.0, dx;
509
+
510
+ if (Type.exists(a.usrCoords)) {
511
+ a = a.usrCoords;
512
+ }
513
+ if (Type.exists(b.usrCoords)) {
514
+ b = b.usrCoords;
515
+ }
516
+ if (Type.exists(c.usrCoords)) {
517
+ c = c.usrCoords;
518
+ }
519
+
520
+ dx = b[1] - a[1];
510
521
 
511
522
  if (Math.abs(dx) > Mat.eps) {
512
- r = (c.usrCoords[1] - a.usrCoords[1]) / dx;
523
+ r = (c[1] - a[1]) / dx;
513
524
  } else {
514
- r = (c.usrCoords[2] - a.usrCoords[2]) /
515
- (b.usrCoords[2] - a.usrCoords[2]);
525
+ r = (c[2] - a[2]) / (b[2] - a[2]);
516
526
  }
517
527
  return r;
518
528
  },
@@ -1062,8 +1072,10 @@ define([
1062
1072
  (el2.type === Const.OBJECT_TYPE_ARC || el2.type === Const.OBJECT_TYPE_SECTOR)
1063
1073
  ) ? true : false;
1064
1074
 
1065
- if (el1.elementClass === Const.OBJECT_CLASS_CURVE &&
1066
- el2.elementClass === Const.OBJECT_CLASS_CURVE && !(el1_isArcType && el2_isArcType) ) {
1075
+ if ((el1.elementClass === Const.OBJECT_CLASS_CURVE || el2.elementClass === Const.OBJECT_CLASS_CURVE) &&
1076
+ (el1.elementClass === Const.OBJECT_CLASS_CURVE || el1.elementClass === Const.OBJECT_CLASS_CIRCLE) &&
1077
+ (el2.elementClass === Const.OBJECT_CLASS_CURVE || el2.elementClass === Const.OBJECT_CLASS_CIRCLE) /*&&
1078
+ !(el1_isArcType && el2_isArcType)*/ ) {
1067
1079
  // curve - curve
1068
1080
  // with the exception that both elements are arc types
1069
1081
  /** @ignore */
@@ -1071,10 +1083,17 @@ define([
1071
1083
  return that.meetCurveCurve(el1, el2, i, j, el1.board);
1072
1084
  };
1073
1085
 
1074
- } else if ((el1.elementClass === Const.OBJECT_CLASS_CURVE &&
1075
- !el1_isArcType && el2.elementClass === Const.OBJECT_CLASS_LINE) ||
1076
- (el2.elementClass === Const.OBJECT_CLASS_CURVE &&
1077
- !el2_isArcType && el1.elementClass === Const.OBJECT_CLASS_LINE)) {
1086
+ } else if ((
1087
+ el1.elementClass === Const.OBJECT_CLASS_CURVE &&
1088
+ !el1_isArcType &&
1089
+ el2.elementClass === Const.OBJECT_CLASS_LINE
1090
+ ) ||
1091
+ (
1092
+ el2.elementClass === Const.OBJECT_CLASS_CURVE &&
1093
+ !el2_isArcType &&
1094
+ el1.elementClass === Const.OBJECT_CLASS_LINE
1095
+ )
1096
+ ) {
1078
1097
  // curve - line (this includes intersections between conic sections and lines)
1079
1098
  // with the exception that the curve is of arc type
1080
1099
  /** @ignore */
@@ -1123,16 +1142,16 @@ define([
1123
1142
  // All other combinations of circles and lines,
1124
1143
  // Arc types are treated as circles.
1125
1144
  /** @ignore */
1126
-
1127
1145
  func = function () {
1128
1146
  var res = that.meet(el1.stdform, el2.stdform, i, el1.board),
1129
- has = true, first, last, r, dx;
1147
+ has = true,
1148
+ first, last, r, dx;
1130
1149
 
1131
1150
  if (alwaysintersect) {
1132
1151
  return res;
1133
1152
  }
1134
1153
  if (el1.elementClass === Const.OBJECT_CLASS_LINE) {
1135
- first = Type.evaluate(el1.visProp.straightfirst),
1154
+ first = Type.evaluate(el1.visProp.straightfirst);
1136
1155
  last = Type.evaluate(el1.visProp.straightlast);
1137
1156
  if (!first || !last) {
1138
1157
  r = that.affineRatio(el1.point1.coords, el1.point2.coords, res);
@@ -1142,7 +1161,7 @@ define([
1142
1161
  }
1143
1162
  }
1144
1163
  if (el2.elementClass === Const.OBJECT_CLASS_LINE) {
1145
- first = Type.evaluate(el2.visProp.straightfirst),
1164
+ first = Type.evaluate(el2.visProp.straightfirst);
1146
1165
  last = Type.evaluate(el2.visProp.straightlast);
1147
1166
  if (!first || !last) {
1148
1167
  r = that.affineRatio(el2.point1.coords, el2.point2.coords, res);
@@ -1350,7 +1369,6 @@ define([
1350
1369
 
1351
1370
  return new Coords(Const.COORDS_BY_USER, [NaN, NaN], board);
1352
1371
  }
1353
-
1354
1372
  c = circ[0];
1355
1373
  b = circ.slice(1, 3);
1356
1374
  a = circ[3];
@@ -1442,7 +1460,7 @@ define([
1442
1460
  if (Type.exists(method) && method === 'newton') {
1443
1461
  co = Numerics.generalizedNewton(c1, c2, nr, t2ini);
1444
1462
  } else {
1445
- if (c1.bezierDegree === 3 && c2.bezierDegree === 3) {
1463
+ if (c1.bezierDegree === 3 || c2.bezierDegree === 3) {
1446
1464
  co = this.meetBezierCurveRedBlueSegments(c1, c2, nr);
1447
1465
  } else {
1448
1466
  co = this.meetCurveRedBlueSegments(c1, c2, nr);
@@ -1483,11 +1501,7 @@ define([
1483
1501
  li = el1;
1484
1502
  }
1485
1503
 
1486
- // if (Type.evaluate(cu.visProp.curvetype) === 'plot') {
1487
- v = this.meetCurveLineDiscrete(cu, li, nr, board, !alwaysIntersect);
1488
- // } else {
1489
- // v = this.meetCurveLineContinuous(cu, li, nr, board);
1490
- // }
1504
+ v = this.meetCurveLineDiscrete(cu, li, nr, board, !alwaysIntersect);
1491
1505
 
1492
1506
  return v;
1493
1507
  },
@@ -1566,80 +1580,6 @@ define([
1566
1580
  return (new Coords(Const.COORDS_BY_USER, [z, cu.X(t), cu.Y(t)], board));
1567
1581
  },
1568
1582
 
1569
- /**
1570
- * Intersection of line and curve, continuous case.
1571
- * Segments are treated as lines. Finding the nr-the intersection point
1572
- * works for nr=0,1 only.
1573
- *
1574
- * @private
1575
- * @deprecated
1576
- * @param {JXG.Curve} cu Curve
1577
- * @param {JXG.Line} li Line
1578
- * @param {Number} nr Will return the nr-th intersection point.
1579
- * @param {JXG.Board} board
1580
- *
1581
- * BUG: does not respect cu.minX() and cu.maxX()
1582
- */
1583
- meetCurveLineContinuousOld: function (cu, li, nr, board) {
1584
- var t, t2, i, func, z,
1585
- tnew, steps, delta, tstart, tend, cux, cuy,
1586
- eps = Mat.eps * 10;
1587
-
1588
- JXG.deprecated('Geometry.meetCurveLineContinuousOld()', 'Geometry.meetCurveLineContinuous()');
1589
- func = function (t) {
1590
- var v = li.stdform[0] + li.stdform[1] * cu.X(t) + li.stdform[2] * cu.Y(t);
1591
- return v * v;
1592
- };
1593
-
1594
- // Find some intersection point
1595
- if (this.meetCurveLineContinuous.t1memo) {
1596
- tstart = this.meetCurveLineContinuous.t1memo;
1597
- t = Numerics.root(func, tstart);
1598
- } else {
1599
- tstart = cu.minX();
1600
- tend = cu.maxX();
1601
- t = Numerics.root(func, [tstart, tend]);
1602
- }
1603
-
1604
- this.meetCurveLineContinuous.t1memo = t;
1605
- cux = cu.X(t);
1606
- cuy = cu.Y(t);
1607
-
1608
- // Find second intersection point
1609
- if (nr === 1) {
1610
- if (this.meetCurveLineContinuous.t2memo) {
1611
- tstart = this.meetCurveLineContinuous.t2memo;
1612
- }
1613
- t2 = Numerics.root(func, tstart);
1614
-
1615
- if (!(Math.abs(t2 - t) > 0.1 && Math.abs(cux - cu.X(t2)) > 0.1 && Math.abs(cuy - cu.Y(t2)) > 0.1)) {
1616
- steps = 20;
1617
- delta = (cu.maxX() - cu.minX()) / steps;
1618
- tnew = cu.minX();
1619
-
1620
- for (i = 0; i < steps; i++) {
1621
- t2 = Numerics.root(func, [tnew, tnew + delta]);
1622
-
1623
- if (Math.abs(func(t2)) <= eps && Math.abs(t2 - t) > 0.1 && Math.abs(cux - cu.X(t2)) > 0.1 && Math.abs(cuy - cu.Y(t2)) > 0.1) {
1624
- break;
1625
- }
1626
-
1627
- tnew += delta;
1628
- }
1629
- }
1630
- t = t2;
1631
- this.meetCurveLineContinuous.t2memo = t;
1632
- }
1633
-
1634
- // Is the point on the line?
1635
- if (Math.abs(func(t)) > eps) {
1636
- z = NaN;
1637
- } else {
1638
- z = 1.0;
1639
- }
1640
-
1641
- return (new Coords(Const.COORDS_BY_USER, [z, cu.X(t), cu.Y(t)], board));
1642
- },
1643
1583
 
1644
1584
  /**
1645
1585
  * Intersection of line and curve, discrete case.
@@ -1676,7 +1616,7 @@ define([
1676
1616
  }
1677
1617
 
1678
1618
  p2 = cu.points[0].usrCoords;
1679
- for (i = 1; i < len; i++) {
1619
+ for (i = 1; i < len; i += cu.bezierDegree) {
1680
1620
  p1 = p2.slice(0);
1681
1621
  p2 = cu.points[i].usrCoords;
1682
1622
  d = this.distance(p1, p2);
@@ -1693,8 +1633,6 @@ define([
1693
1633
  lip1.slice(1),
1694
1634
  lip2.slice(1)
1695
1635
  ], testSegment);
1696
-
1697
- i += 2;
1698
1636
  } else {
1699
1637
  res = [this.meetSegmentSegment(p1, p2, lip1, lip2)];
1700
1638
  }
@@ -1706,7 +1644,7 @@ define([
1706
1644
  /**
1707
1645
  * If the intersection point is not part of the segment,
1708
1646
  * this intersection point is set to non-existent.
1709
- * This prevents jumping of the intersection points.
1647
+ * This prevents jumping behavior of the intersection points.
1710
1648
  * But it may be discussed if it is the desired behavior.
1711
1649
  */
1712
1650
  if (testSegment &&
@@ -1791,13 +1729,13 @@ define([
1791
1729
  * @param {Array} q1 First point of segment 2 using normalized homogeneous coordinates [1,x,y]
1792
1730
  * @param {Array} q2 Second point or direction of segment 2 using normalized homogeneous coordinates [1,x,y] or point at infinity [0,x,y], respectively
1793
1731
  * @returns {Array} [Intersection point, t, u] The first entry contains the homogeneous coordinates
1794
- * of the intersection point. The second and third entry give the position of the intersection with respect
1732
+ * of the intersection point. The second and third entry give the position of the intersection with respect
1795
1733
  * to the definiting parameters. For example, the second entry t is defined by: intersection point = p1 + t * deltaP, where
1796
1734
  * deltaP = (p2 - p1) when both parameters are coordinates, and deltaP = p2 if p2 is a point at infinity.
1797
1735
  * If the two segments are collinear, [[0,0,0], Infinity, Infinity] is returned.
1798
1736
  **/
1799
1737
  meetSegmentSegment: function (p1, p2, q1, q2) {
1800
- var t, u, cx,
1738
+ var t, u, i, d,
1801
1739
  li1 = Mat.crossProduct(p1, p2),
1802
1740
  li2 = Mat.crossProduct(q1, q2),
1803
1741
  c = Mat.crossProduct(li1, li2);
@@ -1806,13 +1744,25 @@ define([
1806
1744
  return [c, Infinity, Infinity];
1807
1745
  }
1808
1746
 
1809
- // The intersection point is already computed in c. To find t and u, it suffices to solve
1810
- // for t in either x or y direction only. W.l.o.g. the x direction is chosen to compute both.
1811
- cx = c[1] / c[0];
1812
- // Note that the z-coordinate of p2 is used to determine whether it should be interpreted
1747
+ // Normalize the intersection coordinates
1748
+ c[1] /= c[0];
1749
+ c[2] /= c[0];
1750
+ c[0] /= c[0];
1751
+
1752
+ // Now compute in principle:
1753
+ // t = dist(c - p1) / dist(p2 - p1) and
1754
+ // u = dist(c - q1) / dist(q2 - q1)
1755
+ // However: the points q1, q2, p1, p2 might be ideal points - or in general - the
1756
+ // coordinates might be not normalized.
1757
+ // Note that the z-coordinates of p2 and q2 are used to determine whether it should be interpreted
1813
1758
  // as a segment coordinate or a direction.
1814
- t = (cx - p1[1]) / (p2[1] - p2[0] * p1[1]);
1815
- u = (cx - q1[1]) / (q2[1] - q2[0] * q1[1]);
1759
+ i = (Math.abs(p2[1] - p2[0] * p1[1]) < Mat.eps) ? 2 : 1;
1760
+ d = p1[i] / p1[0];
1761
+ t = (c[i] - d) / ( (p2[0] !== 0) ? (p2[i] / p2[0] - d) : p2[i] );
1762
+
1763
+ i = (Math.abs(q2[1] - q2[0] * q1[1]) < Mat.eps) ? 2 : 1;
1764
+ d = q1[i] / q1[0];
1765
+ u = (c[i] - d) / ( (q2[0] !== 0) ? (q2[i] / q2[0] - d) : q2[i] );
1816
1766
 
1817
1767
  return [c, t, u];
1818
1768
  },
@@ -2052,40 +2002,71 @@ define([
2052
2002
  * @returns {Array} The homogeneous coordinates of the nr-th intersection point.
2053
2003
  */
2054
2004
  meetBezierCurveRedBlueSegments: function (red, blue, nr) {
2055
- var p, i, j,
2005
+ var p, i, j, k, po,
2056
2006
  redArr, blueArr,
2057
- bbr, bbb,
2058
- lenBlue = blue.numberPoints, //points.length,
2059
- lenRed = red.numberPoints, // points.length,
2007
+ bbr, bbb, intersections,
2008
+ startRed = 0,
2009
+ startBlue = 0,
2010
+ lenBlue = blue.numberPoints,
2011
+ lenRed = red.numberPoints,
2060
2012
  L = [];
2061
2013
 
2062
- if (lenBlue < 4 || lenRed < 4) {
2014
+ if (lenBlue < blue.bezierDegree + 1 || lenRed < red.bezierDegree + 1) {
2063
2015
  return [0, NaN, NaN];
2064
2016
  }
2017
+ lenBlue -= blue.bezierDegree;
2018
+ lenRed -= red.bezierDegree;
2019
+
2020
+ // For sectors, we ignore the "legs"
2021
+ if (red.type === Const.OBJECT_TYPE_SECTOR) {
2022
+ startRed = 3;
2023
+ lenRed -= 3;
2024
+ }
2025
+ if (blue.type === Const.OBJECT_TYPE_SECTOR) {
2026
+ startBlue = 3;
2027
+ lenBlue -= 3;
2028
+ }
2065
2029
 
2066
- for (i = 0; i < lenRed - 3; i += 3) {
2030
+ for (i = startRed; i < lenRed; i += red.bezierDegree) {
2067
2031
  p = red.points;
2068
2032
  redArr = [
2069
- [p[i].usrCoords[1], p[i].usrCoords[2]],
2070
- [p[i + 1].usrCoords[1], p[i + 1].usrCoords[2]],
2071
- [p[i + 2].usrCoords[1], p[i + 2].usrCoords[2]],
2072
- [p[i + 3].usrCoords[1], p[i + 3].usrCoords[2]]
2033
+ p[i].usrCoords.slice(1),
2034
+ p[i + 1].usrCoords.slice(1)
2073
2035
  ];
2036
+ if (red.bezierDegree === 3) {
2037
+ redArr[2] = p[i + 2].usrCoords.slice(1);
2038
+ redArr[3] = p[i + 3].usrCoords.slice(1);
2039
+ }
2074
2040
 
2075
2041
  bbr = this._bezierBbox(redArr);
2076
2042
 
2077
- for (j = 0; j < lenBlue - 3; j += 3) {
2043
+ for (j = startBlue; j < lenBlue; j += blue.bezierDegree) {
2078
2044
  p = blue.points;
2079
2045
  blueArr = [
2080
- [p[j].usrCoords[1], p[j].usrCoords[2]],
2081
- [p[j + 1].usrCoords[1], p[j + 1].usrCoords[2]],
2082
- [p[j + 2].usrCoords[1], p[j + 2].usrCoords[2]],
2083
- [p[j + 3].usrCoords[1], p[j + 3].usrCoords[2]]
2046
+ p[j].usrCoords.slice(1),
2047
+ p[j + 1].usrCoords.slice(1)
2084
2048
  ];
2049
+ if (blue.bezierDegree === 3) {
2050
+ blueArr[2] = p[j + 2].usrCoords.slice(1);
2051
+ blueArr[3] = p[j + 3].usrCoords.slice(1);
2052
+ }
2085
2053
 
2086
2054
  bbb = this._bezierBbox(blueArr);
2087
2055
  if (this._bezierOverlap(bbr, bbb)) {
2088
- L = L.concat(this.meetBeziersegmentBeziersegment(redArr, blueArr));
2056
+ intersections = this.meetBeziersegmentBeziersegment(redArr, blueArr);
2057
+ if (intersections.length === 0) {
2058
+ continue;
2059
+ }
2060
+ for (k = 0; k < intersections.length; k++) {
2061
+ po = intersections[k];
2062
+ if (po[1] < -Mat.eps ||
2063
+ po[1] > 1 + Mat.eps ||
2064
+ po[2] < -Mat.eps ||
2065
+ po[2] > 1 + Mat.eps) {
2066
+ continue;
2067
+ }
2068
+ L.push(po);
2069
+ }
2089
2070
  if (L.length > nr) {
2090
2071
  return L[nr][0];
2091
2072
  }