jsxgraph 1.9.1 → 1.9.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.
- package/CHANGELOG.md +49 -0
- package/distrib/docs.zip +0 -0
- package/distrib/geogebra.min.js +2 -2
- package/distrib/geonext.min.js +2 -2
- package/distrib/intergeo.min.js +2 -2
- package/distrib/jsxgraph.css +1 -1
- package/distrib/jsxgraph.zip +0 -0
- package/distrib/jsxgraphcore.js +3 -3
- package/distrib/jsxgraphcore.mjs +3 -3
- package/distrib/jsxgraphcore.mjs.map +1 -1
- package/distrib/jsxgraphsrc.js +2328 -1508
- package/distrib/jsxgraphsrc.mjs +2328 -1508
- package/distrib/jsxgraphsrc.mjs.map +1 -1
- package/distrib/sketch.min.js +3 -3
- package/package.json +4 -4
- package/src/3d/box3d.js +4 -1
- package/src/3d/circle3d.js +10 -9
- package/src/3d/curve3d.js +2 -0
- package/src/3d/linspace3d.js +18 -55
- package/src/3d/point3d.js +6 -0
- package/src/3d/polygon3d.js +1 -0
- package/src/3d/sphere3d.js +47 -43
- package/src/3d/surface3d.js +1 -0
- package/src/3d/view3d.js +1504 -1067
- package/src/base/board.js +176 -55
- package/src/base/circle.js +3 -1
- package/src/base/constants.js +1 -1
- package/src/base/curve.js +1 -0
- package/src/base/element.js +38 -30
- package/src/base/line.js +93 -105
- package/src/base/polygon.js +1 -1
- package/src/base/text.js +5 -1
- package/src/element/button.js +62 -12
- package/src/element/checkbox.js +6 -2
- package/src/element/grid.js +6 -6
- package/src/element/input.js +9 -6
- package/src/element/slider.js +42 -39
- package/src/jsxgraph.js +5 -3
- package/src/math/geometry.js +86 -64
- package/src/math/math.js +47 -5
- package/src/options.js +45 -0
- package/src/options3d.js +82 -5
- package/src/parser/jessiecode.js +2 -1
- package/src/parser/prefix.js +8 -1
- package/src/reader/sketch.js +106 -0
- package/src/renderer/svg.js +16 -6
- package/src/utils/env.js +2 -2
- package/src/utils/type.js +27 -15
package/src/math/geometry.js
CHANGED
|
@@ -1569,7 +1569,7 @@ JXG.extend(
|
|
|
1569
1569
|
return func;
|
|
1570
1570
|
},
|
|
1571
1571
|
|
|
1572
|
-
otherIntersectionFunction: function(input, others, alwaysintersect, precision) {
|
|
1572
|
+
otherIntersectionFunction: function (input, others, alwaysintersect, precision) {
|
|
1573
1573
|
var func, board,
|
|
1574
1574
|
el1, el2,
|
|
1575
1575
|
that = this;
|
|
@@ -1577,22 +1577,22 @@ JXG.extend(
|
|
|
1577
1577
|
el1 = input[0];
|
|
1578
1578
|
el2 = input[1];
|
|
1579
1579
|
board = el1.board;
|
|
1580
|
-
func = function() {
|
|
1580
|
+
func = function () {
|
|
1581
1581
|
var i, k, c, d,
|
|
1582
1582
|
isClose,
|
|
1583
1583
|
le = others.length,
|
|
1584
1584
|
eps = Type.evaluate(precision);
|
|
1585
1585
|
|
|
1586
1586
|
for (i = le; i >= 0; i--) {
|
|
1587
|
-
if (el1.elementClass ===
|
|
1587
|
+
if (el1.elementClass === Const.OBJECT_CLASS_CIRCLE &&
|
|
1588
1588
|
[Const.OBJECT_CLASS_CIRCLE, Const.OBJECT_CLASS_LINE].indexOf(el2.elementClass) >= 0) {
|
|
1589
1589
|
// circle, circle|line
|
|
1590
1590
|
c = that.meet(el1.stdform, el2.stdform, i, board);
|
|
1591
|
-
} else if (el1.elementClass ===
|
|
1591
|
+
} else if (el1.elementClass === Const.OBJECT_CLASS_CURVE &&
|
|
1592
1592
|
[Const.OBJECT_CLASS_CURVE, Const.OBJECT_CLASS_CIRCLE].indexOf(el2.elementClass) >= 0) {
|
|
1593
1593
|
// curve, circle|curve
|
|
1594
1594
|
c = that.meetCurveCurve(el1, el2, i, 0, board, 'segment');
|
|
1595
|
-
} else if (el1.elementClass ===
|
|
1595
|
+
} else if (el1.elementClass === Const.OBJECT_CLASS_CURVE && el2.elementClass === Const.OBJECT_CLASS_LINE) {
|
|
1596
1596
|
// curve, line
|
|
1597
1597
|
if (Type.exists(el1.dataX)) {
|
|
1598
1598
|
c = JXG.Math.Geometry.meetCurveLine(el1, el2, i, el1.board, Type.evaluate(alwaysintersect));
|
|
@@ -1608,7 +1608,7 @@ JXG.extend(
|
|
|
1608
1608
|
d = c.distance(JXG.COORDS_BY_USER, others[k].coords);
|
|
1609
1609
|
if (d < eps) {
|
|
1610
1610
|
isClose = true;
|
|
1611
|
-
|
|
1611
|
+
}
|
|
1612
1612
|
}
|
|
1613
1613
|
if (!isClose) {
|
|
1614
1614
|
// We are done, the intersection is away from any other
|
|
@@ -2375,7 +2375,7 @@ JXG.extend(
|
|
|
2375
2375
|
meetPlaneSphere: function (el1, el2) {
|
|
2376
2376
|
var dis = function () {
|
|
2377
2377
|
return (
|
|
2378
|
-
|
|
2378
|
+
el1.normal[0] * el2.center.X()
|
|
2379
2379
|
+ el1.normal[1] * el2.center.Y()
|
|
2380
2380
|
+ el1.normal[2] * el2.center.Z()
|
|
2381
2381
|
- el1.d
|
|
@@ -2385,13 +2385,13 @@ JXG.extend(
|
|
|
2385
2385
|
[
|
|
2386
2386
|
// Center
|
|
2387
2387
|
function () {
|
|
2388
|
-
return el2.center.X() - dis()*el1.normal[0];
|
|
2388
|
+
return el2.center.X() - dis() * el1.normal[0];
|
|
2389
2389
|
},
|
|
2390
2390
|
function () {
|
|
2391
|
-
return el2.center.Y() - dis()*el1.normal[1];
|
|
2391
|
+
return el2.center.Y() - dis() * el1.normal[1];
|
|
2392
2392
|
},
|
|
2393
2393
|
function () {
|
|
2394
|
-
return el2.center.Z() - dis()*el1.normal[2];
|
|
2394
|
+
return el2.center.Z() - dis() * el1.normal[2];
|
|
2395
2395
|
}
|
|
2396
2396
|
],
|
|
2397
2397
|
[
|
|
@@ -2402,34 +2402,34 @@ JXG.extend(
|
|
|
2402
2402
|
],
|
|
2403
2403
|
function () {
|
|
2404
2404
|
// Radius (returns NaN if spheres don't touch)
|
|
2405
|
-
|
|
2405
|
+
var r = el2.Radius(),
|
|
2406
2406
|
s = dis();
|
|
2407
|
-
return Math.sqrt(r*r - s*s);
|
|
2407
|
+
return Math.sqrt(r * r - s * s);
|
|
2408
2408
|
}
|
|
2409
2409
|
];
|
|
2410
2410
|
},
|
|
2411
2411
|
|
|
2412
2412
|
meetSphereSphere: function (el1, el2) {
|
|
2413
2413
|
var skew = function () {
|
|
2414
|
-
|
|
2414
|
+
var dist = el1.center.distance(el2.center),
|
|
2415
2415
|
r1 = el1.Radius(),
|
|
2416
2416
|
r2 = el2.Radius();
|
|
2417
|
-
return (r1 - r2)*(r1 + r2) / (dist*dist);
|
|
2417
|
+
return (r1 - r2) * (r1 + r2) / (dist * dist);
|
|
2418
2418
|
};
|
|
2419
2419
|
return [
|
|
2420
2420
|
[
|
|
2421
2421
|
// Center
|
|
2422
2422
|
function () {
|
|
2423
|
-
|
|
2424
|
-
return 0.5*((1-s)*el1.center.X() + (1+s)*el2.center.X());
|
|
2423
|
+
var s = skew();
|
|
2424
|
+
return 0.5 * ((1 - s) * el1.center.X() + (1 + s) * el2.center.X());
|
|
2425
2425
|
},
|
|
2426
2426
|
function () {
|
|
2427
|
-
|
|
2428
|
-
return 0.5*((1-s)*el1.center.Y() + (1+s)*el2.center.Y());
|
|
2427
|
+
var s = skew();
|
|
2428
|
+
return 0.5 * ((1 - s) * el1.center.Y() + (1 + s) * el2.center.Y());
|
|
2429
2429
|
},
|
|
2430
2430
|
function () {
|
|
2431
|
-
|
|
2432
|
-
return 0.5*((1-s)*el1.center.Z() + (1+s)*el2.center.Z());
|
|
2431
|
+
var s = skew();
|
|
2432
|
+
return 0.5 * ((1 - s) * el1.center.Z() + (1 + s) * el2.center.Z());
|
|
2433
2433
|
}
|
|
2434
2434
|
],
|
|
2435
2435
|
[
|
|
@@ -2440,11 +2440,11 @@ JXG.extend(
|
|
|
2440
2440
|
],
|
|
2441
2441
|
function () {
|
|
2442
2442
|
// Radius (returns NaN if spheres don't touch)
|
|
2443
|
-
|
|
2443
|
+
var dist = el1.center.distance(el2.center),
|
|
2444
2444
|
r1 = el1.Radius(),
|
|
2445
2445
|
r2 = el2.Radius(),
|
|
2446
2446
|
s = skew(),
|
|
2447
|
-
rIxnSq = 0.5*(r1*r1 + r2*r2 - 0.5*dist*dist*(1 + s*s));
|
|
2447
|
+
rIxnSq = 0.5 * (r1 * r1 + r2 * r2 - 0.5 * dist * dist * (1 + s * s));
|
|
2448
2448
|
return Math.sqrt(rIxnSq);
|
|
2449
2449
|
}
|
|
2450
2450
|
];
|
|
@@ -2854,28 +2854,19 @@ JXG.extend(
|
|
|
2854
2854
|
* @param {Number} sgn Wither 1 or -1. Needed for minor and major arcs. In case of doubt, use 1.
|
|
2855
2855
|
*/
|
|
2856
2856
|
bezierArc: function (A, B, C, withLegs, sgn) {
|
|
2857
|
-
var p1,
|
|
2858
|
-
p2,
|
|
2859
|
-
p3,
|
|
2860
|
-
p4,
|
|
2857
|
+
var p1, p2, p3, p4,
|
|
2861
2858
|
r,
|
|
2862
|
-
phi,
|
|
2863
|
-
|
|
2864
|
-
PI2 = Math.PI * 0.5,
|
|
2859
|
+
phi, beta, delta,
|
|
2860
|
+
// PI2 = Math.PI * 0.5,
|
|
2865
2861
|
x = B[1],
|
|
2866
2862
|
y = B[2],
|
|
2867
2863
|
z = B[0],
|
|
2868
2864
|
dataX = [],
|
|
2869
2865
|
dataY = [],
|
|
2870
|
-
co,
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
bx,
|
|
2875
|
-
by,
|
|
2876
|
-
k,
|
|
2877
|
-
v,
|
|
2878
|
-
d,
|
|
2866
|
+
co, si,
|
|
2867
|
+
ax, ay,
|
|
2868
|
+
bx, by,
|
|
2869
|
+
k, v, d,
|
|
2879
2870
|
matrix;
|
|
2880
2871
|
|
|
2881
2872
|
r = this.distance(B, A);
|
|
@@ -2889,6 +2880,12 @@ JXG.extend(
|
|
|
2889
2880
|
phi = 2 * Math.PI - phi;
|
|
2890
2881
|
}
|
|
2891
2882
|
|
|
2883
|
+
// Always divide the arc into four Bezier arcs.
|
|
2884
|
+
// Otherwise, the position of gliders on this arc
|
|
2885
|
+
// will be wrong.
|
|
2886
|
+
delta = phi / 4;
|
|
2887
|
+
|
|
2888
|
+
|
|
2892
2889
|
p1 = A;
|
|
2893
2890
|
p1[1] /= p1[0];
|
|
2894
2891
|
p1[2] /= p1[0];
|
|
@@ -2905,9 +2902,16 @@ JXG.extend(
|
|
|
2905
2902
|
}
|
|
2906
2903
|
|
|
2907
2904
|
while (phi > Mat.eps) {
|
|
2908
|
-
if (phi > PI2) {
|
|
2909
|
-
|
|
2910
|
-
|
|
2905
|
+
// if (phi > PI2) {
|
|
2906
|
+
// beta = PI2;
|
|
2907
|
+
// phi -= PI2;
|
|
2908
|
+
// } else {
|
|
2909
|
+
// beta = phi;
|
|
2910
|
+
// phi = 0;
|
|
2911
|
+
// }
|
|
2912
|
+
if (phi > delta) {
|
|
2913
|
+
beta = delta;
|
|
2914
|
+
phi -= delta;
|
|
2911
2915
|
} else {
|
|
2912
2916
|
beta = phi;
|
|
2913
2917
|
phi = 0;
|
|
@@ -3112,8 +3116,13 @@ JXG.extend(
|
|
|
3112
3116
|
|
|
3113
3117
|
var x = point.X(),
|
|
3114
3118
|
y = point.Y(),
|
|
3115
|
-
t = point.position
|
|
3116
|
-
result
|
|
3119
|
+
t = point.position,
|
|
3120
|
+
result;
|
|
3121
|
+
|
|
3122
|
+
if (!Type.exists(t)) {
|
|
3123
|
+
t = Type.evaluate(curve.visProp.curvetype) === 'functiongraph' ? x : 0.0;
|
|
3124
|
+
}
|
|
3125
|
+
result = this.projectCoordsToCurve(x, y, t, curve, board);
|
|
3117
3126
|
|
|
3118
3127
|
// point.position = result[1];
|
|
3119
3128
|
|
|
@@ -3202,6 +3211,21 @@ JXG.extend(
|
|
|
3202
3211
|
newCoordsObj = new Coords(Const.COORDS_BY_USER, newCoords, board);
|
|
3203
3212
|
} else {
|
|
3204
3213
|
// 'parameter', 'polar', 'functiongraph'
|
|
3214
|
+
|
|
3215
|
+
if (Type.evaluate(curve.visProp.curvetype) === 'functiongraph') {
|
|
3216
|
+
let dy = Math.abs(y - curve.Y(x));
|
|
3217
|
+
if (!isNaN(dy)) {
|
|
3218
|
+
minX = x - dy;
|
|
3219
|
+
maxX = x + dy;
|
|
3220
|
+
} else {
|
|
3221
|
+
minX = curve.minX();
|
|
3222
|
+
maxX = curve.maxX();
|
|
3223
|
+
}
|
|
3224
|
+
} else {
|
|
3225
|
+
minX = curve.minX();
|
|
3226
|
+
maxX = curve.maxX();
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3205
3229
|
/** @ignore */
|
|
3206
3230
|
minfunc = function (t) {
|
|
3207
3231
|
var dx, dy;
|
|
@@ -3215,8 +3239,6 @@ JXG.extend(
|
|
|
3215
3239
|
|
|
3216
3240
|
f_old = minfunc(t);
|
|
3217
3241
|
steps = 50;
|
|
3218
|
-
minX = curve.minX();
|
|
3219
|
-
maxX = curve.maxX();
|
|
3220
3242
|
|
|
3221
3243
|
delta = (maxX - minX) / steps;
|
|
3222
3244
|
t_new = minX;
|
|
@@ -3454,9 +3476,9 @@ JXG.extend(
|
|
|
3454
3476
|
|
|
3455
3477
|
// adapt simplex size to parameter range
|
|
3456
3478
|
if (dim === 1) {
|
|
3457
|
-
rhobeg = 0.1*(target.range[1] - target.range[0]);
|
|
3479
|
+
rhobeg = 0.1 * (target.range[1] - target.range[0]);
|
|
3458
3480
|
} else if (dim === 2) {
|
|
3459
|
-
rhobeg = 0.1*Math.min(
|
|
3481
|
+
rhobeg = 0.1 * Math.min(
|
|
3460
3482
|
target.range_u[1] - target.range_u[0],
|
|
3461
3483
|
target.range_v[1] - target.range_v[0]
|
|
3462
3484
|
);
|
|
@@ -3473,17 +3495,17 @@ JXG.extend(
|
|
|
3473
3495
|
zDiff = p[2] - target.Z.apply(null, w);
|
|
3474
3496
|
|
|
3475
3497
|
if (n === 1) {
|
|
3476
|
-
con[0] =
|
|
3498
|
+
con[0] = w[0] - target.range[0];
|
|
3477
3499
|
con[1] = -w[0] + target.range[1];
|
|
3478
3500
|
} else if (n === 2) {
|
|
3479
|
-
con[0] =
|
|
3501
|
+
con[0] = w[0] - target.range_u[0];
|
|
3480
3502
|
con[1] = -w[0] + target.range_u[1];
|
|
3481
|
-
con[2] =
|
|
3503
|
+
con[2] = w[1] - target.range_v[0];
|
|
3482
3504
|
con[3] = -w[1] + target.range_v[1];
|
|
3483
3505
|
}
|
|
3484
|
-
return xDiff*xDiff + yDiff*yDiff + zDiff*zDiff;
|
|
3506
|
+
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff;
|
|
3485
3507
|
};
|
|
3486
|
-
Mat.Nlp.FindMinimum(_minFunc, dim, 2*dim, params, rhobeg, rhoend, iprint, maxfun);
|
|
3508
|
+
Mat.Nlp.FindMinimum(_minFunc, dim, 2 * dim, params, rhobeg, rhoend, iprint, maxfun);
|
|
3487
3509
|
|
|
3488
3510
|
// return [1, target.X(...params), target.Y(...params), target.Z(...params)];
|
|
3489
3511
|
return [1, target.X.apply(null, params), target.Y.apply(null, params), target.Z.apply(null, params)];
|
|
@@ -3511,9 +3533,9 @@ JXG.extend(
|
|
|
3511
3533
|
|
|
3512
3534
|
// adapt simplex size to parameter range
|
|
3513
3535
|
if (dim === 1) {
|
|
3514
|
-
rhobeg = 0.1*(target.range[1] - target.range[0]);
|
|
3536
|
+
rhobeg = 0.1 * (target.range[1] - target.range[0]);
|
|
3515
3537
|
} else if (dim === 2) {
|
|
3516
|
-
rhobeg = 0.1*Math.min(
|
|
3538
|
+
rhobeg = 0.1 * Math.min(
|
|
3517
3539
|
target.range_u[1] - target.range_u[0],
|
|
3518
3540
|
target.range_v[1] - target.range_v[0]
|
|
3519
3541
|
);
|
|
@@ -3529,27 +3551,27 @@ JXG.extend(
|
|
|
3529
3551
|
// target.Z(...w)
|
|
3530
3552
|
// ],
|
|
3531
3553
|
var c3d = [
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3554
|
+
1,
|
|
3555
|
+
target.X.apply(null, w),
|
|
3556
|
+
target.Y.apply(null, w),
|
|
3557
|
+
target.Z.apply(null, w)
|
|
3558
|
+
],
|
|
3537
3559
|
c2d = target.view.project3DTo2D(c3d),
|
|
3538
3560
|
xDiff = pScr[0] - c2d[1],
|
|
3539
3561
|
yDiff = pScr[1] - c2d[2];
|
|
3540
3562
|
|
|
3541
3563
|
if (n === 1) {
|
|
3542
|
-
con[0] =
|
|
3564
|
+
con[0] = w[0] - target.range[0];
|
|
3543
3565
|
con[1] = -w[0] + target.range[1];
|
|
3544
3566
|
} else if (n === 2) {
|
|
3545
|
-
con[0] =
|
|
3567
|
+
con[0] = w[0] - target.range_u[0];
|
|
3546
3568
|
con[1] = -w[0] + target.range_u[1];
|
|
3547
|
-
con[2] =
|
|
3569
|
+
con[2] = w[1] - target.range_v[0];
|
|
3548
3570
|
con[3] = -w[1] + target.range_v[1];
|
|
3549
3571
|
}
|
|
3550
|
-
return xDiff*xDiff + yDiff*yDiff;
|
|
3572
|
+
return xDiff * xDiff + yDiff * yDiff;
|
|
3551
3573
|
};
|
|
3552
|
-
Mat.Nlp.FindMinimum(_minFunc, dim, 2*dim, params, rhobeg, rhoend, iprint, maxfun);
|
|
3574
|
+
Mat.Nlp.FindMinimum(_minFunc, dim, 2 * dim, params, rhobeg, rhoend, iprint, maxfun);
|
|
3553
3575
|
|
|
3554
3576
|
// return [1, target.X(...params), target.Y(...params), target.Z(...params)];
|
|
3555
3577
|
return [1, target.X.apply(null, params), target.Y.apply(null, params), target.Z.apply(null, params)];
|
package/src/math/math.js
CHANGED
|
@@ -109,6 +109,48 @@ JXG.Math = {
|
|
|
109
109
|
return a - Math.floor(a / m) * m;
|
|
110
110
|
},
|
|
111
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Translate <code>x</code> into the interval <code>[a, b)</code> by adding
|
|
114
|
+
* a multiple of <code>b - a</code>.
|
|
115
|
+
* @param {Number} x
|
|
116
|
+
* @param {Number} a
|
|
117
|
+
* @param {Number} b
|
|
118
|
+
*/
|
|
119
|
+
wrap: function (x, a, b) {
|
|
120
|
+
return a + this.mod(x - a, b - a);
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Clamp <code>x</code> within the interval <code>[a, b]</code>. If
|
|
125
|
+
* <code>x</code> is below <code>a</code>, increase it to <code>a</code>. If
|
|
126
|
+
* it's above <code>b</code>, decrease it to <code>b</code>.
|
|
127
|
+
*/
|
|
128
|
+
clamp: function (x, a, b) {
|
|
129
|
+
return Math.min(Math.max(x, a), b);
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* A way of clamping a periodic variable. If <code>x</code> is congruent mod
|
|
134
|
+
* <code>period</code> to a point in <code>[a, b]</code>, return that point.
|
|
135
|
+
* Otherwise, wrap it into <code>[mid - period/2, mid + period/2]</code>,
|
|
136
|
+
* where <code>mid</code> is the mean of <code>a</code> and <code>b</code>,
|
|
137
|
+
* and then clamp it to <code>[a, b]</code> from there.
|
|
138
|
+
*/
|
|
139
|
+
wrapAndClamp: function (x, a, b, period) {
|
|
140
|
+
var mid = 0.5 * (a + b),
|
|
141
|
+
half_period = 0.5 * period;
|
|
142
|
+
|
|
143
|
+
return this.clamp(
|
|
144
|
+
this.wrap(
|
|
145
|
+
x,
|
|
146
|
+
mid - half_period,
|
|
147
|
+
mid + half_period
|
|
148
|
+
),
|
|
149
|
+
a,
|
|
150
|
+
b
|
|
151
|
+
);
|
|
152
|
+
},
|
|
153
|
+
|
|
112
154
|
/**
|
|
113
155
|
* Initializes a vector of size <tt>n</tt> wih coefficients set to the init value (default 0)
|
|
114
156
|
* @param {Number} n Length of the vector
|
|
@@ -882,7 +924,7 @@ JXG.Math = {
|
|
|
882
924
|
|
|
883
925
|
minOr0 = min || 0;
|
|
884
926
|
|
|
885
|
-
if (
|
|
927
|
+
if (JXG.exists(step)) {
|
|
886
928
|
tmp = (n - minOr0) / step;
|
|
887
929
|
if (Number.isInteger(tmp)) {
|
|
888
930
|
return n;
|
|
@@ -968,7 +1010,7 @@ JXG.Math = {
|
|
|
968
1010
|
* @param {Number} a Variable number of arguments.
|
|
969
1011
|
* @returns Number
|
|
970
1012
|
*/
|
|
971
|
-
hypot: function() {
|
|
1013
|
+
hypot: function () {
|
|
972
1014
|
var i, le, a, sum;
|
|
973
1015
|
|
|
974
1016
|
le = arguments.length;
|
|
@@ -985,7 +1027,7 @@ JXG.Math = {
|
|
|
985
1027
|
* @param {Number} x
|
|
986
1028
|
* @returns Number
|
|
987
1029
|
*/
|
|
988
|
-
hstep: function(x) {
|
|
1030
|
+
hstep: function (x) {
|
|
989
1031
|
return (x > 0.0) ? 1 :
|
|
990
1032
|
((x < 0.0) ? 0.0 : 0.5);
|
|
991
1033
|
},
|
|
@@ -997,7 +1039,7 @@ JXG.Math = {
|
|
|
997
1039
|
* @param {Number} z
|
|
998
1040
|
* @returns Number
|
|
999
1041
|
*/
|
|
1000
|
-
gamma: function(z) {
|
|
1042
|
+
gamma: function (z) {
|
|
1001
1043
|
var x, y, t, i, le,
|
|
1002
1044
|
g = 7,
|
|
1003
1045
|
// n = 9,
|
|
@@ -1164,7 +1206,7 @@ JXG.Math = {
|
|
|
1164
1206
|
* JXG.Math.decToFraction(-10.66666666666667);
|
|
1165
1207
|
* // Result: [-1, 10, 2, 3 ]
|
|
1166
1208
|
*/
|
|
1167
|
-
decToFraction: function(x, order) {
|
|
1209
|
+
decToFraction: function (x, order) {
|
|
1168
1210
|
var lead, sign, a,
|
|
1169
1211
|
n, n1, n2,
|
|
1170
1212
|
d, d1, d2,
|
package/src/options.js
CHANGED
|
@@ -2054,6 +2054,50 @@ JXG.Options = {
|
|
|
2054
2054
|
*/
|
|
2055
2055
|
needsRegularUpdate: true,
|
|
2056
2056
|
|
|
2057
|
+
/**
|
|
2058
|
+
* If some size of an element is controlled by a function, like the circle radius
|
|
2059
|
+
* or segments of fixed length, this attribute controls what happens if the value
|
|
2060
|
+
* is negative. By default, the absolute value is taken. If true, the maximum
|
|
2061
|
+
* of 0 and the value is used.
|
|
2062
|
+
*
|
|
2063
|
+
* @type Boolean
|
|
2064
|
+
* @default false
|
|
2065
|
+
* @name JXG.GeometryElement#nonnegativeOnly
|
|
2066
|
+
* @example
|
|
2067
|
+
* var slider = board.create('slider', [[4, -3], [4, 3], [-4, 1, 4]], { name: 'a'});
|
|
2068
|
+
* var circle = board.create('circle', [[-1, 0], 1], {
|
|
2069
|
+
* nonnegativeOnly: true
|
|
2070
|
+
* });
|
|
2071
|
+
* circle.setRadius('a'); // Use JessieCode
|
|
2072
|
+
* var seg = board.create('segment', [[-4, 3], [0, 3], () => slider.Value()], {
|
|
2073
|
+
* point1: {visible: true},
|
|
2074
|
+
* point2: {visible: true},
|
|
2075
|
+
* nonnegativeOnly: true
|
|
2076
|
+
* });
|
|
2077
|
+
*
|
|
2078
|
+
* </pre><div id="JXG9cb76224-1f78-4488-b20f-800788768bc9" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
2079
|
+
* <script type="text/javascript">
|
|
2080
|
+
* (function() {
|
|
2081
|
+
* var board = JXG.JSXGraph.initBoard('JXG9cb76224-1f78-4488-b20f-800788768bc9',
|
|
2082
|
+
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
2083
|
+
* var slider = board.create('slider', [[4, -3], [4, 3], [-4, 1, 4]], { name: 'a'});
|
|
2084
|
+
* var circle = board.create('circle', [[-1, 0], 1], {
|
|
2085
|
+
* nonnegativeOnly: true
|
|
2086
|
+
* });
|
|
2087
|
+
* circle.setRadius('a'); // Use JessieCode
|
|
2088
|
+
* var seg = board.create('segment', [[-4, 3], [0, 3], () => slider.Value()], {
|
|
2089
|
+
* point1: {visible: true},
|
|
2090
|
+
* point2: {visible: true},
|
|
2091
|
+
* nonnegativeOnly: true
|
|
2092
|
+
* });
|
|
2093
|
+
*
|
|
2094
|
+
* })();
|
|
2095
|
+
*
|
|
2096
|
+
* </script><pre>
|
|
2097
|
+
*
|
|
2098
|
+
*/
|
|
2099
|
+
nonnegativeOnly: false,
|
|
2100
|
+
|
|
2057
2101
|
/**
|
|
2058
2102
|
* Precision options for JSXGraph elements.
|
|
2059
2103
|
* This attributes takes either the value 'inherit' or an object of the form:
|
|
@@ -4410,6 +4454,7 @@ JXG.Options = {
|
|
|
4410
4454
|
label: {
|
|
4411
4455
|
position: 'urt'
|
|
4412
4456
|
}
|
|
4457
|
+
|
|
4413
4458
|
/**#@-*/
|
|
4414
4459
|
},
|
|
4415
4460
|
|
package/src/options3d.js
CHANGED
|
@@ -31,7 +31,7 @@ JXG.extend(Options, {
|
|
|
31
31
|
* @type Line3D
|
|
32
32
|
* @name View3D#xAxis
|
|
33
33
|
*/
|
|
34
|
-
xAxis: { visible: true, point2: { name: "x" } },
|
|
34
|
+
xAxis: { visible: true, point2: { name: "x" }, strokeColor: JXG.palette.red },
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Attributes of the 3D y-axis.
|
|
@@ -39,7 +39,7 @@ JXG.extend(Options, {
|
|
|
39
39
|
* @type Line3D
|
|
40
40
|
* @name View3D#yAxis
|
|
41
41
|
*/
|
|
42
|
-
yAxis: { visible: true, point2: { name: "y" } },
|
|
42
|
+
yAxis: { visible: true, point2: { name: "y" }, strokeColor: JXG.palette.green },
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Attributes of the 3D z-axis.
|
|
@@ -47,7 +47,7 @@ JXG.extend(Options, {
|
|
|
47
47
|
* @type Line3D
|
|
48
48
|
* @name View3D#zAxis
|
|
49
49
|
*/
|
|
50
|
-
zAxis: { visible: true, point2: { name: "z" } },
|
|
50
|
+
zAxis: { visible: true, point2: { name: "z" }, strokeColor: JXG.palette.blue },
|
|
51
51
|
|
|
52
52
|
// Planes
|
|
53
53
|
/**
|
|
@@ -492,7 +492,7 @@ JXG.extend(Options, {
|
|
|
492
492
|
},
|
|
493
493
|
continuous: true,
|
|
494
494
|
slider: {
|
|
495
|
-
visible:
|
|
495
|
+
visible: 'inherit',
|
|
496
496
|
style: 6,
|
|
497
497
|
point1: { frozen: true },
|
|
498
498
|
point2: { frozen: true },
|
|
@@ -560,7 +560,7 @@ JXG.extend(Options, {
|
|
|
560
560
|
},
|
|
561
561
|
continuous: true,
|
|
562
562
|
slider: {
|
|
563
|
-
visible:
|
|
563
|
+
visible: 'inherit',
|
|
564
564
|
style: 6,
|
|
565
565
|
point1: { frozen: true },
|
|
566
566
|
point2: { frozen: true },
|
|
@@ -570,6 +570,74 @@ JXG.extend(Options, {
|
|
|
570
570
|
}
|
|
571
571
|
},
|
|
572
572
|
|
|
573
|
+
/**
|
|
574
|
+
* Specify the user handling of the bank angle.
|
|
575
|
+
* <ul>
|
|
576
|
+
* <li><tt>pointer</tt> sub-attributes:
|
|
577
|
+
* <ul>
|
|
578
|
+
* <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by elevation.
|
|
579
|
+
* <li><tt>speed</tt>: Number indicating how many passes the range of the el_slider makes when the cursor crosses the entire board once in the horizontal direction.
|
|
580
|
+
* <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.
|
|
581
|
+
* <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)
|
|
582
|
+
* <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
|
|
583
|
+
* </ul>
|
|
584
|
+
* <li><tt>keyboard</tt> sub-attributes:
|
|
585
|
+
* <ul>
|
|
586
|
+
* <li><tt>enabled</tt>: Boolean that specifies whether the keyboard (arrow keys) can be used to navigate the board.
|
|
587
|
+
* <li><tt>step</tt>: Size of the step per keystroke.
|
|
588
|
+
* <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
|
|
589
|
+
* </ul>
|
|
590
|
+
* <li><tt>continuous</tt>: Boolean that specifies whether the el_slider starts again from the beginning when its end is reached.
|
|
591
|
+
* <li><tt>slider</tt> attributes of the el_slider ({@link Slider}) with additional
|
|
592
|
+
* <ul>
|
|
593
|
+
* <li><tt>min</tt>: Minimum value.
|
|
594
|
+
* <li><tt>max</tt>: Maximum value.
|
|
595
|
+
* <li><tt>start</tt>: Start value.
|
|
596
|
+
* </ul>
|
|
597
|
+
* </ul>
|
|
598
|
+
*
|
|
599
|
+
* @name View3D#bank
|
|
600
|
+
* @type Object
|
|
601
|
+
* @default <pre>{
|
|
602
|
+
* pointer: {enabled: true, speed: 1, outside: true, button: -1, key: 'none'},
|
|
603
|
+
* keyboard: {enabled: true, step: 10, key: 'ctrl'},
|
|
604
|
+
* continuous: true,
|
|
605
|
+
* slider: {
|
|
606
|
+
* visible: true,
|
|
607
|
+
* style: 6,
|
|
608
|
+
* point1: {frozen: true},
|
|
609
|
+
* point2: {frozen: true},
|
|
610
|
+
* min: 0,
|
|
611
|
+
* max: 2 * Math.PI,
|
|
612
|
+
* start: 0.3
|
|
613
|
+
* },
|
|
614
|
+
* }<pre>
|
|
615
|
+
*/
|
|
616
|
+
bank: {
|
|
617
|
+
pointer: {
|
|
618
|
+
enabled: true,
|
|
619
|
+
speed: 0.08,
|
|
620
|
+
outside: true,
|
|
621
|
+
button: -1,
|
|
622
|
+
key: 'none'
|
|
623
|
+
},
|
|
624
|
+
keyboard: {
|
|
625
|
+
enabled: true,
|
|
626
|
+
step: 10,
|
|
627
|
+
key: 'ctrl'
|
|
628
|
+
},
|
|
629
|
+
continuous: true,
|
|
630
|
+
slider: {
|
|
631
|
+
visible: 'inherit',
|
|
632
|
+
style: 6,
|
|
633
|
+
point1: { frozen: true },
|
|
634
|
+
point2: { frozen: true },
|
|
635
|
+
min: -Math.PI,
|
|
636
|
+
max: Math.PI,
|
|
637
|
+
start: 0.0
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
|
|
573
641
|
trackball: {
|
|
574
642
|
enabled: false,
|
|
575
643
|
outside: true,
|
|
@@ -594,6 +662,15 @@ JXG.extend(Options, {
|
|
|
594
662
|
*/
|
|
595
663
|
fov: 1 / 5 * 2 * Math.PI,
|
|
596
664
|
|
|
665
|
+
/**
|
|
666
|
+
* When this option is enabled, points closer to the screen are drawn
|
|
667
|
+
* over points further from the screen within each layer.
|
|
668
|
+
*
|
|
669
|
+
* @name View3D#depthOrderPoints
|
|
670
|
+
* @default false
|
|
671
|
+
*/
|
|
672
|
+
depthOrderPoints: false,
|
|
673
|
+
|
|
597
674
|
/**
|
|
598
675
|
* Fixed values for the view, which can be changed using keyboard keys `picture-up` and `picture-down`.
|
|
599
676
|
* Array of the form: [[el0, az0, r0], [el1, az1, r1, ...[eln, azn, rn]]
|
package/src/parser/jessiecode.js
CHANGED
|
@@ -1110,7 +1110,8 @@ JXG.extend(JXG.JessieCode.prototype, /** @lends JXG.JessieCode.prototype */ {
|
|
|
1110
1110
|
|
|
1111
1111
|
// The $()-function-calls are special because their parameter is given as a string, not as a node_var.
|
|
1112
1112
|
if (node.type === 'node_op' && node.value === 'op_execfun' &&
|
|
1113
|
-
node.children.length > 1 &&
|
|
1113
|
+
node.children.length > 1 &&
|
|
1114
|
+
(node.children[0].value === '$' || node.children[0].value === '$value') &&
|
|
1114
1115
|
node.children[1].length > 0) {
|
|
1115
1116
|
|
|
1116
1117
|
e = node.children[1][0].value;
|
package/src/parser/prefix.js
CHANGED
|
@@ -156,12 +156,19 @@ JXG.PrefixParser = {
|
|
|
156
156
|
throw new Error("PrefixParser.parse: " + fun + " is not allowed");
|
|
157
157
|
}
|
|
158
158
|
} else {
|
|
159
|
-
// Allow shortcut 'V' for 'Value'
|
|
160
159
|
fun = term[0];
|
|
160
|
+
|
|
161
|
+
// Allow shortcut 'V' for 'Value'
|
|
161
162
|
if (fun === 'V') {
|
|
162
163
|
fun = 'Value';
|
|
163
164
|
}
|
|
164
165
|
|
|
166
|
+
// get coords always with z
|
|
167
|
+
// (its visibility is controlled by the attribute function formatCoords)
|
|
168
|
+
if (fun === 'Coords') {
|
|
169
|
+
term[2] = 'true';
|
|
170
|
+
}
|
|
171
|
+
|
|
165
172
|
if (!Type.exists(term[1][fun])) {
|
|
166
173
|
throw new Error("PrefixParser.parse: " + fun + " is not a method of " + term[1]);
|
|
167
174
|
}
|