jsxgraph 1.4.1 → 1.4.4
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/distrib/geogebra.min.js +1 -1
- package/distrib/geonext.min.js +1 -1
- package/distrib/index.d.ts +5252 -4826
- package/distrib/intergeo.min.js +1 -1
- package/distrib/jsxgraph.css +6 -2
- package/distrib/jsxgraphcore.js +4 -4
- package/distrib/jsxgraphsrc.js +2617 -151
- package/distrib/sketch.min.js +2 -2
- package/package.json +1 -1
- package/src/3d/box3d.js +268 -0
- package/src/3d/curve3d.js +97 -0
- package/src/3d/linspace3d.js +375 -0
- package/src/3d/point3d.js +200 -0
- package/src/3d/surface3d.js +220 -0
- package/src/3d/threed.js +38 -0
- package/src/3d/view3d.js +529 -0
- package/src/base/board.js +62 -45
- package/src/base/constants.js +2 -1
- package/src/base/coordselement.js +1 -4
- package/src/base/element.js +23 -14
- package/src/base/foreignobject.js +7 -1
- package/src/base/line.js +1 -1
- package/src/base/point.js +1 -0
- package/src/base/polygon.js +88 -33
- package/src/base/ticks.js +9 -2
- package/src/element/composition.js +62 -23
- package/src/element/slider.js +12 -0
- package/src/jsxgraph.js +6 -4
- package/src/loadjsxgraph.js +17 -11
- package/src/math/clip.js +0 -1
- package/src/math/geometry.js +187 -2
- package/src/math/math.js +9 -0
- package/src/options.js +24 -9
- package/src/options3d.js +265 -0
- package/src/parser/jessiecode.js +103 -0
- package/src/reader/sketch.js +6 -6
- package/src/renderer/abstract.js +4 -1
- package/src/renderer/svg.js +7 -4
- package/src/utils/color.js +1 -2
- package/src/utils/type.js +2 -2
package/distrib/jsxgraphsrc.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
} else {
|
|
7
7
|
root.returnExports = factory();
|
|
8
8
|
}
|
|
9
|
-
}(this, function () {
|
|
9
|
+
}(typeof self !== 'undefined' ? self : this, function () {
|
|
10
10
|
/**
|
|
11
11
|
* @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
|
|
12
12
|
* Released under MIT license, http://github.com/requirejs/almond/LICENSE
|
|
@@ -842,7 +842,7 @@ define('base/constants',['jxg'], function (JXG) {
|
|
|
842
842
|
|
|
843
843
|
var major = 1,
|
|
844
844
|
minor = 4,
|
|
845
|
-
patch =
|
|
845
|
+
patch = 4,
|
|
846
846
|
add = '', //'dev'
|
|
847
847
|
version = major + '.' + minor + '.' + patch + (add ? '-' + add : ''),
|
|
848
848
|
constants;
|
|
@@ -911,6 +911,7 @@ define('base/constants',['jxg'], function (JXG) {
|
|
|
911
911
|
OBJECT_TYPE_BUTTON: 29,
|
|
912
912
|
OBJECT_TYPE_TRANSFORMATION: 30,
|
|
913
913
|
OBJECT_TYPE_FOREIGNOBJECT: 31,
|
|
914
|
+
OBJECT_TYPE_VIEW3D: 32,
|
|
914
915
|
|
|
915
916
|
// IMPORTANT:
|
|
916
917
|
// ----------
|
|
@@ -2025,7 +2026,7 @@ define('utils/type',[
|
|
|
2025
2026
|
}
|
|
2026
2027
|
|
|
2027
2028
|
// options from attributes
|
|
2028
|
-
o = attributes;
|
|
2029
|
+
o = (typeof attributes === 'object') ? attributes : {};
|
|
2029
2030
|
isAvail = true;
|
|
2030
2031
|
for (i = 3; i < len; i++) {
|
|
2031
2032
|
if (this.exists(o[arguments[i]])) {
|
|
@@ -2331,7 +2332,7 @@ define('utils/type',[
|
|
|
2331
2332
|
return html_sanitize(str, function () { return undefined; }, function (id) { return id; });
|
|
2332
2333
|
}
|
|
2333
2334
|
|
|
2334
|
-
if (str) {
|
|
2335
|
+
if (str && typeof str === 'string') {
|
|
2335
2336
|
str = str.replace(/</g, '<').replace(/>/g, '>');
|
|
2336
2337
|
}
|
|
2337
2338
|
|
|
@@ -3998,6 +3999,15 @@ define('math/math',['jxg', 'utils/type'], function (JXG, Type) {
|
|
|
3998
3999
|
return Math.sqrt(sum);
|
|
3999
4000
|
},
|
|
4000
4001
|
|
|
4002
|
+
axpy: function (a, x, y) {
|
|
4003
|
+
var i, le = x.length,
|
|
4004
|
+
p = [];
|
|
4005
|
+
for (i = 0; i < le; i++) {
|
|
4006
|
+
p[i] = a * x[i] + y[i];
|
|
4007
|
+
}
|
|
4008
|
+
return p;
|
|
4009
|
+
},
|
|
4010
|
+
|
|
4001
4011
|
/**
|
|
4002
4012
|
* Compute the factorial of a positive integer. If a non-integer value
|
|
4003
4013
|
* is given, the fraction will be ignored.
|
|
@@ -14727,6 +14737,30 @@ define('math/geometry',[
|
|
|
14727
14737
|
return that.meetCurveLine(el1, el2, i, el1.board, alwaysintersect);
|
|
14728
14738
|
};
|
|
14729
14739
|
|
|
14740
|
+
} else if (el1.type === Const.OBJECT_TYPE_POLYGON || el2.type === Const.OBJECT_TYPE_POLYGON) {
|
|
14741
|
+
// polygon - other
|
|
14742
|
+
// Uses the Greiner-Hormann clipping algorithm
|
|
14743
|
+
// Not implemented: polygon - point
|
|
14744
|
+
|
|
14745
|
+
if (el1.elementClass === Const.OBJECT_CLASS_LINE) {
|
|
14746
|
+
// line - path
|
|
14747
|
+
/** @ignore */
|
|
14748
|
+
func = function () {
|
|
14749
|
+
return that.meetPolygonLine(el2, el1, i, el1.board, alwaysintersect);
|
|
14750
|
+
};
|
|
14751
|
+
} else if (el2.elementClass === Const.OBJECT_CLASS_LINE) {
|
|
14752
|
+
// path - line
|
|
14753
|
+
func = function () {
|
|
14754
|
+
return that.meetPolygonLine(el1, el2, i, el1.board, alwaysintersect);
|
|
14755
|
+
};
|
|
14756
|
+
} else {
|
|
14757
|
+
// path - path
|
|
14758
|
+
/** @ignore */
|
|
14759
|
+
func = function () {
|
|
14760
|
+
return that.meetPathPath(el1, el2, i, el1.board);
|
|
14761
|
+
};
|
|
14762
|
+
}
|
|
14763
|
+
|
|
14730
14764
|
} else if (el1.elementClass === Const.OBJECT_CLASS_LINE && el2.elementClass === Const.OBJECT_CLASS_LINE) {
|
|
14731
14765
|
// line - line, lines may also be segments.
|
|
14732
14766
|
/** @ignore */
|
|
@@ -15142,6 +15176,8 @@ define('math/geometry',[
|
|
|
15142
15176
|
* @param {JXG.Line} li Line
|
|
15143
15177
|
* @param {Number} nr Will return the nr-th intersection point.
|
|
15144
15178
|
* @param {JXG.Board} board
|
|
15179
|
+
* @param {Boolean} testSegment Test if intersection has to be inside of the segment or somewhere on the
|
|
15180
|
+
* line defined by the segment
|
|
15145
15181
|
* @returns {JXG.Coords} Coords object containing the intersection.
|
|
15146
15182
|
*/
|
|
15147
15183
|
meetCurveLineContinuous: function (cu, li, nr, board, testSegment) {
|
|
@@ -15206,7 +15242,6 @@ define('math/geometry',[
|
|
|
15206
15242
|
return (new Coords(Const.COORDS_BY_USER, [z, cu.X(t), cu.Y(t)], board));
|
|
15207
15243
|
},
|
|
15208
15244
|
|
|
15209
|
-
|
|
15210
15245
|
/**
|
|
15211
15246
|
* Intersection of line and curve, discrete case.
|
|
15212
15247
|
* Segments are treated as lines.
|
|
@@ -15393,6 +15428,87 @@ define('math/geometry',[
|
|
|
15393
15428
|
return [c, t, u];
|
|
15394
15429
|
},
|
|
15395
15430
|
|
|
15431
|
+
/**
|
|
15432
|
+
* Find the n-th intersection point of two pathes, usually given by polygons. Uses parts of the
|
|
15433
|
+
* Greiner-Hormann algorithm in JXG.Math.Clip.
|
|
15434
|
+
*
|
|
15435
|
+
* @param {JXG.Circle|JXG.Curve|JXG.Polygon} path1
|
|
15436
|
+
* @param {JXG.Circle|JXG.Curve|JXG.Polygon} path2
|
|
15437
|
+
* @param {Number} n
|
|
15438
|
+
* @param {JXG.Board} board
|
|
15439
|
+
*
|
|
15440
|
+
* @returns {JXG.Coords} Intersection point. In case no intersection point is detected,
|
|
15441
|
+
* the ideal point [0,0,0] is returned.
|
|
15442
|
+
*
|
|
15443
|
+
*/
|
|
15444
|
+
meetPathPath: function(path1, path2, nr, board) {
|
|
15445
|
+
var S, C, len, intersections;
|
|
15446
|
+
|
|
15447
|
+
S = JXG.Math.Clip._getPath(path1, board);
|
|
15448
|
+
len = S.length;
|
|
15449
|
+
if (len > 0 && this.distance(S[0].coords.usrCoords, S[len - 1].coords.usrCoords, 3) < Mat.eps) {
|
|
15450
|
+
S.pop();
|
|
15451
|
+
}
|
|
15452
|
+
|
|
15453
|
+
C = JXG.Math.Clip._getPath(path2, board);
|
|
15454
|
+
len = C.length;
|
|
15455
|
+
if (len > 0 && this.distance(C[0].coords.usrCoords, C[len - 1].coords.usrCoords, 3) < Mat.eps * Mat.eps) {
|
|
15456
|
+
C.pop();
|
|
15457
|
+
}
|
|
15458
|
+
|
|
15459
|
+
// Handle cases where at least one of the paths is empty
|
|
15460
|
+
if (nr < 0 || JXG.Math.Clip.isEmptyCase(S, C, 'intersection')) {
|
|
15461
|
+
return (new Coords(Const.COORDS_BY_USER, [0, 0, 0], board));
|
|
15462
|
+
}
|
|
15463
|
+
|
|
15464
|
+
JXG.Math.Clip.makeDoublyLinkedList(S);
|
|
15465
|
+
JXG.Math.Clip.makeDoublyLinkedList(C);
|
|
15466
|
+
|
|
15467
|
+
intersections = JXG.Math.Clip.findIntersections(S, C, board)[0];
|
|
15468
|
+
if (nr < intersections.length) {
|
|
15469
|
+
return intersections[nr].coords;
|
|
15470
|
+
}
|
|
15471
|
+
return (new Coords(Const.COORDS_BY_USER, [0, 0, 0], board));
|
|
15472
|
+
},
|
|
15473
|
+
|
|
15474
|
+
/**
|
|
15475
|
+
* Find the n-th intersection point between a polygon and a line.
|
|
15476
|
+
* @param {JXG.Polygon} path
|
|
15477
|
+
* @param {JXG.Line} line
|
|
15478
|
+
* @param {Number} nr
|
|
15479
|
+
* @param {JXG.Board} board
|
|
15480
|
+
* @param {Boolean} alwaysIntersect If false just the segment between the two defining points of the line are tested for intersection.
|
|
15481
|
+
*
|
|
15482
|
+
* @returns {JXG.Coords} Intersection point. In case no intersection point is detected,
|
|
15483
|
+
* the ideal point [0,0,0] is returned.
|
|
15484
|
+
*/
|
|
15485
|
+
meetPolygonLine: function(path, line, nr, board, alwaysIntersect) {
|
|
15486
|
+
var i, res, border,
|
|
15487
|
+
crds = [0,0,0],
|
|
15488
|
+
len = path.borders.length,
|
|
15489
|
+
intersections = [];
|
|
15490
|
+
|
|
15491
|
+
for (i = 0; i < len; i++) {
|
|
15492
|
+
border = path.borders[i];
|
|
15493
|
+
res = this.meetSegmentSegment(
|
|
15494
|
+
border.point1.coords.usrCoords,
|
|
15495
|
+
border.point2.coords.usrCoords,
|
|
15496
|
+
line.point1.coords.usrCoords,
|
|
15497
|
+
line.point2.coords.usrCoords);
|
|
15498
|
+
|
|
15499
|
+
if (
|
|
15500
|
+
(!alwaysIntersect || (res[2] >= 0 && res[2] < 1)) &&
|
|
15501
|
+
res[1] >= 0 && res[1] < 1) {
|
|
15502
|
+
intersections.push(res[0]);
|
|
15503
|
+
}
|
|
15504
|
+
}
|
|
15505
|
+
|
|
15506
|
+
if (nr >= 0 && nr < intersections.length) {
|
|
15507
|
+
crds = intersections[nr];
|
|
15508
|
+
}
|
|
15509
|
+
return (new Coords(Const.COORDS_BY_USER, crds, board));
|
|
15510
|
+
},
|
|
15511
|
+
|
|
15396
15512
|
/****************************************/
|
|
15397
15513
|
/**** BEZIER CURVE ALGORITHMS ****/
|
|
15398
15514
|
/****************************************/
|
|
@@ -16333,7 +16449,86 @@ define('math/geometry',[
|
|
|
16333
16449
|
};
|
|
16334
16450
|
|
|
16335
16451
|
return [makeFct('X', 'cos'), makeFct('Y', 'sin'), 0, pi2];
|
|
16336
|
-
}
|
|
16452
|
+
},
|
|
16453
|
+
|
|
16454
|
+
|
|
16455
|
+
meet3Planes: function (n1, d1, n2, d2, n3, d3) {
|
|
16456
|
+
var p = [0, 0, 0],
|
|
16457
|
+
n31, n12, n23, denom,
|
|
16458
|
+
i;
|
|
16459
|
+
|
|
16460
|
+
n31 = Mat.crossProduct(n3, n1);
|
|
16461
|
+
n12 = Mat.crossProduct(n1, n2);
|
|
16462
|
+
n23 = Mat.crossProduct(n2, n3);
|
|
16463
|
+
denom = Mat.innerProduct(n1, n23, 3);
|
|
16464
|
+
for (i = 0; i < 3; i++) {
|
|
16465
|
+
p[i] = (d1 * n23[i] + d2 * n31[i] + d3 * n12[i]) / denom;
|
|
16466
|
+
}
|
|
16467
|
+
return p;
|
|
16468
|
+
},
|
|
16469
|
+
|
|
16470
|
+
|
|
16471
|
+
meetPlanePlane: function (v11, v12, v21, v22) {
|
|
16472
|
+
var i, no1, no2,
|
|
16473
|
+
v = [0, 0, 0],
|
|
16474
|
+
w = [0, 0, 0];
|
|
16475
|
+
|
|
16476
|
+
for (i = 0; i < 3; i++) {
|
|
16477
|
+
v[i] = Type.evaluate(v11[i]);
|
|
16478
|
+
w[i] = Type.evaluate(v12[i]);
|
|
16479
|
+
}
|
|
16480
|
+
no1 = Mat.crossProduct(v, w);
|
|
16481
|
+
|
|
16482
|
+
for (i = 0; i < 3; i++) {
|
|
16483
|
+
v[i] = Type.evaluate(v21[i]);
|
|
16484
|
+
w[i] = Type.evaluate(v22[i]);
|
|
16485
|
+
}
|
|
16486
|
+
no2 = Mat.crossProduct(v, w);
|
|
16487
|
+
|
|
16488
|
+
return Mat.crossProduct(no1, no2);
|
|
16489
|
+
},
|
|
16490
|
+
|
|
16491
|
+
project3DTo3DPlane: function (point, normal, foot) {
|
|
16492
|
+
// TODO: homogeneous 3D coordinates
|
|
16493
|
+
var sol = [0, 0, 0],
|
|
16494
|
+
le, d1, d2, lbda;
|
|
16495
|
+
|
|
16496
|
+
foot = foot || [0, 0, 0];
|
|
16497
|
+
|
|
16498
|
+
le = Mat.norm(normal);
|
|
16499
|
+
d1 = Mat.innerProduct(point, normal, 3);
|
|
16500
|
+
d2 = Mat.innerProduct(foot, normal, 3);
|
|
16501
|
+
// (point - lbda * normal / le) * normal / le == foot * normal / le
|
|
16502
|
+
// => (point * normal - foot * normal) == lbda * le
|
|
16503
|
+
lbda = (d1 - d2) / le;
|
|
16504
|
+
sol = Mat.axpy(-lbda, normal, point);
|
|
16505
|
+
|
|
16506
|
+
return sol;
|
|
16507
|
+
},
|
|
16508
|
+
|
|
16509
|
+
getPlaneBounds: function (v1, v2, q, s, e) {
|
|
16510
|
+
var s1, s2, e1, e2, mat, rhs, sol;
|
|
16511
|
+
|
|
16512
|
+
if (v1[2] + v2[0] !== 0) {
|
|
16513
|
+
mat = [
|
|
16514
|
+
[v1[0], v2[0]],
|
|
16515
|
+
[v1[1], v2[1]]
|
|
16516
|
+
];
|
|
16517
|
+
rhs = [s - q[0], s - q[1]];
|
|
16518
|
+
|
|
16519
|
+
sol = Numerics.Gauss(mat, rhs);
|
|
16520
|
+
s1 = sol[0];
|
|
16521
|
+
s2 = sol[1];
|
|
16522
|
+
|
|
16523
|
+
rhs = [e - q[0], e - q[1]];
|
|
16524
|
+
sol = Numerics.Gauss(mat, rhs);
|
|
16525
|
+
e1 = sol[0];
|
|
16526
|
+
e2 = sol[1];
|
|
16527
|
+
return [s1, e1, s2, e2];
|
|
16528
|
+
}
|
|
16529
|
+
return null;
|
|
16530
|
+
},
|
|
16531
|
+
|
|
16337
16532
|
});
|
|
16338
16533
|
|
|
16339
16534
|
return Mat.Geometry;
|
|
@@ -23139,7 +23334,6 @@ define('math/clip',[
|
|
|
23139
23334
|
|
|
23140
23335
|
// Collect all points into clip array C
|
|
23141
23336
|
C = this._getPath(clip, board);
|
|
23142
|
-
|
|
23143
23337
|
len = C.length;
|
|
23144
23338
|
if (len > 0 && Geometry.distance(C[0].coords.usrCoords, C[len - 1].coords.usrCoords, 3) < Mat.eps * Mat.eps) {
|
|
23145
23339
|
C.pop();
|
|
@@ -25020,8 +25214,7 @@ define('utils/color',['jxg', 'utils/type', 'math/math'],
|
|
|
25020
25214
|
green: '#009E73', // bluishgreen
|
|
25021
25215
|
purple: '#CC79A7', // reddishpurple
|
|
25022
25216
|
white: '#ffffff'
|
|
25023
|
-
}
|
|
25024
|
-
|
|
25217
|
+
}
|
|
25025
25218
|
});
|
|
25026
25219
|
|
|
25027
25220
|
/**
|
|
@@ -25837,6 +26030,10 @@ define('options',[
|
|
|
25837
26030
|
* visible: false // Initial visibility. Should be set to false always
|
|
25838
26031
|
* }
|
|
25839
26032
|
* </pre>
|
|
26033
|
+
* <p>
|
|
26034
|
+
* Board events triggered by selection manipulation:
|
|
26035
|
+
* 'startselecting', 'stopselecting', 'mousestartselecting', 'mousestopselecting',
|
|
26036
|
+
* 'pointerstartselecting', 'pointerstopselecting', 'touchstartselecting', 'touchstopselecting'.
|
|
25840
26037
|
*
|
|
25841
26038
|
* @example
|
|
25842
26039
|
* board.on('stopselecting', function(){
|
|
@@ -25850,14 +26047,10 @@ define('options',[
|
|
|
25850
26047
|
* });
|
|
25851
26048
|
*
|
|
25852
26049
|
* @name JXG.Board#selection
|
|
25853
|
-
*
|
|
25854
|
-
* @see JXG.Board#
|
|
25855
|
-
* @see JXG.Board#
|
|
25856
|
-
*
|
|
25857
|
-
* @see JXG.Board#touchstartselecting
|
|
25858
|
-
* @see JXG.Board#mousestopselecting
|
|
25859
|
-
* @see JXG.Board#pointerstopselecting
|
|
25860
|
-
* @see JXG.Board#touchstopselecting
|
|
26050
|
+
*
|
|
26051
|
+
* @see JXG.Board#startSelectionMode
|
|
26052
|
+
* @see JXG.Board#stopSelectionMode
|
|
26053
|
+
*
|
|
25861
26054
|
* @type Object
|
|
25862
26055
|
* @default
|
|
25863
26056
|
*/
|
|
@@ -26542,7 +26735,20 @@ define('options',[
|
|
|
26542
26735
|
*/
|
|
26543
26736
|
isLabel: false,
|
|
26544
26737
|
|
|
26545
|
-
|
|
26738
|
+
/**
|
|
26739
|
+
* Controls if an element can get the focus with the tab key.
|
|
26740
|
+
* See <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex">descriptiona at MDN</a>.
|
|
26741
|
+
* The additional value null completely disables focus of an element.
|
|
26742
|
+
* The value will be ignored if keyboard control of the board is not enabled or
|
|
26743
|
+
* the element is fixed or not visible.
|
|
26744
|
+
*
|
|
26745
|
+
* @name JXG.GeometryElement#tabindex
|
|
26746
|
+
* @type Number
|
|
26747
|
+
* @default 0
|
|
26748
|
+
* @see JXG.Board#keyboard
|
|
26749
|
+
* @see JXG.GeometryElement#fixed
|
|
26750
|
+
* @see JXG.GeometryElement#visible
|
|
26751
|
+
*/
|
|
26546
26752
|
tabindex: 0
|
|
26547
26753
|
|
|
26548
26754
|
// close the meta tag
|
|
@@ -29742,6 +29948,7 @@ define('options',[
|
|
|
29742
29948
|
visible: 'inherit',
|
|
29743
29949
|
fixed: true,
|
|
29744
29950
|
scalable: false,
|
|
29951
|
+
tabindex: null,
|
|
29745
29952
|
name: '',
|
|
29746
29953
|
strokeWidth: 1,
|
|
29747
29954
|
strokeColor: '#000000',
|
|
@@ -29791,6 +29998,7 @@ define('options',[
|
|
|
29791
29998
|
strokeWidth: 3,
|
|
29792
29999
|
visible: 'inherit',
|
|
29793
30000
|
fixed: true,
|
|
30001
|
+
tabindex: null,
|
|
29794
30002
|
name: '',
|
|
29795
30003
|
strokeColor: '#000000',
|
|
29796
30004
|
highlightStrokeColor: '#888888'
|
|
@@ -32720,8 +32928,11 @@ define('renderer/abstract',[
|
|
|
32720
32928
|
|
|
32721
32929
|
setTabindex: function(element) {
|
|
32722
32930
|
var val;
|
|
32723
|
-
if (Type.exists(element.rendNode)) {
|
|
32931
|
+
if (element.board.attr.keyboard.enabled && Type.exists(element.rendNode)) {
|
|
32724
32932
|
val = Type.evaluate(element.visProp.tabindex);
|
|
32933
|
+
if (!element.visPropCalc.visible || Type.evaluate(element.visProp.fixed)) {
|
|
32934
|
+
val = null;
|
|
32935
|
+
}
|
|
32725
32936
|
if (val !== element.visPropOld.tabindex) {
|
|
32726
32937
|
element.rendNode.setAttribute('tabindex', val);
|
|
32727
32938
|
element.visPropOld.tabindex = val;
|
|
@@ -34253,7 +34464,7 @@ define('base/element',[
|
|
|
34253
34464
|
|
|
34254
34465
|
/**
|
|
34255
34466
|
* Inherits contains the subelements, which may have an attribute
|
|
34256
|
-
* (in
|
|
34467
|
+
* (in particular the attribute "visible") having value 'inherit'.
|
|
34257
34468
|
* @type Object
|
|
34258
34469
|
*/
|
|
34259
34470
|
this.inherits = [];
|
|
@@ -35081,26 +35292,35 @@ define('base/element',[
|
|
|
35081
35292
|
},
|
|
35082
35293
|
|
|
35083
35294
|
/**
|
|
35084
|
-
* Resolves
|
|
35085
|
-
* Writes the expanded
|
|
35086
|
-
* @param {Object}
|
|
35087
|
-
* @returns {Object} The given
|
|
35295
|
+
* Resolves attribute shortcuts like <tt>color</tt> and expands them, e.g. <tt>strokeColor</tt> and <tt>fillColor</tt>.
|
|
35296
|
+
* Writes the expanded attributes back to the given <tt>attributes</tt>.
|
|
35297
|
+
* @param {Object} attributes object
|
|
35298
|
+
* @returns {Object} The given attributes object with shortcuts expanded.
|
|
35299
|
+
* @private
|
|
35088
35300
|
*/
|
|
35089
|
-
resolveShortcuts: function (
|
|
35090
|
-
var key, i
|
|
35301
|
+
resolveShortcuts: function (attributes) {
|
|
35302
|
+
var key, i,
|
|
35303
|
+
j,
|
|
35304
|
+
subattr = ['traceattributes', 'traceAttributes'];
|
|
35091
35305
|
|
|
35092
35306
|
for (key in Options.shortcuts) {
|
|
35093
35307
|
if (Options.shortcuts.hasOwnProperty(key)) {
|
|
35094
|
-
|
|
35095
|
-
|
|
35096
|
-
|
|
35097
|
-
|
|
35308
|
+
|
|
35309
|
+
if (Type.exists(attributes[key])) {
|
|
35310
|
+
for (i = 0; i < Options.shortcuts[key].length; i++) {
|
|
35311
|
+
if (!Type.exists(attributes[Options.shortcuts[key][i]])) {
|
|
35312
|
+
attributes[Options.shortcuts[key][i]] = attributes[key];
|
|
35313
|
+
}
|
|
35314
|
+
}
|
|
35315
|
+
}
|
|
35316
|
+
for (j = 0; j < subattr.length; j++) {
|
|
35317
|
+
if (Type.isObject(attributes[subattr[j]])) {
|
|
35318
|
+
attributes[subattr[j]] = this.resolveShortcuts(attributes[subattr[j]]);
|
|
35319
|
+
}
|
|
35098
35320
|
}
|
|
35099
35321
|
}
|
|
35100
|
-
}
|
|
35101
|
-
}
|
|
35102
35322
|
}
|
|
35103
|
-
return
|
|
35323
|
+
return attributes;
|
|
35104
35324
|
},
|
|
35105
35325
|
|
|
35106
35326
|
/**
|
|
@@ -36528,8 +36748,6 @@ define('base/coordselement',[
|
|
|
36528
36748
|
* @private
|
|
36529
36749
|
*/
|
|
36530
36750
|
updateCoords: function (fromParent) {
|
|
36531
|
-
var i;
|
|
36532
|
-
|
|
36533
36751
|
if (!this.needsUpdate) {
|
|
36534
36752
|
return this;
|
|
36535
36753
|
}
|
|
@@ -36656,7 +36874,6 @@ define('base/coordselement',[
|
|
|
36656
36874
|
doRound = true;
|
|
36657
36875
|
newPos = 0.0;
|
|
36658
36876
|
} else {
|
|
36659
|
-
//this.coords.setCoordinates(Const.COORDS_BY_USER, Geometry.projectPointToLine(this, slide, this.board).usrCoords, false);
|
|
36660
36877
|
newCoords = Geometry.projectPointToLine(this, slide, this.board);
|
|
36661
36878
|
p1c = p1c.usrCoords.slice(0);
|
|
36662
36879
|
p2c = p2c.usrCoords.slice(0);
|
|
@@ -38163,7 +38380,7 @@ define('base/coordselement',[
|
|
|
38163
38380
|
if (direction < 0) {
|
|
38164
38381
|
alpha *= this.intervalCount / stepCount;
|
|
38165
38382
|
} else {
|
|
38166
|
-
alpha *= (stepCount - this.intervalCount);
|
|
38383
|
+
alpha *= (stepCount - this.intervalCount) / stepCount;
|
|
38167
38384
|
}
|
|
38168
38385
|
radius = this.slideObject.Radius();
|
|
38169
38386
|
|
|
@@ -39664,6 +39881,12 @@ define('parser/jessiecode',[
|
|
|
39664
39881
|
*/
|
|
39665
39882
|
this.builtIn = this.defineBuiltIn();
|
|
39666
39883
|
|
|
39884
|
+
/**
|
|
39885
|
+
* List of all possible operands in JessieCode (except of JSXGraph objects).
|
|
39886
|
+
* @type Object
|
|
39887
|
+
*/
|
|
39888
|
+
this.operands = this.getPossibleOperands();
|
|
39889
|
+
|
|
39667
39890
|
/**
|
|
39668
39891
|
* The board which currently is used to create and look up elements.
|
|
39669
39892
|
* @type JXG.Board
|
|
@@ -41956,6 +42179,103 @@ define('parser/jessiecode',[
|
|
|
41956
42179
|
return builtIn;
|
|
41957
42180
|
},
|
|
41958
42181
|
|
|
42182
|
+
/**
|
|
42183
|
+
* Returns information about the possible functions and constants.
|
|
42184
|
+
* @returns {Object}
|
|
42185
|
+
*/
|
|
42186
|
+
getPossibleOperands: function () {
|
|
42187
|
+
var FORBIDDEN = ['E'],
|
|
42188
|
+
jessiecode = this.defineBuiltIn(),
|
|
42189
|
+
math = Math,
|
|
42190
|
+
jc, ma, merge,
|
|
42191
|
+
i, j, p, len, e,
|
|
42192
|
+
funcs, funcsJC, consts, operands,
|
|
42193
|
+
sort, pack;
|
|
42194
|
+
|
|
42195
|
+
sort = function (a, b) {
|
|
42196
|
+
return a.toLowerCase().localeCompare(b.toLowerCase());
|
|
42197
|
+
};
|
|
42198
|
+
|
|
42199
|
+
pack = function (name, origin) {
|
|
42200
|
+
var that = null;
|
|
42201
|
+
|
|
42202
|
+
if (origin === 'jc') that = jessiecode[name];
|
|
42203
|
+
else if (origin === 'Math') that = math[name];
|
|
42204
|
+
else return;
|
|
42205
|
+
|
|
42206
|
+
if (FORBIDDEN.includes(name)) {
|
|
42207
|
+
return;
|
|
42208
|
+
} else if (JXG.isFunction(that)) {
|
|
42209
|
+
return {
|
|
42210
|
+
name: name,
|
|
42211
|
+
type: 'function',
|
|
42212
|
+
numParams: that.length,
|
|
42213
|
+
origin: origin,
|
|
42214
|
+
};
|
|
42215
|
+
} else if (JXG.isNumber(that)) {
|
|
42216
|
+
return {
|
|
42217
|
+
name: name,
|
|
42218
|
+
type: 'constant',
|
|
42219
|
+
value: that,
|
|
42220
|
+
origin: origin,
|
|
42221
|
+
};
|
|
42222
|
+
} else if (that !== undefined) {
|
|
42223
|
+
console.error('undefined type', that);
|
|
42224
|
+
}
|
|
42225
|
+
};
|
|
42226
|
+
|
|
42227
|
+
jc = Object.getOwnPropertyNames(jessiecode).sort(sort);
|
|
42228
|
+
ma = Object.getOwnPropertyNames(math).sort(sort);
|
|
42229
|
+
merge = [];
|
|
42230
|
+
i = 0;
|
|
42231
|
+
j = 0;
|
|
42232
|
+
|
|
42233
|
+
while (i < jc.length || j < ma.length) {
|
|
42234
|
+
if (jc[i] === ma[j]) {
|
|
42235
|
+
p = pack(ma[j], 'Math');
|
|
42236
|
+
if (JXG.exists(p)) merge.push(p);
|
|
42237
|
+
i++;
|
|
42238
|
+
j++;
|
|
42239
|
+
} else if (!JXG.exists(ma[j]) || jc[i].toLowerCase().localeCompare(ma[j].toLowerCase()) < 0) {
|
|
42240
|
+
p = pack(jc[i], 'jc');
|
|
42241
|
+
if (JXG.exists(p)) merge.push(p);
|
|
42242
|
+
i++;
|
|
42243
|
+
} else {
|
|
42244
|
+
p = pack(ma[j], 'Math');
|
|
42245
|
+
if (JXG.exists(p)) merge.push(p);
|
|
42246
|
+
j++;
|
|
42247
|
+
}
|
|
42248
|
+
}
|
|
42249
|
+
|
|
42250
|
+
funcs = [];
|
|
42251
|
+
funcsJC = [];
|
|
42252
|
+
consts = [];
|
|
42253
|
+
operands = {};
|
|
42254
|
+
len = merge.length;
|
|
42255
|
+
for (i = 0; i < len; i++) {
|
|
42256
|
+
e = merge[i];
|
|
42257
|
+
switch (e.type) {
|
|
42258
|
+
case 'function':
|
|
42259
|
+
funcs.push(e.name);
|
|
42260
|
+
if (e.origin === 'jc')
|
|
42261
|
+
funcsJC.push(e.name);
|
|
42262
|
+
break;
|
|
42263
|
+
case 'constant':
|
|
42264
|
+
consts.push(e.name);
|
|
42265
|
+
break;
|
|
42266
|
+
}
|
|
42267
|
+
operands[e.name] = e;
|
|
42268
|
+
}
|
|
42269
|
+
|
|
42270
|
+
return {
|
|
42271
|
+
all: operands,
|
|
42272
|
+
list: merge,
|
|
42273
|
+
functions: funcs,
|
|
42274
|
+
functions_jessiecode: funcsJC,
|
|
42275
|
+
constants: consts,
|
|
42276
|
+
};
|
|
42277
|
+
},
|
|
42278
|
+
|
|
41959
42279
|
/**
|
|
41960
42280
|
* Output a debugging message. Uses debug console, if available. Otherwise an HTML element with the
|
|
41961
42281
|
* id "debug" and an innerHTML property is used.
|
|
@@ -44040,8 +44360,12 @@ define('base/board',[
|
|
|
44040
44360
|
*/
|
|
44041
44361
|
getCoordsTopLeftCorner: function () {
|
|
44042
44362
|
var cPos, doc, crect,
|
|
44043
|
-
|
|
44044
|
-
|
|
44363
|
+
// In ownerDoc we need the "real" document object.
|
|
44364
|
+
// The first version is used in the case of shadowDom,
|
|
44365
|
+
// the second case in the "normal" case.
|
|
44366
|
+
ownerDoc = this.document.ownerDocument || this.document,
|
|
44367
|
+
docElement = ownerDoc.documentElement || this.document.body.parentNode,
|
|
44368
|
+
docBody = ownerDoc.body,
|
|
44045
44369
|
container = this.containerObj,
|
|
44046
44370
|
// viewport, content,
|
|
44047
44371
|
zoom, o;
|
|
@@ -44888,7 +45212,7 @@ define('base/board',[
|
|
|
44888
45212
|
},
|
|
44889
45213
|
|
|
44890
45214
|
addKeyboardEventHandlers: function() {
|
|
44891
|
-
if (!this.hasKeyboardHandlers && Env.isBrowser) {
|
|
45215
|
+
if (this.attr.keyboard.enabled && !this.hasKeyboardHandlers && Env.isBrowser) {
|
|
44892
45216
|
Env.addEvent(this.containerObj, 'keydown', this.keyDownListener, this);
|
|
44893
45217
|
Env.addEvent(this.containerObj, 'focusin', this.keyFocusInListener, this);
|
|
44894
45218
|
Env.addEvent(this.containerObj, 'focusout', this.keyFocusOutListener, this);
|
|
@@ -45641,10 +45965,14 @@ define('base/board',[
|
|
|
45641
45965
|
}
|
|
45642
45966
|
}
|
|
45643
45967
|
|
|
45968
|
+
this.originMoveEnd();
|
|
45969
|
+
this.update();
|
|
45970
|
+
|
|
45644
45971
|
// selection
|
|
45645
45972
|
if (this.selectingMode) {
|
|
45646
45973
|
this._stopSelecting(evt);
|
|
45647
45974
|
this.triggerEventHandlers(['touchstopselecting', 'pointerstopselecting', 'stopselecting'], [evt]);
|
|
45975
|
+
this.stopSelectionMode();
|
|
45648
45976
|
} else {
|
|
45649
45977
|
for (i = this.downObjects.length - 1; i > -1; i--) {
|
|
45650
45978
|
found = false;
|
|
@@ -45655,32 +45983,30 @@ define('base/board',[
|
|
|
45655
45983
|
}
|
|
45656
45984
|
if (!found) {
|
|
45657
45985
|
this.downObjects[i].triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
|
|
45658
|
-
this.downObjects[i].snapToGrid();
|
|
45659
|
-
this.downObjects[i].snapToPoints();
|
|
45986
|
+
// this.downObjects[i].snapToGrid();
|
|
45987
|
+
// this.downObjects[i].snapToPoints();
|
|
45660
45988
|
this.downObjects.splice(i, 1);
|
|
45661
45989
|
}
|
|
45662
45990
|
}
|
|
45663
45991
|
}
|
|
45664
45992
|
|
|
45665
|
-
|
|
45666
|
-
|
|
45667
|
-
|
|
45668
|
-
|
|
45669
|
-
|
|
45670
|
-
|
|
45671
|
-
Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
|
|
45672
|
-
Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
|
|
45673
|
-
}
|
|
45674
|
-
this.hasPointerUp = false;
|
|
45993
|
+
if (this.hasPointerUp) {
|
|
45994
|
+
if (window.navigator.msPointerEnabled) { // IE10-
|
|
45995
|
+
Env.removeEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);
|
|
45996
|
+
} else {
|
|
45997
|
+
Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
|
|
45998
|
+
Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
|
|
45675
45999
|
}
|
|
46000
|
+
this.hasPointerUp = false;
|
|
46001
|
+
}
|
|
45676
46002
|
|
|
45677
|
-
|
|
45678
|
-
|
|
45679
|
-
|
|
46003
|
+
// this.dehighlightAll();
|
|
46004
|
+
// this.updateQuality = this.BOARD_QUALITY_HIGH;
|
|
46005
|
+
// this.mode = this.BOARD_MODE_NONE;
|
|
46006
|
+
|
|
46007
|
+
// this.originMoveEnd();
|
|
46008
|
+
// this.update();
|
|
45680
46009
|
|
|
45681
|
-
this.originMoveEnd();
|
|
45682
|
-
this.update();
|
|
45683
|
-
// }
|
|
45684
46010
|
// After one finger leaves the screen the gesture is stopped.
|
|
45685
46011
|
this._pointerClearTouches();
|
|
45686
46012
|
return true;
|
|
@@ -45815,7 +46141,7 @@ define('base/board',[
|
|
|
45815
46141
|
obj.type === Const.OBJECT_TYPE_TICKS ||
|
|
45816
46142
|
obj.type === Const.OBJECT_TYPE_IMAGE) {
|
|
45817
46143
|
// It's a point, so it's single touch, so we just push it to our touches
|
|
45818
|
-
targets = [
|
|
46144
|
+
targets = [target];
|
|
45819
46145
|
|
|
45820
46146
|
// For the UNDO/REDO of object moves
|
|
45821
46147
|
this.saveStartPos(obj, targets[0]);
|
|
@@ -46023,6 +46349,7 @@ define('base/board',[
|
|
|
46023
46349
|
if (this.selectingMode) {
|
|
46024
46350
|
this._stopSelecting(evt);
|
|
46025
46351
|
this.triggerEventHandlers(['touchstopselecting', 'stopselecting'], [evt]);
|
|
46352
|
+
this.stopSelectionMode();
|
|
46026
46353
|
} else if (evtTouches && evtTouches.length > 0) {
|
|
46027
46354
|
for (i = 0; i < this.touches.length; i++) {
|
|
46028
46355
|
tmpTouches[i] = this.touches[i];
|
|
@@ -46114,8 +46441,8 @@ define('base/board',[
|
|
|
46114
46441
|
}
|
|
46115
46442
|
if (!found) {
|
|
46116
46443
|
this.downObjects[i].triggerEventHandlers(['touchup', 'up'], [evt]);
|
|
46117
|
-
this.downObjects[i].snapToGrid();
|
|
46118
|
-
this.downObjects[i].snapToPoints();
|
|
46444
|
+
// this.downObjects[i].snapToGrid();
|
|
46445
|
+
// this.downObjects[i].snapToPoints();
|
|
46119
46446
|
this.downObjects.splice(i, 1);
|
|
46120
46447
|
}
|
|
46121
46448
|
}
|
|
@@ -46278,11 +46605,11 @@ define('base/board',[
|
|
|
46278
46605
|
// redraw with high precision
|
|
46279
46606
|
this.updateQuality = this.BOARD_QUALITY_HIGH;
|
|
46280
46607
|
|
|
46281
|
-
if (this.mouse && this.mouse.obj) {
|
|
46282
|
-
|
|
46283
|
-
|
|
46284
|
-
|
|
46285
|
-
}
|
|
46608
|
+
// if (this.mouse && this.mouse.obj) {
|
|
46609
|
+
// // The parameter is needed for lines with snapToGrid enabled
|
|
46610
|
+
// this.mouse.obj.snapToGrid(this.mouse.targets[0]);
|
|
46611
|
+
// this.mouse.obj.snapToPoints();
|
|
46612
|
+
// }
|
|
46286
46613
|
|
|
46287
46614
|
this.originMoveEnd();
|
|
46288
46615
|
this.dehighlightAll();
|
|
@@ -46292,6 +46619,7 @@ define('base/board',[
|
|
|
46292
46619
|
if (this.selectingMode) {
|
|
46293
46620
|
this._stopSelecting(evt);
|
|
46294
46621
|
this.triggerEventHandlers(['mousestopselecting', 'stopselecting'], [evt]);
|
|
46622
|
+
this.stopSelectionMode();
|
|
46295
46623
|
} else {
|
|
46296
46624
|
for (i = 0; i < this.downObjects.length; i++) {
|
|
46297
46625
|
this.downObjects[i].triggerEventHandlers(['mouseup', 'up'], [evt]);
|
|
@@ -46360,6 +46688,7 @@ define('base/board',[
|
|
|
46360
46688
|
dx = Type.evaluate(this.attr.keyboard.dx) / this.unitX,
|
|
46361
46689
|
dy = Type.evaluate(this.attr.keyboard.dy) / this.unitY,
|
|
46362
46690
|
doZoom = false,
|
|
46691
|
+
done = true,
|
|
46363
46692
|
dir, actPos;
|
|
46364
46693
|
|
|
46365
46694
|
if (!this.attr.keyboard.enabled || id_node === '') {
|
|
@@ -46388,6 +46717,8 @@ define('base/board',[
|
|
|
46388
46717
|
this.clickLeftArrow();
|
|
46389
46718
|
} else if (evt.keyCode === 39) { // right
|
|
46390
46719
|
this.clickRightArrow();
|
|
46720
|
+
} else {
|
|
46721
|
+
done = false;
|
|
46391
46722
|
}
|
|
46392
46723
|
} else {
|
|
46393
46724
|
// Adapt dx, dy to snapToGrid and attractToGrid
|
|
@@ -46440,7 +46771,10 @@ define('base/board',[
|
|
|
46440
46771
|
this.zoomOut();
|
|
46441
46772
|
} else if (doZoom && evt.key === 'o') { // o
|
|
46442
46773
|
this.zoom100();
|
|
46774
|
+
} else {
|
|
46775
|
+
done = false;
|
|
46443
46776
|
}
|
|
46777
|
+
|
|
46444
46778
|
if (dir && el.isDraggable &&
|
|
46445
46779
|
el.visPropCalc.visible &&
|
|
46446
46780
|
((this.geonextCompatibilityMode &&
|
|
@@ -46466,6 +46800,9 @@ define('base/board',[
|
|
|
46466
46800
|
|
|
46467
46801
|
this.update();
|
|
46468
46802
|
|
|
46803
|
+
if (done && Type.exists(evt.preventDefault)) {
|
|
46804
|
+
evt.preventDefault();
|
|
46805
|
+
}
|
|
46469
46806
|
return true;
|
|
46470
46807
|
},
|
|
46471
46808
|
|
|
@@ -46551,7 +46888,7 @@ define('base/board',[
|
|
|
46551
46888
|
}
|
|
46552
46889
|
|
|
46553
46890
|
// If div is invisible - do nothing
|
|
46554
|
-
if (w <= 0 || h <= 0) {
|
|
46891
|
+
if (w <= 0 || h <= 0 || Type.isNaN(w) || Type.isNaN(h)) {
|
|
46555
46892
|
return;
|
|
46556
46893
|
}
|
|
46557
46894
|
|
|
@@ -47957,12 +48294,12 @@ define('base/board',[
|
|
|
47957
48294
|
this.inUpdate = true;
|
|
47958
48295
|
|
|
47959
48296
|
if (this.attr.minimizereflow === 'all' && this.containerObj && this.renderer.type !== 'vml') {
|
|
47960
|
-
storeActiveEl = document.activeElement; // Store focus element
|
|
48297
|
+
storeActiveEl = this.document.activeElement; // Store focus element
|
|
47961
48298
|
insert = this.renderer.removeToInsertLater(this.containerObj);
|
|
47962
48299
|
}
|
|
47963
48300
|
|
|
47964
48301
|
if (this.attr.minimizereflow === 'svg' && this.renderer.type === 'svg') {
|
|
47965
|
-
storeActiveEl = document.activeElement;
|
|
48302
|
+
storeActiveEl = this.document.activeElement;
|
|
47966
48303
|
insert = this.renderer.removeToInsertLater(this.renderer.svgRoot);
|
|
47967
48304
|
}
|
|
47968
48305
|
|
|
@@ -48064,6 +48401,7 @@ define('base/board',[
|
|
|
48064
48401
|
for (i = 0; i < parents.length; i++) {
|
|
48065
48402
|
if (Type.isString(parents[i]) &&
|
|
48066
48403
|
!(elementType === 'text' && i === 2) &&
|
|
48404
|
+
!(elementType === 'solidofrevolution3d' && i === 2) &&
|
|
48067
48405
|
!((elementType === 'input' || elementType === 'checkbox' || elementType === 'button') &&
|
|
48068
48406
|
(i === 2 || i === 3)) &&
|
|
48069
48407
|
!(elementType === 'curve' && i > 0) // Allow curve plots with jessiecode
|
|
@@ -48584,7 +48922,7 @@ define('base/board',[
|
|
|
48584
48922
|
o2 = o2.parentNode;
|
|
48585
48923
|
while (o2 !== o) {
|
|
48586
48924
|
this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
|
|
48587
|
-
o2 = o2.parentNode;
|
|
48925
|
+
o2 = o2.parentNode || o2.host;
|
|
48588
48926
|
}
|
|
48589
48927
|
|
|
48590
48928
|
o = o.offsetParent;
|
|
@@ -49154,7 +49492,7 @@ define('base/board',[
|
|
|
49154
49492
|
|
|
49155
49493
|
id = id || this.container;
|
|
49156
49494
|
this._fullscreen_inner_id = id;
|
|
49157
|
-
inner_node = document.getElementById(id);
|
|
49495
|
+
inner_node = this.document.getElementById(id);
|
|
49158
49496
|
wrap_id = 'fullscreenwrap_' + id;
|
|
49159
49497
|
|
|
49160
49498
|
// Wrap a div around the JSXGraph div.
|
|
@@ -49200,16 +49538,16 @@ define('base/board',[
|
|
|
49200
49538
|
return;
|
|
49201
49539
|
}
|
|
49202
49540
|
|
|
49203
|
-
document.fullscreenElement = document.fullscreenElement ||
|
|
49204
|
-
document.webkitFullscreenElement ||
|
|
49205
|
-
document.mozFullscreenElement ||
|
|
49206
|
-
document.msFullscreenElement;
|
|
49541
|
+
this.document.fullscreenElement = this.document.fullscreenElement ||
|
|
49542
|
+
this.document.webkitFullscreenElement ||
|
|
49543
|
+
this.document.mozFullscreenElement ||
|
|
49544
|
+
this.document.msFullscreenElement;
|
|
49207
49545
|
|
|
49208
|
-
inner_node = document.getElementById(inner_id);
|
|
49546
|
+
inner_node = this.document.getElementById(inner_id);
|
|
49209
49547
|
// If full screen mode is started we have to remove CSS margin around the JSXGraph div.
|
|
49210
49548
|
// Otherwise, the positioning of the fullscreen div will be false.
|
|
49211
49549
|
// When leaving the fullscreen mode, the margin is put back in.
|
|
49212
|
-
if (document.fullscreenElement) {
|
|
49550
|
+
if (this.document.fullscreenElement) {
|
|
49213
49551
|
// Just entered fullscreen mode
|
|
49214
49552
|
|
|
49215
49553
|
// Get the data computed in board.toFullscreen()
|
|
@@ -49221,7 +49559,7 @@ define('base/board',[
|
|
|
49221
49559
|
// Further, the CSS margin has to be removed when in fullscreen mode,
|
|
49222
49560
|
// and must be restored later.
|
|
49223
49561
|
inner_node._cssFullscreenStore = {
|
|
49224
|
-
id: document.fullscreenElement.id,
|
|
49562
|
+
id: this.document.fullscreenElement.id,
|
|
49225
49563
|
isFullscreen: true,
|
|
49226
49564
|
margin: inner_node.style.margin,
|
|
49227
49565
|
width: inner_node.style.width,
|
|
@@ -49237,16 +49575,16 @@ define('base/board',[
|
|
|
49237
49575
|
// of the JSXGraph div.
|
|
49238
49576
|
Env.scaleJSXGraphDiv(document.fullscreenElement.id, inner_id, res.scale, res.vshift);
|
|
49239
49577
|
|
|
49240
|
-
// Clear document.fullscreenElement, because Safari doesn't to it and
|
|
49578
|
+
// Clear this.document.fullscreenElement, because Safari doesn't to it and
|
|
49241
49579
|
// when leaving full screen mode it is still set.
|
|
49242
|
-
document.fullscreenElement = null;
|
|
49580
|
+
this.document.fullscreenElement = null;
|
|
49243
49581
|
|
|
49244
49582
|
} else if (Type.exists(inner_node._cssFullscreenStore)) {
|
|
49245
49583
|
// Just left the fullscreen mode
|
|
49246
49584
|
|
|
49247
49585
|
// Remove the CSS rules added in Env.scaleJSXGraphDiv
|
|
49248
49586
|
try {
|
|
49249
|
-
document.styleSheets[document.styleSheets.length - 1].deleteRule(0);
|
|
49587
|
+
this.document.styleSheets[this.document.styleSheets.length - 1].deleteRule(0);
|
|
49250
49588
|
} catch (err) {
|
|
49251
49589
|
console.log('JSXGraph: Could not remove CSS rules for full screen mode');
|
|
49252
49590
|
}
|
|
@@ -49254,7 +49592,6 @@ define('base/board',[
|
|
|
49254
49592
|
inner_node._cssFullscreenStore.isFullscreen = false;
|
|
49255
49593
|
inner_node.style.margin = inner_node._cssFullscreenStore.margin;
|
|
49256
49594
|
inner_node.style.width = inner_node._cssFullscreenStore.width;
|
|
49257
|
-
|
|
49258
49595
|
}
|
|
49259
49596
|
|
|
49260
49597
|
this.updateCSSTransforms();
|
|
@@ -51164,10 +51501,11 @@ define('renderer/svg',[
|
|
|
51164
51501
|
* setTimeout(function() { console.log('done'); }, 400);
|
|
51165
51502
|
*/
|
|
51166
51503
|
dumpToCanvas: function (canvasId, w, h, ignoreTexts) {
|
|
51167
|
-
var svg, tmpImg, cv, ctx
|
|
51504
|
+
var svg, tmpImg, cv, ctx,
|
|
51505
|
+
doc = this.container.ownerDocument;
|
|
51168
51506
|
|
|
51169
51507
|
// Prepare the canvas element
|
|
51170
|
-
cv =
|
|
51508
|
+
cv = doc.getElementById(canvasId);
|
|
51171
51509
|
|
|
51172
51510
|
// Clear the canvas
|
|
51173
51511
|
/* eslint-disable no-self-assign */
|
|
@@ -51303,7 +51641,8 @@ define('renderer/svg',[
|
|
|
51303
51641
|
} else {
|
|
51304
51642
|
// Debug: use canvas element 'jxgbox_canvas' from jsxdev/dump.html
|
|
51305
51643
|
id = 'jxgbox_canvas';
|
|
51306
|
-
canvas = document.getElementById(id);
|
|
51644
|
+
// canvas = document.getElementById(id);
|
|
51645
|
+
canvas = doc.getElementById(id);
|
|
51307
51646
|
}
|
|
51308
51647
|
|
|
51309
51648
|
if (newImg) {
|
|
@@ -51323,7 +51662,8 @@ define('renderer/svg',[
|
|
|
51323
51662
|
}
|
|
51324
51663
|
|
|
51325
51664
|
// Hide navigation bar in board
|
|
51326
|
-
zbar = document.getElementById(this.container.id + '_navigationbar');
|
|
51665
|
+
// zbar = document.getElementById(this.container.id + '_navigationbar');
|
|
51666
|
+
zbar = doc.getElementById(this.container.id + '_navigationbar');
|
|
51327
51667
|
if (Type.exists(zbar)) {
|
|
51328
51668
|
zbarDisplay = zbar.style.display;
|
|
51329
51669
|
zbar.style.display = 'none';
|
|
@@ -54859,6 +55199,7 @@ define('jsxgraph',[
|
|
|
54859
55199
|
*/
|
|
54860
55200
|
_setARIA: function(container, attr) {
|
|
54861
55201
|
var doc = attr.document || document,
|
|
55202
|
+
doc_glob,
|
|
54862
55203
|
node_jsx, newNode, parent,
|
|
54863
55204
|
id_label, id_description;
|
|
54864
55205
|
|
|
@@ -54867,18 +55208,19 @@ define('jsxgraph',[
|
|
|
54867
55208
|
}
|
|
54868
55209
|
|
|
54869
55210
|
node_jsx = doc.getElementById(container);
|
|
55211
|
+
doc_glob = node_jsx.ownerDocument; // This is the window.document element, needed below.
|
|
54870
55212
|
parent = node_jsx.parentNode;
|
|
54871
55213
|
|
|
54872
55214
|
id_label = container + '_ARIAlabel';
|
|
54873
55215
|
id_description = container + '_ARIAdescription';
|
|
54874
55216
|
|
|
54875
|
-
newNode =
|
|
55217
|
+
newNode = doc_glob.createElement('div');
|
|
54876
55218
|
newNode.innerHTML = attr.title;
|
|
54877
55219
|
newNode.setAttribute('id', id_label);
|
|
54878
55220
|
newNode.style.display = 'none';
|
|
54879
55221
|
parent.insertBefore(newNode, node_jsx);
|
|
54880
55222
|
|
|
54881
|
-
newNode =
|
|
55223
|
+
newNode = doc_glob.createElement('div');
|
|
54882
55224
|
newNode.innerHTML = attr.description;
|
|
54883
55225
|
newNode.setAttribute('id', id_description);
|
|
54884
55226
|
newNode.style.display = 'none';
|
|
@@ -54904,12 +55246,12 @@ define('jsxgraph',[
|
|
|
54904
55246
|
}
|
|
54905
55247
|
|
|
54906
55248
|
id = board.containerObj.getAttribute('aria-labelledby');
|
|
54907
|
-
node =
|
|
55249
|
+
node = doc.getElementById(id);
|
|
54908
55250
|
if (node && node.parentNode) {
|
|
54909
55251
|
node.parentNode.removeChild(node);
|
|
54910
55252
|
}
|
|
54911
55253
|
id = board.containerObj.getAttribute('aria-describedby');
|
|
54912
|
-
node =
|
|
55254
|
+
node = doc.getElementById(id);
|
|
54913
55255
|
if (node && node.parentNode) {
|
|
54914
55256
|
node.parentNode.removeChild(node);
|
|
54915
55257
|
}
|
|
@@ -55395,6 +55737,7 @@ define('base/point',[
|
|
|
55395
55737
|
this.board.renderer.drawPoint(this);
|
|
55396
55738
|
this.board.finalizeAdding(this);
|
|
55397
55739
|
|
|
55740
|
+
this.createGradient();
|
|
55398
55741
|
this.createLabel();
|
|
55399
55742
|
|
|
55400
55743
|
};
|
|
@@ -56886,7 +57229,7 @@ define('base/line',[
|
|
|
56886
57229
|
if (this.parents.length < 3) { // Line through two points
|
|
56887
57230
|
this.point1.handleSnapToGrid(true, true);
|
|
56888
57231
|
this.point2.handleSnapToGrid(true, true);
|
|
56889
|
-
|
|
57232
|
+
} else if (Type.exists(pos)) { // Free line
|
|
56890
57233
|
sX = Type.evaluate(this.visProp.snapsizex);
|
|
56891
57234
|
sY = Type.evaluate(this.visProp.snapsizey);
|
|
56892
57235
|
|
|
@@ -61565,8 +61908,35 @@ define('base/polygon',[
|
|
|
61565
61908
|
|
|
61566
61909
|
/**
|
|
61567
61910
|
* Add more points to the polygon. The new points will be inserted at the end.
|
|
61568
|
-
*
|
|
61911
|
+
* The attributes of new border segments are set to the same values
|
|
61912
|
+
* as those used when the polygon was created.
|
|
61913
|
+
* If new vertices are supplied by coordinates, the default attributes of polygon
|
|
61914
|
+
* vertices are taken as their attributes. Therefore, the visual attributes of
|
|
61915
|
+
* new vertices and borders may have to be adapted afterwards.
|
|
61916
|
+
* @param {JXG.Point} p Arbitrary number of points or coordinate arrays
|
|
61569
61917
|
* @returns {JXG.Polygon} Reference to the polygon
|
|
61918
|
+
* @example
|
|
61919
|
+
* const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
|
|
61920
|
+
* var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
|
|
61921
|
+
* var newPoint = board.create('point', [-1, -1]);
|
|
61922
|
+
* var newPoint2 = board.create('point', [-1, -2]);
|
|
61923
|
+
* pg.addPoints(newPoint, newPoint2, [1, -2]);
|
|
61924
|
+
*
|
|
61925
|
+
* </pre><div id="JXG70eb0fd2-d20f-4ba9-9ab6-0eac92aabfa5" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
61926
|
+
* <script type="text/javascript">
|
|
61927
|
+
* (function() {
|
|
61928
|
+
* var board = JXG.JSXGraph.initBoard('JXG70eb0fd2-d20f-4ba9-9ab6-0eac92aabfa5',
|
|
61929
|
+
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
61930
|
+
* const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
|
|
61931
|
+
* var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
|
|
61932
|
+
* var newPoint = board.create('point', [-1, -1]);
|
|
61933
|
+
* var newPoint2 = board.create('point', [-1, -2]);
|
|
61934
|
+
* pg.addPoints(newPoint, newPoint2, [1, -2]);
|
|
61935
|
+
*
|
|
61936
|
+
* })();
|
|
61937
|
+
*
|
|
61938
|
+
* </script><pre>
|
|
61939
|
+
*
|
|
61570
61940
|
*/
|
|
61571
61941
|
addPoints: function (p) {
|
|
61572
61942
|
var args = Array.prototype.slice.call(arguments);
|
|
@@ -61575,44 +61945,72 @@ define('base/polygon',[
|
|
|
61575
61945
|
},
|
|
61576
61946
|
|
|
61577
61947
|
/**
|
|
61578
|
-
*
|
|
61579
|
-
*
|
|
61580
|
-
*
|
|
61948
|
+
* Insert points to the vertex list of the polygon after index <tt><idx</tt>.
|
|
61949
|
+
* The attributes of new border segments are set to the same values
|
|
61950
|
+
* as those used when the polygon was created.
|
|
61951
|
+
* If new vertices are supplied by coordinates, the default attributes of polygon
|
|
61952
|
+
* vertices are taken as their attributes. Therefore, the visual attributes of
|
|
61953
|
+
* new vertices and borders may have to be adapted afterwards.
|
|
61954
|
+
*
|
|
61955
|
+
* @param {Number} idx The position after which the new vertices are inserted.
|
|
61956
|
+
* Setting idx to -1 inserts the new points at the front, i.e. at position 0.
|
|
61957
|
+
* @param {JXG.Point} p Arbitrary number of points or coordinate arrays to insert.
|
|
61581
61958
|
* @returns {JXG.Polygon} Reference to the polygon object
|
|
61959
|
+
*
|
|
61960
|
+
* @example
|
|
61961
|
+
* const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
|
|
61962
|
+
* var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
|
|
61963
|
+
* var newPoint = board.create('point', [-1, -1]);
|
|
61964
|
+
* pg.insertPoints(0, newPoint, newPoint, [1, -2]);
|
|
61965
|
+
*
|
|
61966
|
+
* </pre><div id="JXG17b84b2a-a851-4e3f-824f-7f6a60f166ca" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
61967
|
+
* <script type="text/javascript">
|
|
61968
|
+
* (function() {
|
|
61969
|
+
* var board = JXG.JSXGraph.initBoard('JXG17b84b2a-a851-4e3f-824f-7f6a60f166ca',
|
|
61970
|
+
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
61971
|
+
* const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
|
|
61972
|
+
* var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
|
|
61973
|
+
* var newPoint = board.create('point', [-1, -1]);
|
|
61974
|
+
* pg.insertPoints(0, newPoint, newPoint, [1, -2]);
|
|
61975
|
+
*
|
|
61976
|
+
* })();
|
|
61977
|
+
*
|
|
61978
|
+
* </script><pre>
|
|
61979
|
+
*
|
|
61582
61980
|
*/
|
|
61583
61981
|
insertPoints: function (idx, p) {
|
|
61584
|
-
var i,
|
|
61982
|
+
var i, le;
|
|
61585
61983
|
|
|
61586
61984
|
if (arguments.length === 0) {
|
|
61587
61985
|
return this;
|
|
61588
61986
|
}
|
|
61589
61987
|
|
|
61590
61988
|
|
|
61591
|
-
if (idx <
|
|
61989
|
+
if (idx < -1 || idx > this.vertices.length - 2) {
|
|
61592
61990
|
return this;
|
|
61593
61991
|
}
|
|
61594
61992
|
|
|
61595
|
-
|
|
61596
|
-
|
|
61597
|
-
|
|
61598
|
-
|
|
61993
|
+
le = arguments.length - 1;
|
|
61994
|
+
for (i = 1; i < le + 1; i++) {
|
|
61995
|
+
this.vertices.splice(idx + i, 0,
|
|
61996
|
+
Type.providePoints(this.board, [arguments[i]], {}, 'polygon', ['vertices'])[0]
|
|
61997
|
+
);
|
|
61998
|
+
}
|
|
61999
|
+
if (idx === -1) {
|
|
62000
|
+
this.vertices[this.vertices.length - 1] = this.vertices[0];
|
|
61599
62001
|
}
|
|
61600
|
-
|
|
61601
|
-
tmp = this.vertices.slice(0, idx + 1).concat(npoints);
|
|
61602
|
-
this.vertices = tmp.concat(this.vertices.slice(idx + 1));
|
|
61603
|
-
|
|
61604
62002
|
if (this.withLines) {
|
|
61605
|
-
|
|
61606
|
-
|
|
61607
|
-
|
|
61608
|
-
|
|
61609
|
-
|
|
62003
|
+
if (idx < 0) {
|
|
62004
|
+
this.borders[this.borders.length - 1].point2 = this.vertices[this.vertices.length - 1];
|
|
62005
|
+
} else {
|
|
62006
|
+
this.borders[idx].point2 = this.vertices[idx + 1];
|
|
62007
|
+
}
|
|
62008
|
+
for (i = idx + 1; i < idx + 1 + le; i++) {
|
|
62009
|
+
this.borders.splice(i, 0,
|
|
62010
|
+
this.board.create('segment', [this.vertices[i], this.vertices[i + 1]], this.attr_line)
|
|
62011
|
+
);
|
|
61610
62012
|
}
|
|
61611
|
-
|
|
61612
|
-
tmp.push(this.board.create('segment', [this.vertices[idx + npoints.length], this.vertices[idx + npoints.length + 1]], this.attr_line));
|
|
61613
|
-
this.borders = tmp.concat(this.borders.slice(idx + 1));
|
|
61614
62013
|
}
|
|
61615
|
-
|
|
61616
62014
|
this.board.update();
|
|
61617
62015
|
|
|
61618
62016
|
return this;
|
|
@@ -61627,7 +62025,7 @@ define('base/polygon',[
|
|
|
61627
62025
|
var i, j, idx, nvertices = [], nborders = [],
|
|
61628
62026
|
nidx = [], partition = [];
|
|
61629
62027
|
|
|
61630
|
-
//
|
|
62028
|
+
// Partition:
|
|
61631
62029
|
// in order to keep the borders which could be recycled, we have to partition
|
|
61632
62030
|
// the set of removed points. I.e. if the points 1, 2, 5, 6, 7, 10 are removed,
|
|
61633
62031
|
// the partitions are
|
|
@@ -61635,10 +62033,10 @@ define('base/polygon',[
|
|
|
61635
62033
|
// this gives us the borders, that can be removed and the borders we have to create.
|
|
61636
62034
|
|
|
61637
62035
|
|
|
61638
|
-
//
|
|
62036
|
+
// Remove the last vertex which is identical to the first
|
|
61639
62037
|
this.vertices = this.vertices.slice(0, this.vertices.length - 1);
|
|
61640
62038
|
|
|
61641
|
-
//
|
|
62039
|
+
// Collect all valid parameters as indices in nidx
|
|
61642
62040
|
for (i = 0; i < arguments.length; i++) {
|
|
61643
62041
|
idx = arguments[i];
|
|
61644
62042
|
if (Type.isPoint(idx)) {
|
|
@@ -61650,22 +62048,22 @@ define('base/polygon',[
|
|
|
61650
62048
|
}
|
|
61651
62049
|
}
|
|
61652
62050
|
|
|
61653
|
-
//
|
|
62051
|
+
// Remove the polygon from each removed point's children
|
|
61654
62052
|
for (i = 0; i < nidx.length; i++) {
|
|
61655
62053
|
this.vertices[nidx[i]].removeChild(this);
|
|
61656
62054
|
}
|
|
61657
62055
|
|
|
61658
|
-
//
|
|
62056
|
+
// Sort the elements to be eliminated
|
|
61659
62057
|
nidx = nidx.sort();
|
|
61660
62058
|
nvertices = this.vertices.slice();
|
|
61661
62059
|
nborders = this.borders.slice();
|
|
61662
62060
|
|
|
61663
|
-
//
|
|
62061
|
+
// Initialize the partition
|
|
61664
62062
|
if (this.withLines) {
|
|
61665
62063
|
partition.push([nidx[nidx.length - 1]]);
|
|
61666
62064
|
}
|
|
61667
62065
|
|
|
61668
|
-
//
|
|
62066
|
+
// Run through all existing vertices and copy all remaining ones to nvertices,
|
|
61669
62067
|
// compute the partition
|
|
61670
62068
|
for (i = nidx.length - 1; i > -1; i--) {
|
|
61671
62069
|
nvertices[nidx[i]] = -1;
|
|
@@ -61676,12 +62074,12 @@ define('base/polygon',[
|
|
|
61676
62074
|
}
|
|
61677
62075
|
}
|
|
61678
62076
|
|
|
61679
|
-
//
|
|
62077
|
+
// Finalize the partition computation
|
|
61680
62078
|
if (this.withLines) {
|
|
61681
62079
|
partition[partition.length - 1][1] = nidx[0];
|
|
61682
62080
|
}
|
|
61683
62081
|
|
|
61684
|
-
//
|
|
62082
|
+
// Update vertices
|
|
61685
62083
|
this.vertices = [];
|
|
61686
62084
|
for (i = 0; i < nvertices.length; i++) {
|
|
61687
62085
|
if (Type.isPoint(nvertices[i])) {
|
|
@@ -61692,7 +62090,7 @@ define('base/polygon',[
|
|
|
61692
62090
|
this.vertices.push(this.vertices[0]);
|
|
61693
62091
|
}
|
|
61694
62092
|
|
|
61695
|
-
//
|
|
62093
|
+
// Delete obsolete and create missing borders
|
|
61696
62094
|
if (this.withLines) {
|
|
61697
62095
|
for (i = 0; i < partition.length; i++) {
|
|
61698
62096
|
for (j = partition[i][1] - 1; j < partition[i][0] + 1; j++) {
|
|
@@ -68552,9 +68950,6 @@ define('element/composition',[
|
|
|
68552
68950
|
b.addChild(t);
|
|
68553
68951
|
}
|
|
68554
68952
|
|
|
68555
|
-
|
|
68556
|
-
|
|
68557
|
-
|
|
68558
68953
|
t.elType = 'midpoint';
|
|
68559
68954
|
t.setParents([a.id, b.id]);
|
|
68560
68955
|
|
|
@@ -68764,14 +69159,21 @@ define('element/composition',[
|
|
|
68764
69159
|
};
|
|
68765
69160
|
|
|
68766
69161
|
/**
|
|
68767
|
-
* @class A parallel is a line through a given point with the same slope as a given line
|
|
69162
|
+
* @class A parallel is a line through a given point with the same slope as a given line or
|
|
69163
|
+
* the line through two given point.
|
|
69164
|
+
* <p>
|
|
69165
|
+
* If original line is given as a JSXGraph line object, the resulting parallel line will be defined by the given point and an
|
|
69166
|
+
* infinitely far away point (an ideal point). That means, the line can not be shortened to a segment.
|
|
69167
|
+
* <p>
|
|
69168
|
+
* If the original line is given as two points, the resulting parallel line can be shortened to a a segment.
|
|
68768
69169
|
* @pseudo
|
|
68769
69170
|
* @name Parallel
|
|
68770
69171
|
* @augments Line
|
|
68771
69172
|
* @constructor
|
|
68772
69173
|
* @type JXG.Line
|
|
68773
69174
|
* @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
68774
|
-
* @param {JXG.Line_JXG.Point} l,p The constructed line contains p and has the same slope as l.
|
|
69175
|
+
* @param {JXG.Line_JXG.Point} l,p The constructed line contains p and has the same slope as l. Alternative parameters are p1, p2, p: The
|
|
69176
|
+
* constructed line contains p and has the same slope as the line through p1 and p2.
|
|
68775
69177
|
* @example
|
|
68776
69178
|
* // Create a parallel
|
|
68777
69179
|
* var p1 = board.create('point', [0.0, 2.0]);
|
|
@@ -68789,22 +69191,47 @@ define('element/composition',[
|
|
|
68789
69191
|
* var plex1_p3 = plex1_board.create('point', [3.0, 3.0]);
|
|
68790
69192
|
* var plex1_pl1 = plex1_board.create('parallel', [plex1_l1, plex1_p3]);
|
|
68791
69193
|
* </script><pre>
|
|
69194
|
+
* @example
|
|
69195
|
+
* var p1, p2, p3, l1, pl1;
|
|
69196
|
+
*
|
|
69197
|
+
* p1 = board.create('point', [0.0, 2.0]);
|
|
69198
|
+
* p2 = board.create('point', [2.0, 1.0]);
|
|
69199
|
+
* l1 = board.create('line', [p1, p2]);
|
|
69200
|
+
*
|
|
69201
|
+
* p3 = board.create('point', [1.0, 3.0]);
|
|
69202
|
+
* pl1 = board.create('parallel', [p1, p2, p3], {straightFirst: false, straightLast: false});
|
|
69203
|
+
*
|
|
69204
|
+
* </pre><div id="JXGd643305d-20c3-4a88-91f9-8d0c4448594f" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
69205
|
+
* <script type="text/javascript">
|
|
69206
|
+
* (function() {
|
|
69207
|
+
* var board = JXG.JSXGraph.initBoard('JXGd643305d-20c3-4a88-91f9-8d0c4448594f',
|
|
69208
|
+
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
69209
|
+
* var p1, p2, p3, l1, pl1;
|
|
69210
|
+
*
|
|
69211
|
+
* p1 = board.create('point', [0.0, 2.0]);
|
|
69212
|
+
* p2 = board.create('point', [2.0, 1.0]);
|
|
69213
|
+
* l1 = board.create('line', [p1, p2]);
|
|
69214
|
+
*
|
|
69215
|
+
* p3 = board.create('point', [1.0, 3.0]);
|
|
69216
|
+
* pl1 = board.create('parallel', [p1, p2, p3], {straightFirst: false, straightLast: false});
|
|
69217
|
+
*
|
|
69218
|
+
* })();
|
|
69219
|
+
*
|
|
69220
|
+
* </script><pre>
|
|
69221
|
+
*
|
|
68792
69222
|
*/
|
|
68793
69223
|
JXG.createParallel = function (board, parents, attributes) {
|
|
68794
|
-
var p, pp, pl, li, i, attr;
|
|
69224
|
+
var p, pp, pl, li, i, attr, ty = 1;
|
|
68795
69225
|
|
|
68796
69226
|
for (i = 0; i < parents.length; ++i) {
|
|
68797
69227
|
parents[i] = board.select(parents[i]);
|
|
68798
69228
|
}
|
|
68799
69229
|
p = null;
|
|
68800
69230
|
if (parents.length === 3) {
|
|
69231
|
+
// Line / segment through point parents[2] which is parallel to line through parents[0] and parents[1]
|
|
68801
69232
|
parents = Type.providePoints(board, parents, attributes, 'point');
|
|
68802
|
-
// line through point parents[2] which is parallel to line through parents[0] and parents[1]
|
|
68803
69233
|
p = parents[2];
|
|
68804
|
-
|
|
68805
|
-
li = function () {
|
|
68806
|
-
return Mat.crossProduct(parents[0].coords.usrCoords, parents[1].coords.usrCoords);
|
|
68807
|
-
};
|
|
69234
|
+
ty = 0;
|
|
68808
69235
|
} else if (Type.isPointType(board, parents[0])) {
|
|
68809
69236
|
// Parallel to line parents[1] through point parents[0]
|
|
68810
69237
|
p = Type.providePoints(board, [parents[0]], attributes, 'point')[0];
|
|
@@ -68826,11 +69253,19 @@ define('element/composition',[
|
|
|
68826
69253
|
}
|
|
68827
69254
|
|
|
68828
69255
|
attr = Type.copyAttributes(attributes, board.options, 'parallel', 'point');
|
|
68829
|
-
|
|
68830
|
-
|
|
68831
|
-
|
|
68832
|
-
|
|
68833
|
-
|
|
69256
|
+
if (ty === 1) {
|
|
69257
|
+
// Line is given by line element. The parallel line is
|
|
69258
|
+
// constructed as line through an ideal point.
|
|
69259
|
+
pp = board.create('point', [
|
|
69260
|
+
function () {
|
|
69261
|
+
return Mat.crossProduct([1, 0, 0], li());
|
|
69262
|
+
}
|
|
69263
|
+
], attr);
|
|
69264
|
+
} else {
|
|
69265
|
+
// Line is given by two points. The parallel line is
|
|
69266
|
+
// constructed as line through two finite point.
|
|
69267
|
+
pp = board.create('parallelpoint', parents, attr);
|
|
69268
|
+
}
|
|
68834
69269
|
pp.isDraggable = true;
|
|
68835
69270
|
|
|
68836
69271
|
attr = Type.copyAttributes(attributes, board.options, 'parallel');
|
|
@@ -68864,31 +69299,33 @@ define('element/composition',[
|
|
|
68864
69299
|
};
|
|
68865
69300
|
|
|
68866
69301
|
/**
|
|
68867
|
-
* @class An arrow parallel is a
|
|
69302
|
+
* @class An arrow parallel is a segment with an arrow attached which is parallel through a given segment, given by its defining two points,
|
|
69303
|
+
* through a given point.
|
|
69304
|
+
* <p>
|
|
68868
69305
|
* @pseudo
|
|
68869
69306
|
* @constructor
|
|
68870
69307
|
* @name Arrowparallel
|
|
68871
69308
|
* @type Parallel
|
|
68872
69309
|
* @augments Parallel
|
|
68873
69310
|
* @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
68874
|
-
* @param
|
|
69311
|
+
* @param JXG.Point_JXG.Point_JXG.Point} p1, p2,p3 The constructed arrow contains p3 and has the same slope as the line through p1 and p2.
|
|
68875
69312
|
* @example
|
|
68876
69313
|
* // Create a parallel
|
|
68877
69314
|
* var p1 = board.create('point', [0.0, 2.0]);
|
|
68878
69315
|
* var p2 = board.create('point', [2.0, 1.0]);
|
|
68879
|
-
* var l1 = board.create('
|
|
69316
|
+
* var l1 = board.create('segment', [p1, p2]);
|
|
68880
69317
|
*
|
|
68881
69318
|
* var p3 = board.create('point', [3.0, 3.0]);
|
|
68882
|
-
* var pl1 = board.create('arrowparallel', [
|
|
69319
|
+
* var pl1 = board.create('arrowparallel', [p1, p2, p3]);
|
|
68883
69320
|
* </pre><div class="jxgbox" id="JXGeeacdf99-036f-4e83-aeb6-f7388423e369" style="width: 400px; height: 400px;"></div>
|
|
68884
69321
|
* <script type="text/javascript">
|
|
68885
69322
|
* (function () {
|
|
68886
69323
|
* var plex1_board = JXG.JSXGraph.initBoard('JXGeeacdf99-036f-4e83-aeb6-f7388423e369', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});
|
|
68887
69324
|
* var plex1_p1 = plex1_board.create('point', [0.0, 2.0]);
|
|
68888
69325
|
* var plex1_p2 = plex1_board.create('point', [2.0, 1.0]);
|
|
68889
|
-
* var plex1_l1 = plex1_board.create('
|
|
69326
|
+
* var plex1_l1 = plex1_board.create('segment', [plex1_p1, plex1_p2]);
|
|
68890
69327
|
* var plex1_p3 = plex1_board.create('point', [3.0, 3.0]);
|
|
68891
|
-
* var plex1_pl1 = plex1_board.create('arrowparallel', [
|
|
69328
|
+
* var plex1_pl1 = plex1_board.create('arrowparallel', [plex1_p1, plex1_p2, plex1_p3]);
|
|
68892
69329
|
* })();
|
|
68893
69330
|
* </script><pre>
|
|
68894
69331
|
*/
|
|
@@ -69335,7 +69772,7 @@ define('element/composition',[
|
|
|
69335
69772
|
};
|
|
69336
69773
|
|
|
69337
69774
|
/**
|
|
69338
|
-
* @class Bisector lines are similar to {@link Bisector} but
|
|
69775
|
+
* @class Bisector lines are similar to {@link Bisector} but take two lines as parent elements. The resulting element is
|
|
69339
69776
|
* a composition of two lines.
|
|
69340
69777
|
* @pseudo
|
|
69341
69778
|
* @constructor
|
|
@@ -72092,6 +72529,10 @@ define('element/slider',[
|
|
|
72092
72529
|
p2.dump = false;
|
|
72093
72530
|
l1.dump = false;
|
|
72094
72531
|
l2.dump = false;
|
|
72532
|
+
if (withText) {
|
|
72533
|
+
t.dump = false;
|
|
72534
|
+
}
|
|
72535
|
+
|
|
72095
72536
|
|
|
72096
72537
|
p3.elType = 'slider';
|
|
72097
72538
|
p3.parents = parents;
|
|
@@ -72109,6 +72550,14 @@ define('element/slider',[
|
|
|
72109
72550
|
p3.inherits.push(ti);
|
|
72110
72551
|
}
|
|
72111
72552
|
|
|
72553
|
+
p3.getParents = function() {
|
|
72554
|
+
return [
|
|
72555
|
+
this.point1.coords.usrCoords.slice(1),
|
|
72556
|
+
this.point2.coords.usrCoords.slice(1),
|
|
72557
|
+
[this._smin, this.position * (this._smax - this._smin) + this._smin, this._smax]
|
|
72558
|
+
];
|
|
72559
|
+
};
|
|
72560
|
+
|
|
72112
72561
|
p3.baseline.on('up', function(evt) {
|
|
72113
72562
|
var pos, c;
|
|
72114
72563
|
|
|
@@ -75831,12 +76280,13 @@ define('base/ticks',[
|
|
|
75831
76280
|
* @private
|
|
75832
76281
|
*/
|
|
75833
76282
|
formatLabelText: function(value) {
|
|
75834
|
-
var labelText
|
|
76283
|
+
var labelText,
|
|
75835
76284
|
digits,
|
|
75836
76285
|
ev_s = Type.evaluate(this.visProp.scalesymbol);
|
|
75837
76286
|
|
|
75838
76287
|
// if value is Number
|
|
75839
76288
|
if (Type.isNumber(value)) {
|
|
76289
|
+
labelText = (Math.round(value * 1.e13) / 1.e13).toString();
|
|
75840
76290
|
if (labelText.length > Type.evaluate(this.visProp.maxlabellength) ||
|
|
75841
76291
|
labelText.indexOf('e') !== -1) {
|
|
75842
76292
|
|
|
@@ -75845,7 +76295,9 @@ define('base/ticks',[
|
|
|
75845
76295
|
// Use the deprecated attribute "precision"
|
|
75846
76296
|
digits = Type.evaluate(this.visProp.precision);
|
|
75847
76297
|
}
|
|
75848
|
-
|
|
76298
|
+
|
|
76299
|
+
//labelText = value.toPrecision(digits).toString();
|
|
76300
|
+
labelText = value.toExponential(digits).toString();
|
|
75849
76301
|
}
|
|
75850
76302
|
|
|
75851
76303
|
if (Type.evaluate(this.visProp.beautifulscientificticklabels)) {
|
|
@@ -75858,6 +76310,8 @@ define('base/ticks',[
|
|
|
75858
76310
|
// trim trailing .
|
|
75859
76311
|
labelText = labelText.replace(/\.$/, '');
|
|
75860
76312
|
}
|
|
76313
|
+
} else {
|
|
76314
|
+
labelText = value.toString();
|
|
75861
76315
|
}
|
|
75862
76316
|
|
|
75863
76317
|
if (ev_s.length > 0) {
|
|
@@ -76077,6 +76531,8 @@ define('base/ticks',[
|
|
|
76077
76531
|
attr.id = this.id + ld.i + 'Label' + this.labelCounter;
|
|
76078
76532
|
|
|
76079
76533
|
label = Text.createText(this.board, [ld.x, ld.y, ld.t], attr);
|
|
76534
|
+
this.addChild(label);
|
|
76535
|
+
label.setParents(this);
|
|
76080
76536
|
label.isDraggable = false;
|
|
76081
76537
|
label.dump = false;
|
|
76082
76538
|
this.labels.push(label);
|
|
@@ -79618,7 +80074,13 @@ define('element/button',[
|
|
|
79618
80074
|
* an SVG foreignObject container.
|
|
79619
80075
|
* <p>
|
|
79620
80076
|
* Instead of board.create('foreignobject') the shortcut board.create('fo') may be used.
|
|
79621
|
-
*
|
|
80077
|
+
*
|
|
80078
|
+
* <p style="background-color:#dddddd; padding:10px"><b>NOTE:</b> In Safari up to version 15, a foreignObject does not obey the layer structure
|
|
80079
|
+
* if it contains <video> or <iframe> tags, as well as elements which are
|
|
80080
|
+
* positioned with <tt>position:absolute|relative|fixed</tt>. In this case, the foreignobject will be
|
|
80081
|
+
* "above" the JSXGraph construction.
|
|
80082
|
+
* </p>
|
|
80083
|
+
*
|
|
79622
80084
|
* @pseudo
|
|
79623
80085
|
* @description
|
|
79624
80086
|
* @name ForeignObject
|
|
@@ -79756,6 +80218,2002 @@ define('element/button',[
|
|
|
79756
80218
|
};
|
|
79757
80219
|
});
|
|
79758
80220
|
|
|
80221
|
+
/*global JXG:true, define: true*/
|
|
80222
|
+
|
|
80223
|
+
define('options3d',[
|
|
80224
|
+
'jxg', 'options'
|
|
80225
|
+
], function (JXG, Options) {
|
|
80226
|
+
|
|
80227
|
+
"use strict";
|
|
80228
|
+
|
|
80229
|
+
JXG.extend(Options, {
|
|
80230
|
+
|
|
80231
|
+
infobox: {
|
|
80232
|
+
strokeColor: 'black'
|
|
80233
|
+
},
|
|
80234
|
+
|
|
80235
|
+
axes3d: {
|
|
80236
|
+
/**#@+
|
|
80237
|
+
* @visprop
|
|
80238
|
+
*/
|
|
80239
|
+
|
|
80240
|
+
/**
|
|
80241
|
+
* Position of the main axes in a View3D element. Possible values are
|
|
80242
|
+
* 'center' and 'border'.
|
|
80243
|
+
*
|
|
80244
|
+
* @type String
|
|
80245
|
+
* @name View3D#axesPosition
|
|
80246
|
+
* @default 'center'
|
|
80247
|
+
*/
|
|
80248
|
+
axesPosition: 'center', // Possible values: 'center', otherwise: border
|
|
80249
|
+
|
|
80250
|
+
// Main axes
|
|
80251
|
+
|
|
80252
|
+
/**
|
|
80253
|
+
* Attributes of the 3D x-axis.
|
|
80254
|
+
*
|
|
80255
|
+
* @type Line3D
|
|
80256
|
+
* @name View3D#xAxis
|
|
80257
|
+
*/
|
|
80258
|
+
xAxis: { visible: true, point2: {name: 'x'}},
|
|
80259
|
+
|
|
80260
|
+
/**
|
|
80261
|
+
* Attributes of the 3D y-axis.
|
|
80262
|
+
*
|
|
80263
|
+
* @type Line3D
|
|
80264
|
+
* @name View3D#yAxis
|
|
80265
|
+
*/
|
|
80266
|
+
yAxis: { visible: true, point2: {name: 'y'}},
|
|
80267
|
+
|
|
80268
|
+
/**
|
|
80269
|
+
* Attributes of the 3D z-axis.
|
|
80270
|
+
*
|
|
80271
|
+
* @type Line3D
|
|
80272
|
+
* @name View3D#zAxis
|
|
80273
|
+
*/
|
|
80274
|
+
zAxis: { visible: true, point2: {name: 'z'}},
|
|
80275
|
+
|
|
80276
|
+
// Planes
|
|
80277
|
+
/**
|
|
80278
|
+
* Attributes of the 3D plane orthogonal to the x-axis at the "rear" of the cube.
|
|
80279
|
+
* @type Plane3D
|
|
80280
|
+
* @name View3D#xPlaneRear
|
|
80281
|
+
*/
|
|
80282
|
+
xPlaneRear: { visible: true, layer: 0, mesh3d: { layer: 1 } },
|
|
80283
|
+
/**
|
|
80284
|
+
* Attributes of the 3D plane orthogonal to the y-axis at the "rear" of the cube.
|
|
80285
|
+
* @type Plane3D
|
|
80286
|
+
* @name View3D#yPlaneRear
|
|
80287
|
+
*/
|
|
80288
|
+
yPlaneRear: { visible: true, layer: 0, mesh3d: { layer: 1 } },
|
|
80289
|
+
/**
|
|
80290
|
+
* Attributes of the 3D plane orthogonal to the z-axis at the "rear" of the cube.
|
|
80291
|
+
* @type Plane3D
|
|
80292
|
+
* @name View3D#zPlaneRear
|
|
80293
|
+
*/
|
|
80294
|
+
zPlaneRear: { visible: true, layer: 0, mesh3d: { layer: 1 } },
|
|
80295
|
+
|
|
80296
|
+
/**
|
|
80297
|
+
* Attributes of the 3D plane orthogonal to the x-axis at the "front" of the cube.
|
|
80298
|
+
* @type Plane3D
|
|
80299
|
+
* @name View3D#xPlaneFront
|
|
80300
|
+
*/
|
|
80301
|
+
xPlaneFront: { visible: false, layer: 0, mesh3d: { layer: 1 } },
|
|
80302
|
+
/**
|
|
80303
|
+
* Attributes of the 3D plane orthogonal to the y-axis at the "front" of the cube.
|
|
80304
|
+
* @type Plane3D
|
|
80305
|
+
* @name View3D#yPlaneFront
|
|
80306
|
+
*/
|
|
80307
|
+
yPlaneFront: { visible: false, layer: 0, mesh3d: { layer: 1 } },
|
|
80308
|
+
/**
|
|
80309
|
+
* Attributes of the 3D plane orthogonal to the z-axis at the "front" of the cube.
|
|
80310
|
+
* @type Plane3D
|
|
80311
|
+
* @name View3D#zPlaneFront
|
|
80312
|
+
*/
|
|
80313
|
+
zPlaneFront: { visible: false, layer: 0, mesh3d: { layer: 1 } },
|
|
80314
|
+
|
|
80315
|
+
// Axes on the planes
|
|
80316
|
+
/**
|
|
80317
|
+
* Attributes of the 3D y-axis on the 3D plane orthogonal to the x-axis at the "rear" of the cube.
|
|
80318
|
+
* @type Plane3D
|
|
80319
|
+
* @name View3D#xPlaneRearYAxis
|
|
80320
|
+
*/
|
|
80321
|
+
xPlaneRearYAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80322
|
+
/**
|
|
80323
|
+
* Attributes of the 3D z-axis on the 3D plane orthogonal to the x-axis at the "rear" of the cube.
|
|
80324
|
+
* @type Plane3D
|
|
80325
|
+
* @name View3D#xPlaneRearZAxis
|
|
80326
|
+
*/
|
|
80327
|
+
xPlaneRearZAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80328
|
+
/**
|
|
80329
|
+
* Attributes of the 3D y-axis on the 3D plane orthogonal to the x-axis at the "front" of the cube.
|
|
80330
|
+
* @type Plane3D
|
|
80331
|
+
* @name View3D#xPlaneFrontYAxis
|
|
80332
|
+
*/
|
|
80333
|
+
xPlaneFrontYAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80334
|
+
/**
|
|
80335
|
+
* Attributes of the 3D z-axis on the 3D plane orthogonal to the x-axis at the "front" of the cube.
|
|
80336
|
+
* @type Plane3D
|
|
80337
|
+
* @name View3D#xPlaneFrontZAxis
|
|
80338
|
+
*/
|
|
80339
|
+
xPlaneFrontZAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80340
|
+
|
|
80341
|
+
/**
|
|
80342
|
+
* Attributes of the 3D x-axis on the 3D plane orthogonal to the y-axis at the "rear" of the cube.
|
|
80343
|
+
* @type Plane3D
|
|
80344
|
+
* @name View3D#yPlaneRearXAxis
|
|
80345
|
+
*/
|
|
80346
|
+
yPlaneRearXAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80347
|
+
/**
|
|
80348
|
+
* Attributes of the 3D z-axis on the 3D plane orthogonal to the y-axis at the "rear" of the cube.
|
|
80349
|
+
* @type Plane3D
|
|
80350
|
+
* @name View3D#yPlaneRearZAxis
|
|
80351
|
+
*/
|
|
80352
|
+
yPlaneRearZAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80353
|
+
/**
|
|
80354
|
+
* Attributes of the 3D x-axis on the 3D plane orthogonal to the y-axis at the "front" of the cube.
|
|
80355
|
+
* @type Plane3D
|
|
80356
|
+
* @name View3D#yPlaneFrontXAxis
|
|
80357
|
+
*/
|
|
80358
|
+
yPlaneFrontXAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80359
|
+
/**
|
|
80360
|
+
* Attributes of the 3D z-axis on the 3D plane orthogonal to the y-axis at the "front" of the cube.
|
|
80361
|
+
* @type Plane3D
|
|
80362
|
+
* @name View3D#yPlaneFrontZAxis
|
|
80363
|
+
*/
|
|
80364
|
+
yPlaneFrontZAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80365
|
+
|
|
80366
|
+
/**
|
|
80367
|
+
* Attributes of the 3D x-axis on the 3D plane orthogonal to the z-axis at the "rear" of the cube.
|
|
80368
|
+
* @type Plane3D
|
|
80369
|
+
* @name View3D#zPlaneRearXAxis
|
|
80370
|
+
*/
|
|
80371
|
+
zPlaneRearXAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80372
|
+
/**
|
|
80373
|
+
* Attributes of the 3D y-axis on the 3D plane orthogonal to the z-axis at the "rear" of the cube.
|
|
80374
|
+
* @type Plane3D
|
|
80375
|
+
* @name View3D#zPlaneRearYAxis
|
|
80376
|
+
*/
|
|
80377
|
+
zPlaneRearYAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80378
|
+
/**
|
|
80379
|
+
* Attributes of the 3D x-axis on the 3D plane orthogonal to the z-axis at the "front" of the cube.
|
|
80380
|
+
* @type Plane3D
|
|
80381
|
+
* @name View3D#zPlaneFrontXAxis
|
|
80382
|
+
*/
|
|
80383
|
+
zPlaneFrontXAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80384
|
+
/**
|
|
80385
|
+
* Attributes of the 3D y-axis on the 3D plane orthogonal to the z-axis at the "front" of the cube.
|
|
80386
|
+
* @type Plane3D
|
|
80387
|
+
* @name View3D#zPlaneFrontYAxis
|
|
80388
|
+
*/
|
|
80389
|
+
zPlaneFrontYAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1}
|
|
80390
|
+
|
|
80391
|
+
/**#@-*/
|
|
80392
|
+
},
|
|
80393
|
+
|
|
80394
|
+
axis3d: {
|
|
80395
|
+
highlight: false,
|
|
80396
|
+
strokecolor: 'black',
|
|
80397
|
+
strokeWidth: 1,
|
|
80398
|
+
tabindex: null,
|
|
80399
|
+
|
|
80400
|
+
point1: { visible: false, name: '' },
|
|
80401
|
+
point2: { visible: false, name: '', label: { visible: true } }
|
|
80402
|
+
},
|
|
80403
|
+
|
|
80404
|
+
mesh3d: {
|
|
80405
|
+
strokeWidth: 1,
|
|
80406
|
+
strokeColor: '#9a9a9a',
|
|
80407
|
+
strokeOpacity: 0.6,
|
|
80408
|
+
highlight: false,
|
|
80409
|
+
fillColor: '#9a9a9a',
|
|
80410
|
+
fillOpacity: 0.1,
|
|
80411
|
+
tabindex: null,
|
|
80412
|
+
|
|
80413
|
+
visible: 'inherit'
|
|
80414
|
+
},
|
|
80415
|
+
|
|
80416
|
+
line3d: {
|
|
80417
|
+
strokeWidth: 1,
|
|
80418
|
+
strokeColor: 'black',
|
|
80419
|
+
fixed: true,
|
|
80420
|
+
tabindex: null,
|
|
80421
|
+
|
|
80422
|
+
gradient: 'linear',
|
|
80423
|
+
gradientSecondColor: '#ffffff',
|
|
80424
|
+
|
|
80425
|
+
point1: {visible: false, name: ''},
|
|
80426
|
+
point2: {visible: false, name: ''}
|
|
80427
|
+
},
|
|
80428
|
+
|
|
80429
|
+
plane3d: {
|
|
80430
|
+
strokeWidth: 0,
|
|
80431
|
+
strokeColor: 'black',
|
|
80432
|
+
strokeOpacity: 1,
|
|
80433
|
+
highlight: false,
|
|
80434
|
+
tabindex: null,
|
|
80435
|
+
|
|
80436
|
+
gradient: 'linear',
|
|
80437
|
+
gradientSecondColor: '#ffffff',
|
|
80438
|
+
gradientAngle: Math.PI,
|
|
80439
|
+
fillColor: '#a7a7a7',
|
|
80440
|
+
fillOpacity: 0.6
|
|
80441
|
+
},
|
|
80442
|
+
|
|
80443
|
+
point3d: {
|
|
80444
|
+
strokeWidth: 0,
|
|
80445
|
+
gradient: 'radial',
|
|
80446
|
+
gradientSecondColor: '#555555',
|
|
80447
|
+
fillColor: 'yellow',
|
|
80448
|
+
highlightStrokeColor: '#555555'
|
|
80449
|
+
},
|
|
80450
|
+
|
|
80451
|
+
surface3d: {
|
|
80452
|
+
/**#@+
|
|
80453
|
+
* @visprop
|
|
80454
|
+
*/
|
|
80455
|
+
|
|
80456
|
+
highlight: false,
|
|
80457
|
+
tabindex: -1,
|
|
80458
|
+
strokeWidth: 1,
|
|
80459
|
+
|
|
80460
|
+
/**
|
|
80461
|
+
* Number of intervals the mesh is divided into in direction of parameter u.
|
|
80462
|
+
* @type Number
|
|
80463
|
+
* @name Surface3D#stepsU
|
|
80464
|
+
*/
|
|
80465
|
+
stepsU: 30,
|
|
80466
|
+
|
|
80467
|
+
/**
|
|
80468
|
+
* Number of intervals the mesh is divided into in direction of parameter v.
|
|
80469
|
+
* @type Number
|
|
80470
|
+
* @name Surface3D#stepsV
|
|
80471
|
+
*/
|
|
80472
|
+
stepsV: 30
|
|
80473
|
+
|
|
80474
|
+
/**#@-*/
|
|
80475
|
+
},
|
|
80476
|
+
|
|
80477
|
+
view3d: {
|
|
80478
|
+
needsRegularUpdate: true
|
|
80479
|
+
}
|
|
80480
|
+
|
|
80481
|
+
});
|
|
80482
|
+
|
|
80483
|
+
return JXG.Options;
|
|
80484
|
+
});
|
|
80485
|
+
|
|
80486
|
+
|
|
80487
|
+
/*
|
|
80488
|
+
Copyright 2008-2022
|
|
80489
|
+
Matthias Ehmann,
|
|
80490
|
+
Carsten Miller,
|
|
80491
|
+
Andreas Walter,
|
|
80492
|
+
Alfred Wassermann
|
|
80493
|
+
|
|
80494
|
+
This file is part of JSXGraph.
|
|
80495
|
+
|
|
80496
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
80497
|
+
|
|
80498
|
+
You can redistribute it and/or modify it under the terms of the
|
|
80499
|
+
|
|
80500
|
+
* GNU Lesser General Public License as published by
|
|
80501
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
80502
|
+
(at your option) any later version
|
|
80503
|
+
OR
|
|
80504
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
80505
|
+
|
|
80506
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
80507
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
80508
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
80509
|
+
GNU Lesser General Public License for more details.
|
|
80510
|
+
|
|
80511
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
80512
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
80513
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
80514
|
+
*/
|
|
80515
|
+
/*global JXG:true, define: true*/
|
|
80516
|
+
|
|
80517
|
+
define('3d/threed',['jxg'
|
|
80518
|
+
], function (JXG) {
|
|
80519
|
+
"use strict";
|
|
80520
|
+
|
|
80521
|
+
JXG.ThreeD = {};
|
|
80522
|
+
|
|
80523
|
+
return JXG.ThreeD;
|
|
80524
|
+
});
|
|
80525
|
+
|
|
80526
|
+
/*
|
|
80527
|
+
Copyright 2008-2022
|
|
80528
|
+
Matthias Ehmann,
|
|
80529
|
+
Carsten Miller,
|
|
80530
|
+
Andreas Walter,
|
|
80531
|
+
Alfred Wassermann
|
|
80532
|
+
|
|
80533
|
+
This file is part of JSXGraph.
|
|
80534
|
+
|
|
80535
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
80536
|
+
|
|
80537
|
+
You can redistribute it and/or modify it under the terms of the
|
|
80538
|
+
|
|
80539
|
+
* GNU Lesser General Public License as published by
|
|
80540
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
80541
|
+
(at your option) any later version
|
|
80542
|
+
OR
|
|
80543
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
80544
|
+
|
|
80545
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
80546
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
80547
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
80548
|
+
GNU Lesser General Public License for more details.
|
|
80549
|
+
|
|
80550
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
80551
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
80552
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
80553
|
+
*/
|
|
80554
|
+
/*global JXG:true, define: true*/
|
|
80555
|
+
|
|
80556
|
+
define('3d/view3d',['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/element', '3d/threed',
|
|
80557
|
+
], function (JXG, Options, Const, Type, Mat, GeometryElement, ThreeD) {
|
|
80558
|
+
"use strict";
|
|
80559
|
+
|
|
80560
|
+
ThreeD.View3D = function (board, parents, attributes) {
|
|
80561
|
+
var bbox3d, coords, size;
|
|
80562
|
+
this.constructor(board, attributes, Const.OBJECT_TYPE_VIEW3D, Const.OBJECT_CLASS_CURVE);
|
|
80563
|
+
|
|
80564
|
+
bbox3d = parents[2]; // [[x1, x2], [y1,y2], [z1,z2]]
|
|
80565
|
+
coords = parents[0]; // llft corner
|
|
80566
|
+
size = parents[1]; // [w, h]
|
|
80567
|
+
|
|
80568
|
+
/**
|
|
80569
|
+
* "Namespace" for all 3D handling
|
|
80570
|
+
*/
|
|
80571
|
+
this.D3 = {};
|
|
80572
|
+
|
|
80573
|
+
/**
|
|
80574
|
+
* An associative array containing all geometric objects belonging to the view.
|
|
80575
|
+
* Key is the id of the object and value is a reference to the object.
|
|
80576
|
+
* @type Object
|
|
80577
|
+
*/
|
|
80578
|
+
this.D3.objects = {};
|
|
80579
|
+
|
|
80580
|
+
/**
|
|
80581
|
+
* An array containing all geometric objects in this view in the order of construction.
|
|
80582
|
+
* @type Array
|
|
80583
|
+
*/
|
|
80584
|
+
this.D3.objectsList = [];
|
|
80585
|
+
|
|
80586
|
+
/**
|
|
80587
|
+
* @type {Object} contains the axes of the view or null
|
|
80588
|
+
* @default null
|
|
80589
|
+
*/
|
|
80590
|
+
this.D3.defaultAxes = null;
|
|
80591
|
+
|
|
80592
|
+
/**
|
|
80593
|
+
* 3D-to-2D transformation matrix
|
|
80594
|
+
* @type {Array} 3 x 4 mattrix
|
|
80595
|
+
*/
|
|
80596
|
+
this.D3.matrix = [
|
|
80597
|
+
[1, 0, 0, 0],
|
|
80598
|
+
[0, 1, 0, 0],
|
|
80599
|
+
[0, 0, 1, 0]
|
|
80600
|
+
];
|
|
80601
|
+
|
|
80602
|
+
// Bounding box (cube) [[x1, x2], [y1,y2], [z1,z2]]:
|
|
80603
|
+
this.D3.bbox3d = bbox3d;
|
|
80604
|
+
this.D3.coords = coords;
|
|
80605
|
+
this.D3.size = size;
|
|
80606
|
+
|
|
80607
|
+
/**
|
|
80608
|
+
* Distance of the view to the origin. In other words, its
|
|
80609
|
+
* the radius of the sphere where the camera sits.
|
|
80610
|
+
*/
|
|
80611
|
+
this.D3.r = -1;
|
|
80612
|
+
|
|
80613
|
+
this.timeoutAzimuth = null;
|
|
80614
|
+
|
|
80615
|
+
this.id = this.board.setId(this, 'V');
|
|
80616
|
+
this.board.finalizeAdding(this);
|
|
80617
|
+
this.elType = 'view3d';
|
|
80618
|
+
this.methodMap = Type.deepCopy(this.methodMap, {
|
|
80619
|
+
});
|
|
80620
|
+
};
|
|
80621
|
+
ThreeD.View3D.prototype = new GeometryElement();
|
|
80622
|
+
|
|
80623
|
+
JXG.extend(ThreeD.View3D.prototype, /** @lends ThreeD.View3D.prototype */ {
|
|
80624
|
+
create: function (elementType, parents, attributes) {
|
|
80625
|
+
var prefix = [],
|
|
80626
|
+
is3D = false,
|
|
80627
|
+
el;
|
|
80628
|
+
|
|
80629
|
+
if (elementType.indexOf('3d') > 0) {
|
|
80630
|
+
is3D = true;
|
|
80631
|
+
prefix.push(this);
|
|
80632
|
+
}
|
|
80633
|
+
el = this.board.create(elementType, prefix.concat(parents), attributes);
|
|
80634
|
+
if (true || is3D) {
|
|
80635
|
+
this.add(el);
|
|
80636
|
+
}
|
|
80637
|
+
return el;
|
|
80638
|
+
},
|
|
80639
|
+
|
|
80640
|
+
add: function (el) {
|
|
80641
|
+
this.D3.objects[el.id] = el;
|
|
80642
|
+
this.D3.objectsList.push(el);
|
|
80643
|
+
},
|
|
80644
|
+
|
|
80645
|
+
/**
|
|
80646
|
+
* Update 3D-to-2D transformation matrix with the actual
|
|
80647
|
+
* elevation and azimuth angles.
|
|
80648
|
+
*
|
|
80649
|
+
* @private
|
|
80650
|
+
*/
|
|
80651
|
+
update: function () {
|
|
80652
|
+
var D3 = this.D3,
|
|
80653
|
+
e, r, a, f, mat;
|
|
80654
|
+
|
|
80655
|
+
if (!Type.exists(D3.el_slide) ||
|
|
80656
|
+
!Type.exists(D3.az_slide) ||
|
|
80657
|
+
!this.needsUpdate) {
|
|
80658
|
+
return this;
|
|
80659
|
+
}
|
|
80660
|
+
|
|
80661
|
+
e = D3.el_slide.Value();
|
|
80662
|
+
r = D3.r;
|
|
80663
|
+
a = D3.az_slide.Value();
|
|
80664
|
+
f = r * Math.sin(e);
|
|
80665
|
+
mat = [[1, 0, 0,], [0, 1, 0], [0, 0, 1]];
|
|
80666
|
+
|
|
80667
|
+
D3.matrix = [
|
|
80668
|
+
[1, 0, 0, 0],
|
|
80669
|
+
[0, 1, 0, 0],
|
|
80670
|
+
[0, 0, 1, 0]
|
|
80671
|
+
];
|
|
80672
|
+
|
|
80673
|
+
D3.matrix[1][1] = r * Math.cos(a);
|
|
80674
|
+
D3.matrix[1][2] = -r * Math.sin(a);
|
|
80675
|
+
D3.matrix[2][1] = f * Math.sin(a);
|
|
80676
|
+
D3.matrix[2][2] = f * Math.cos(a);
|
|
80677
|
+
D3.matrix[2][3] = Math.cos(e);
|
|
80678
|
+
|
|
80679
|
+
if (true) {
|
|
80680
|
+
mat[1][1] = D3.size[0] / (D3.bbox3d[0][1] - D3.bbox3d[0][0]); // w / d_x
|
|
80681
|
+
mat[2][2] = D3.size[1] / (D3.bbox3d[1][1] - D3.bbox3d[1][0]); // h / d_y
|
|
80682
|
+
mat[1][0] = D3.coords[0] - mat[1][1] * D3.bbox3d[0][0]; // llft_x
|
|
80683
|
+
mat[2][0] = D3.coords[1] - mat[2][2] * D3.bbox3d[1][0]; // llft_y
|
|
80684
|
+
|
|
80685
|
+
D3.matrix = Mat.matMatMult(mat, D3.matrix);
|
|
80686
|
+
}
|
|
80687
|
+
|
|
80688
|
+
return this;
|
|
80689
|
+
},
|
|
80690
|
+
|
|
80691
|
+
updateRenderer: function () {
|
|
80692
|
+
this.needsUpdate = false;
|
|
80693
|
+
return this;
|
|
80694
|
+
},
|
|
80695
|
+
|
|
80696
|
+
/**
|
|
80697
|
+
* Project 3D coordinates to 2D board coordinates
|
|
80698
|
+
* The 3D coordinates are provides as three numbers x, y, z or one array of length 3.
|
|
80699
|
+
*
|
|
80700
|
+
* @param {Number|Array} x
|
|
80701
|
+
* @param {[Number]} y
|
|
80702
|
+
* @param {[Number]} z
|
|
80703
|
+
* @returns {Array} Array of length 3 containing the projection on to the board
|
|
80704
|
+
* in homogeneous user coordinates.
|
|
80705
|
+
*/
|
|
80706
|
+
project3DTo2D: function (x, y, z) {
|
|
80707
|
+
var vec;
|
|
80708
|
+
if (arguments.length === 3) {
|
|
80709
|
+
vec = [1, x, y, z];
|
|
80710
|
+
} else {
|
|
80711
|
+
// Argument is an array
|
|
80712
|
+
if (x.length === 3) {
|
|
80713
|
+
vec = [1].concat(x);
|
|
80714
|
+
} else {
|
|
80715
|
+
vec = x;
|
|
80716
|
+
}
|
|
80717
|
+
}
|
|
80718
|
+
return Mat.matVecMult(this.D3.matrix, vec);
|
|
80719
|
+
},
|
|
80720
|
+
|
|
80721
|
+
/**
|
|
80722
|
+
* Project a 2D coordinate to the plane through the origin
|
|
80723
|
+
* defined by its normal vector `normal`.
|
|
80724
|
+
*
|
|
80725
|
+
* @param {JXG.Point} point
|
|
80726
|
+
* @param {Array} normal
|
|
80727
|
+
* @returns Array of length 4 containing the projected
|
|
80728
|
+
* point in homogeneous coordinates.
|
|
80729
|
+
*/
|
|
80730
|
+
project2DTo3DPlane: function (point, normal, foot) {
|
|
80731
|
+
var mat, rhs, d, le,
|
|
80732
|
+
n = normal.slice(1),
|
|
80733
|
+
sol = [1, 0, 0, 0];
|
|
80734
|
+
|
|
80735
|
+
foot = foot || [1, 0, 0, 0];
|
|
80736
|
+
le = Mat.norm(n, 3);
|
|
80737
|
+
d = Mat.innerProduct(foot.slice(1), n, 3) / le;
|
|
80738
|
+
|
|
80739
|
+
mat = this.D3.matrix.slice(0, 3); // True copy
|
|
80740
|
+
mat.push([0].concat(n));
|
|
80741
|
+
|
|
80742
|
+
// 2D coordinates of point:
|
|
80743
|
+
rhs = point.coords.usrCoords.concat([d]);
|
|
80744
|
+
try {
|
|
80745
|
+
// Prevent singularity in case elevation angle is zero
|
|
80746
|
+
if (mat[2][3] === 1.0) {
|
|
80747
|
+
mat[2][1] = mat[2][2] = Mat.eps * 0.001;
|
|
80748
|
+
}
|
|
80749
|
+
sol = Mat.Numerics.Gauss(mat, rhs);
|
|
80750
|
+
} catch (err) {
|
|
80751
|
+
sol = [0, NaN, NaN, NaN];
|
|
80752
|
+
}
|
|
80753
|
+
|
|
80754
|
+
return sol;
|
|
80755
|
+
},
|
|
80756
|
+
|
|
80757
|
+
project3DToCube: function (c3d) {
|
|
80758
|
+
var cube = this.D3.bbox3d;
|
|
80759
|
+
if (c3d[1] < cube[0][0]) { c3d[1] = cube[0][0]; }
|
|
80760
|
+
if (c3d[1] > cube[0][1]) { c3d[1] = cube[0][1]; }
|
|
80761
|
+
if (c3d[2] < cube[1][0]) { c3d[2] = cube[1][0]; }
|
|
80762
|
+
if (c3d[2] > cube[1][1]) { c3d[2] = cube[1][1]; }
|
|
80763
|
+
if (c3d[3] < cube[2][0]) { c3d[3] = cube[2][0]; }
|
|
80764
|
+
if (c3d[3] > cube[2][1]) { c3d[3] = cube[2][1]; }
|
|
80765
|
+
|
|
80766
|
+
return c3d;
|
|
80767
|
+
},
|
|
80768
|
+
|
|
80769
|
+
intersectionLineCube: function (p, d, r) {
|
|
80770
|
+
var rnew, i, r0, r1;
|
|
80771
|
+
|
|
80772
|
+
rnew = r;
|
|
80773
|
+
for (i = 0; i < 3; i++) {
|
|
80774
|
+
if (d[i] !== 0) {
|
|
80775
|
+
r0 = (this.D3.bbox3d[i][0] - p[i]) / d[i];
|
|
80776
|
+
r1 = (this.D3.bbox3d[i][1] - p[i]) / d[i];
|
|
80777
|
+
if (r < 0) {
|
|
80778
|
+
rnew = Math.max(rnew, Math.min(r0, r1));
|
|
80779
|
+
} else {
|
|
80780
|
+
rnew = Math.min(rnew, Math.max(r0, r1));
|
|
80781
|
+
}
|
|
80782
|
+
}
|
|
80783
|
+
}
|
|
80784
|
+
return rnew;
|
|
80785
|
+
},
|
|
80786
|
+
|
|
80787
|
+
isInCube: function (q) {
|
|
80788
|
+
return q[0] > this.D3.bbox3d[0][0] - Mat.eps && q[0] < this.D3.bbox3d[0][1] + Mat.eps &&
|
|
80789
|
+
q[1] > this.D3.bbox3d[1][0] - Mat.eps && q[1] < this.D3.bbox3d[1][1] + Mat.eps &&
|
|
80790
|
+
q[2] > this.D3.bbox3d[2][0] - Mat.eps && q[2] < this.D3.bbox3d[2][1] + Mat.eps;
|
|
80791
|
+
},
|
|
80792
|
+
|
|
80793
|
+
/**
|
|
80794
|
+
*
|
|
80795
|
+
* @param {*} plane1
|
|
80796
|
+
* @param {*} plane2
|
|
80797
|
+
* @param {*} d
|
|
80798
|
+
* @returns Array of length 2 containing the coordinates of the defining points of
|
|
80799
|
+
* of the intersection segment.
|
|
80800
|
+
*/
|
|
80801
|
+
intersectionPlanePlane: function(plane1, plane2, d) {
|
|
80802
|
+
var ret = [[], []],
|
|
80803
|
+
p, dir, r, q;
|
|
80804
|
+
|
|
80805
|
+
d = d || plane2.D3.d;
|
|
80806
|
+
|
|
80807
|
+
p = Mat.Geometry.meet3Planes(plane1.D3.normal, plane1.D3.d, plane2.D3.normal, d,
|
|
80808
|
+
Mat.crossProduct(plane1.D3.normal, plane2.D3.normal), 0);
|
|
80809
|
+
dir = Mat.Geometry.meetPlanePlane(plane1.D3.dir1, plane1.D3.dir2, plane2.D3.dir1, plane2.D3.dir2);
|
|
80810
|
+
r = this.intersectionLineCube(p, dir, Infinity);
|
|
80811
|
+
q = Mat.axpy(r, dir, p);
|
|
80812
|
+
if (this.isInCube(q)) {
|
|
80813
|
+
ret[0] = q;
|
|
80814
|
+
}
|
|
80815
|
+
r = this.intersectionLineCube(p, dir, -Infinity);
|
|
80816
|
+
q = Mat.axpy(r, dir, p);
|
|
80817
|
+
if (this.isInCube(q) ) {
|
|
80818
|
+
ret[1] = q;
|
|
80819
|
+
}
|
|
80820
|
+
return ret;
|
|
80821
|
+
},
|
|
80822
|
+
|
|
80823
|
+
getMesh: function (X, Y, Z, interval_u, interval_v) {
|
|
80824
|
+
var i_u, i_v, u, v, c2d,
|
|
80825
|
+
delta_u, delta_v,
|
|
80826
|
+
p = [0, 0, 0],
|
|
80827
|
+
steps_u = interval_u[2],
|
|
80828
|
+
steps_v = interval_v[2],
|
|
80829
|
+
|
|
80830
|
+
dataX = [],
|
|
80831
|
+
dataY = [];
|
|
80832
|
+
|
|
80833
|
+
delta_u = (Type.evaluate(interval_u[1]) - Type.evaluate(interval_u[0])) / (steps_u);
|
|
80834
|
+
delta_v = (Type.evaluate(interval_v[1]) - Type.evaluate(interval_v[0])) / (steps_v);
|
|
80835
|
+
|
|
80836
|
+
for (i_u = 0; i_u <= steps_u; i_u++) {
|
|
80837
|
+
u = interval_u[0] + delta_u * i_u;
|
|
80838
|
+
for (i_v = 0; i_v <= steps_v; i_v++) {
|
|
80839
|
+
v = interval_v[0] + delta_v * i_v;
|
|
80840
|
+
p[0] = X(u, v);
|
|
80841
|
+
p[1] = Y(u, v);
|
|
80842
|
+
p[2] = Z(u, v);
|
|
80843
|
+
c2d = this.project3DTo2D(p);
|
|
80844
|
+
dataX.push(c2d[1]);
|
|
80845
|
+
dataY.push(c2d[2]);
|
|
80846
|
+
}
|
|
80847
|
+
dataX.push(NaN);
|
|
80848
|
+
dataY.push(NaN);
|
|
80849
|
+
}
|
|
80850
|
+
|
|
80851
|
+
for (i_v = 0; i_v <= steps_v; i_v++) {
|
|
80852
|
+
v = interval_v[0] + delta_v * i_v;
|
|
80853
|
+
for (i_u = 0; i_u <= steps_u; i_u++) {
|
|
80854
|
+
u = interval_u[0] + delta_u * i_u;
|
|
80855
|
+
p[0] = X(u, v);
|
|
80856
|
+
p[1] = Y(u, v);
|
|
80857
|
+
p[2] = Z(u, v);
|
|
80858
|
+
c2d = this.project3DTo2D(p);
|
|
80859
|
+
dataX.push(c2d[1]);
|
|
80860
|
+
dataY.push(c2d[2]);
|
|
80861
|
+
}
|
|
80862
|
+
dataX.push(NaN);
|
|
80863
|
+
dataY.push(NaN);
|
|
80864
|
+
}
|
|
80865
|
+
|
|
80866
|
+
return [dataX, dataY];
|
|
80867
|
+
},
|
|
80868
|
+
|
|
80869
|
+
animateAzimuth: function () {
|
|
80870
|
+
var s = this.D3.az_slide._smin,
|
|
80871
|
+
e = this.D3.az_slide._smax,
|
|
80872
|
+
sdiff = e - s,
|
|
80873
|
+
newVal = this.D3.az_slide.Value() + 0.1;
|
|
80874
|
+
|
|
80875
|
+
this.D3.az_slide.position = ((newVal - s) / sdiff);
|
|
80876
|
+
if (this.D3.az_slide.position > 1) {
|
|
80877
|
+
this.D3.az_slide.position = 0.0;
|
|
80878
|
+
}
|
|
80879
|
+
this.board.update();
|
|
80880
|
+
|
|
80881
|
+
this.timeoutAzimuth = setTimeout(function () { this.animateAzimuth(); }.bind(this), 200);
|
|
80882
|
+
},
|
|
80883
|
+
|
|
80884
|
+
stopAzimuth: function () {
|
|
80885
|
+
clearTimeout(this.timeoutAzimuth);
|
|
80886
|
+
this.timeoutAzimuth = null;
|
|
80887
|
+
}
|
|
80888
|
+
});
|
|
80889
|
+
|
|
80890
|
+
/**
|
|
80891
|
+
* @class This element creates a 3D view.
|
|
80892
|
+
* @pseudo
|
|
80893
|
+
* @description A View3D element provides the container and the methods to create and display 3D elements.
|
|
80894
|
+
* It is contained in a JSXGraph board.
|
|
80895
|
+
* @name View3D
|
|
80896
|
+
* @augments JXG.View3D
|
|
80897
|
+
* @constructor
|
|
80898
|
+
* @type Object
|
|
80899
|
+
* @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
80900
|
+
* @param {Array_Array_Array} lower,dim,cube Here, lower is an array of the form [x, y] and
|
|
80901
|
+
* dim is an array of the form [w, h].
|
|
80902
|
+
* The arrays [x, y] and [w, h] define the 2D frame into which the 3D cube is
|
|
80903
|
+
* (roughly) projected.
|
|
80904
|
+
* cube is an array of the form [[x1, x2], [y1, y2], [z1, z2]]
|
|
80905
|
+
* which determines the coordinate ranges of the 3D cube.
|
|
80906
|
+
*
|
|
80907
|
+
* @example
|
|
80908
|
+
* var bound = [-5, 5];
|
|
80909
|
+
* var view = board.create('view3d',
|
|
80910
|
+
* [[-6, -3],
|
|
80911
|
+
* [8, 8],
|
|
80912
|
+
* [bound, bound, bound]],
|
|
80913
|
+
* {
|
|
80914
|
+
* // Main axes
|
|
80915
|
+
* axesPosition: 'center',
|
|
80916
|
+
* xAxis: { strokeColor: 'blue', strokeWidth: 3},
|
|
80917
|
+
*
|
|
80918
|
+
* // Planes
|
|
80919
|
+
* xPlaneRear: { fillColor: 'yellow', mesh3d: {visible: false}},
|
|
80920
|
+
* yPlaneFront: { visible: true, fillColor: 'blue'},
|
|
80921
|
+
*
|
|
80922
|
+
* // Axes on planes
|
|
80923
|
+
* xPlaneRearYAxis: {strokeColor: 'red'},
|
|
80924
|
+
* xPlaneRearZAxis: {strokeColor: 'red'},
|
|
80925
|
+
*
|
|
80926
|
+
* yPlaneFrontXAxis: {strokeColor: 'blue'},
|
|
80927
|
+
* yPlaneFrontZAxis: {strokeColor: 'blue'},
|
|
80928
|
+
*
|
|
80929
|
+
* zPlaneFrontXAxis: {visible: false},
|
|
80930
|
+
* zPlaneFrontYAxis: {visible: false}
|
|
80931
|
+
* });
|
|
80932
|
+
*
|
|
80933
|
+
* </pre><div id="JXGdd06d90e-be5d-4531-8f0b-65fc30b1a7c7" class="jxgbox" style="width: 500px; height: 500px;"></div>
|
|
80934
|
+
* <script type="text/javascript">
|
|
80935
|
+
* (function() {
|
|
80936
|
+
* var board = JXG.JSXGraph.initBoard('JXGdd06d90e-be5d-4531-8f0b-65fc30b1a7c7',
|
|
80937
|
+
* {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
|
|
80938
|
+
* var bound = [-5, 5];
|
|
80939
|
+
* var view = board.create('view3d',
|
|
80940
|
+
* [[-6, -3], [8, 8],
|
|
80941
|
+
* [bound, bound, bound]],
|
|
80942
|
+
* {
|
|
80943
|
+
* // Main axes
|
|
80944
|
+
* axesPosition: 'center',
|
|
80945
|
+
* xAxis: { strokeColor: 'blue', strokeWidth: 3},
|
|
80946
|
+
*
|
|
80947
|
+
* // Planes
|
|
80948
|
+
* xPlaneRear: { fillColor: 'yellow', mesh3d: {visible: false}},
|
|
80949
|
+
* yPlaneFront: { visible: true, fillColor: 'blue'},
|
|
80950
|
+
*
|
|
80951
|
+
* // Axes on planes
|
|
80952
|
+
* xPlaneRearYAxis: {strokeColor: 'red'},
|
|
80953
|
+
* xPlaneRearZAxis: {strokeColor: 'red'},
|
|
80954
|
+
*
|
|
80955
|
+
* yPlaneFrontXAxis: {strokeColor: 'blue'},
|
|
80956
|
+
* yPlaneFrontZAxis: {strokeColor: 'blue'},
|
|
80957
|
+
*
|
|
80958
|
+
* zPlaneFrontXAxis: {visible: false},
|
|
80959
|
+
* zPlaneFrontYAxis: {visible: false}
|
|
80960
|
+
* });
|
|
80961
|
+
*
|
|
80962
|
+
* })();
|
|
80963
|
+
*
|
|
80964
|
+
* </script><pre>
|
|
80965
|
+
*
|
|
80966
|
+
*/
|
|
80967
|
+
ThreeD.createView3D = function (board, parents, attributes) {
|
|
80968
|
+
var view, frame, attr,
|
|
80969
|
+
x, y, w, h,
|
|
80970
|
+
coords = parents[0], // llft corner
|
|
80971
|
+
size = parents[1]; // [w, h]
|
|
80972
|
+
|
|
80973
|
+
attr = Type.copyAttributes(attributes, board.options, 'view3d');
|
|
80974
|
+
view = new ThreeD.View3D(board, parents, attr);
|
|
80975
|
+
view.defaultAxes = view.create('axes3d', parents, attributes);
|
|
80976
|
+
|
|
80977
|
+
x = coords[0];
|
|
80978
|
+
y = coords[1];
|
|
80979
|
+
w = size[0];
|
|
80980
|
+
h = size[1];
|
|
80981
|
+
|
|
80982
|
+
/**
|
|
80983
|
+
* Frame around the view object
|
|
80984
|
+
*/
|
|
80985
|
+
if (false) {
|
|
80986
|
+
frame = board.create('polygon', [
|
|
80987
|
+
[coords[0], coords[1] + size[1]], // ulft
|
|
80988
|
+
[coords[0], coords[1]], // llft
|
|
80989
|
+
[coords[0] + size[0], coords[1]], // lrt
|
|
80990
|
+
[coords[0] + size[0], coords[1] + size[1]], // urt
|
|
80991
|
+
], {
|
|
80992
|
+
fillColor: 'none',
|
|
80993
|
+
highlightFillColor: 'none',
|
|
80994
|
+
highlight: false,
|
|
80995
|
+
vertices: {
|
|
80996
|
+
fixed: true,
|
|
80997
|
+
visible: false
|
|
80998
|
+
},
|
|
80999
|
+
borders: {
|
|
81000
|
+
strokeColor: 'black',
|
|
81001
|
+
highlight: false,
|
|
81002
|
+
strokeWidth: 0.5,
|
|
81003
|
+
dash: 4
|
|
81004
|
+
}
|
|
81005
|
+
});
|
|
81006
|
+
//view.add(frame);
|
|
81007
|
+
}
|
|
81008
|
+
|
|
81009
|
+
/**
|
|
81010
|
+
* Slider to adapt azimuth angle
|
|
81011
|
+
*/
|
|
81012
|
+
view.D3.az_slide = board.create('slider', [[x - 1, y - 2], [x + w + 1, y - 2], [0, 1.0, 2 * Math.PI]], {
|
|
81013
|
+
style: 6, name: 'az',
|
|
81014
|
+
point1: { frozen: true },
|
|
81015
|
+
point2: { frozen: true }
|
|
81016
|
+
});
|
|
81017
|
+
|
|
81018
|
+
/**
|
|
81019
|
+
* Slider to adapt elevation angle
|
|
81020
|
+
*/
|
|
81021
|
+
view.D3.el_slide = board.create('slider', [[x - 1, y], [x - 1, y + h], [0, 0.30, Math.PI / 2]], {
|
|
81022
|
+
style: 6, name: 'el',
|
|
81023
|
+
point1: { frozen: true },
|
|
81024
|
+
point2: { frozen: true }
|
|
81025
|
+
});
|
|
81026
|
+
|
|
81027
|
+
view.board.highlightInfobox = function (x, y, el) {
|
|
81028
|
+
var d;
|
|
81029
|
+
|
|
81030
|
+
if (Type.exists(el.D3)) {
|
|
81031
|
+
d = Type.evaluate(el.visProp.infoboxdigits);
|
|
81032
|
+
if (d === 'auto') {
|
|
81033
|
+
view.board.highlightCustomInfobox('(' +
|
|
81034
|
+
Type.autoDigits(el.D3.X()) + ' | ' +
|
|
81035
|
+
Type.autoDigits(el.D3.Y()) + ' | ' +
|
|
81036
|
+
Type.autoDigits(el.D3.Z()) + ')', el);
|
|
81037
|
+
} else {
|
|
81038
|
+
view.board.highlightCustomInfobox('(' +
|
|
81039
|
+
Type.toFixed(el.D3.X(), d) + ' | ' +
|
|
81040
|
+
Type.toFixed(el.D3.Y(), d) + ' | ' +
|
|
81041
|
+
Type.toFixed(el.D3.Z(), d) + ')', el);
|
|
81042
|
+
}
|
|
81043
|
+
} else {
|
|
81044
|
+
view.board.highlightCustomInfobox('(' + x + ', ' + y + ')', el);
|
|
81045
|
+
}
|
|
81046
|
+
};
|
|
81047
|
+
|
|
81048
|
+
return view;
|
|
81049
|
+
};
|
|
81050
|
+
JXG.registerElement('view3d', ThreeD.createView3D);
|
|
81051
|
+
|
|
81052
|
+
return ThreeD.View3D;
|
|
81053
|
+
});
|
|
81054
|
+
|
|
81055
|
+
|
|
81056
|
+
/*
|
|
81057
|
+
Copyright 2008-2022
|
|
81058
|
+
Matthias Ehmann,
|
|
81059
|
+
Carsten Miller,
|
|
81060
|
+
Andreas Walter,
|
|
81061
|
+
Alfred Wassermann
|
|
81062
|
+
|
|
81063
|
+
This file is part of JSXGraph.
|
|
81064
|
+
|
|
81065
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
81066
|
+
|
|
81067
|
+
You can redistribute it and/or modify it under the terms of the
|
|
81068
|
+
|
|
81069
|
+
* GNU Lesser General Public License as published by
|
|
81070
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
81071
|
+
(at your option) any later version
|
|
81072
|
+
OR
|
|
81073
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
81074
|
+
|
|
81075
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
81076
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
81077
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
81078
|
+
GNU Lesser General Public License for more details.
|
|
81079
|
+
|
|
81080
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
81081
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
81082
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
81083
|
+
*/
|
|
81084
|
+
/*global JXG:true, define: true*/
|
|
81085
|
+
|
|
81086
|
+
/**
|
|
81087
|
+
* Create axes and rear and front walls of the
|
|
81088
|
+
* view3d bounding box bbox3d.
|
|
81089
|
+
*/
|
|
81090
|
+
define('3d/box3d',['jxg', 'utils/type', 'math/math', 'math/geometry', '3d/view3d'
|
|
81091
|
+
], function (JXG, Type, Mat, Geometry, ThreeD) {
|
|
81092
|
+
"use strict";
|
|
81093
|
+
|
|
81094
|
+
ThreeD.createAxes = function (board, parents, attributes) {
|
|
81095
|
+
var view = parents[0],
|
|
81096
|
+
i, j, k, i1, i2,
|
|
81097
|
+
attr,
|
|
81098
|
+
pos,
|
|
81099
|
+
directions = ['x', 'y', 'z'],
|
|
81100
|
+
suffixAxis = 'Axis',
|
|
81101
|
+
dir, dir1,
|
|
81102
|
+
sides = ['Rear', 'Front'],
|
|
81103
|
+
rear = [0, 0, 0], // x, y, z
|
|
81104
|
+
front = [0, 0, 0], // x, y, z
|
|
81105
|
+
from, to,
|
|
81106
|
+
vec1, vec2, range1, range2,
|
|
81107
|
+
na, na_parent,
|
|
81108
|
+
ticks_attr,
|
|
81109
|
+
axes = {};
|
|
81110
|
+
|
|
81111
|
+
if (Type.exists(view.D3)) {
|
|
81112
|
+
for (i = 0; i < directions.length; i++) {
|
|
81113
|
+
rear[i] = view.D3.bbox3d[i][0];
|
|
81114
|
+
front[i] = view.D3.bbox3d[i][1];
|
|
81115
|
+
}
|
|
81116
|
+
} else {
|
|
81117
|
+
for (i = 0; i < directions.length; i++) {
|
|
81118
|
+
rear[i] = parents[1][i];
|
|
81119
|
+
front[i] = parents[2][1];
|
|
81120
|
+
}
|
|
81121
|
+
}
|
|
81122
|
+
|
|
81123
|
+
// Main 3D axes
|
|
81124
|
+
attr = Type.copyAttributes(attributes, board.options, 'axes3d');
|
|
81125
|
+
pos = attr.axesposition;
|
|
81126
|
+
for (i = 0; i < directions.length; i++) {
|
|
81127
|
+
// Run through ['x', 'y', 'z']
|
|
81128
|
+
dir = directions[i];
|
|
81129
|
+
na = dir + suffixAxis;
|
|
81130
|
+
|
|
81131
|
+
if (pos === 'center') { // Axes centered
|
|
81132
|
+
from = [0, 0, 0];
|
|
81133
|
+
to = [0, 0, 0];
|
|
81134
|
+
to[i] = front[i];
|
|
81135
|
+
axes[na] = view.create('axis3d', [from, to], attr[na.toLowerCase()]);
|
|
81136
|
+
} else {
|
|
81137
|
+
na += 'Border'; // Axes bordered
|
|
81138
|
+
from = rear.slice();
|
|
81139
|
+
to = front.slice();
|
|
81140
|
+
if (i === 2) {
|
|
81141
|
+
from[1] = front[1];
|
|
81142
|
+
to[0] = rear[0];
|
|
81143
|
+
} else {
|
|
81144
|
+
from[i] = front[i];
|
|
81145
|
+
to[2] = rear[2];
|
|
81146
|
+
}
|
|
81147
|
+
to[i] = front[i];
|
|
81148
|
+
attr[na.toLowerCase()].lastArrow = false;
|
|
81149
|
+
axes[na] = view.create('axis3d', [from, to], attr[na.toLowerCase()]);
|
|
81150
|
+
|
|
81151
|
+
// TODO
|
|
81152
|
+
ticks_attr = {
|
|
81153
|
+
visible: true, // Für z-Ticks wird path nicht berechnet
|
|
81154
|
+
minorTicks: 0,
|
|
81155
|
+
tickEndings: [0, 1],
|
|
81156
|
+
drawLabels: false
|
|
81157
|
+
};
|
|
81158
|
+
if (i === 2) {
|
|
81159
|
+
ticks_attr.tickEndings = [1, 0];
|
|
81160
|
+
}
|
|
81161
|
+
axes[na + 'Ticks'] = view.create('ticks', [axes[na], 1], ticks_attr);
|
|
81162
|
+
}
|
|
81163
|
+
}
|
|
81164
|
+
|
|
81165
|
+
// Origin (2D point)
|
|
81166
|
+
axes.O = board.create('intersection', [
|
|
81167
|
+
axes[directions[0] + suffixAxis],
|
|
81168
|
+
axes[directions[1] + suffixAxis]
|
|
81169
|
+
], {
|
|
81170
|
+
name: '', visible: false, withLabel: false
|
|
81171
|
+
});
|
|
81172
|
+
|
|
81173
|
+
// Front and rear planes
|
|
81174
|
+
for (i = 0; i < directions.length; i++) {
|
|
81175
|
+
// Run through ['x', 'y', 'z']
|
|
81176
|
+
i1 = (i + 1) % 3;
|
|
81177
|
+
i2 = (i + 2) % 3;
|
|
81178
|
+
|
|
81179
|
+
dir = directions[i];
|
|
81180
|
+
for (j = 0; j < sides.length; j++) {
|
|
81181
|
+
// Run through ['Rear', 'Front']
|
|
81182
|
+
|
|
81183
|
+
from = [0, 0, 0];
|
|
81184
|
+
from[i] = (j === 0) ? rear[i] : front[i];
|
|
81185
|
+
vec1 = [0, 0, 0];
|
|
81186
|
+
vec2 = [0, 0, 0];
|
|
81187
|
+
vec1[i1] = 1;
|
|
81188
|
+
vec2[i2] = 1;
|
|
81189
|
+
range1 = [rear[i1], front[i1]];
|
|
81190
|
+
range2 = [rear[i2], front[i2]];
|
|
81191
|
+
na = dir + 'Plane' + sides[j];
|
|
81192
|
+
|
|
81193
|
+
attr = Type.copyAttributes(attributes, board.options, 'axes3d', na);
|
|
81194
|
+
axes[na] =
|
|
81195
|
+
view.create('plane3d', [from, vec1, vec2, range1, range2], attr);
|
|
81196
|
+
axes[na].D3.elType = 'axisplane3d';
|
|
81197
|
+
}
|
|
81198
|
+
}
|
|
81199
|
+
|
|
81200
|
+
// Axes on front and rear planes
|
|
81201
|
+
for (i = 0; i < directions.length; i++) {
|
|
81202
|
+
// Run through ['x', 'y', 'z']
|
|
81203
|
+
dir = directions[i];
|
|
81204
|
+
for (j = 0; j < sides.length; j++) {
|
|
81205
|
+
for (k = 1; k <= 2; k++) {
|
|
81206
|
+
i1 = (i + k) % 3;
|
|
81207
|
+
dir1 = directions[i1];
|
|
81208
|
+
na = dir + 'Plane' + sides[j] + dir1.toUpperCase() + 'Axis';
|
|
81209
|
+
na_parent = dir + 'Plane' + sides[j];
|
|
81210
|
+
|
|
81211
|
+
from = [0, 0, 0];
|
|
81212
|
+
to = [0, 0, 0];
|
|
81213
|
+
from[i] = to[i] = (j === 0) ? rear[i] : front[i];
|
|
81214
|
+
|
|
81215
|
+
from[i1] = rear[i1];
|
|
81216
|
+
to[i1] = front[i1];
|
|
81217
|
+
|
|
81218
|
+
attr = Type.copyAttributes(attributes, board.options, 'axes3d', na);
|
|
81219
|
+
axes[na] = view.create('axis3d', [from, to], attr);
|
|
81220
|
+
axes[na_parent].addChild(axes[na]);
|
|
81221
|
+
axes[na_parent].inherits.push(axes[na]);
|
|
81222
|
+
}
|
|
81223
|
+
}
|
|
81224
|
+
}
|
|
81225
|
+
|
|
81226
|
+
return axes;
|
|
81227
|
+
};
|
|
81228
|
+
JXG.registerElement('axes3d', ThreeD.createAxes);
|
|
81229
|
+
|
|
81230
|
+
ThreeD.createAxis = function (board, parents, attributes) {
|
|
81231
|
+
var view = parents[0],
|
|
81232
|
+
attr,
|
|
81233
|
+
start = parents[1],
|
|
81234
|
+
end = parents[2],
|
|
81235
|
+
el_start, el_end, el;
|
|
81236
|
+
|
|
81237
|
+
// Use 2D points to create axis
|
|
81238
|
+
attr = Type.copyAttributes(attributes.point1, board.options, 'axis3d', 'point1');
|
|
81239
|
+
el_start = board.create('point', [
|
|
81240
|
+
(function (xx, yy, zz) {
|
|
81241
|
+
return function () { return view.project3DTo2D(xx, yy, zz)[1]; };
|
|
81242
|
+
})(start[0], start[1], start[2]),
|
|
81243
|
+
(function (xx, yy, zz) {
|
|
81244
|
+
return function () { return view.project3DTo2D(xx, yy, zz)[2]; };
|
|
81245
|
+
})(start[0], start[1], start[2])
|
|
81246
|
+
], attr);
|
|
81247
|
+
|
|
81248
|
+
attr = Type.copyAttributes(attributes.point2, board.options, 'axis3d', 'point2');
|
|
81249
|
+
el_end = board.create('point', [
|
|
81250
|
+
(function (xx, yy, zz) {
|
|
81251
|
+
return function () { return view.project3DTo2D(xx, yy, zz)[1]; };
|
|
81252
|
+
})(end[0], end[1], end[2]),
|
|
81253
|
+
(function (xx, yy, zz) {
|
|
81254
|
+
return function () { return view.project3DTo2D(xx, yy, zz)[2]; };
|
|
81255
|
+
})(end[0], end[1], end[2])
|
|
81256
|
+
], attr);
|
|
81257
|
+
|
|
81258
|
+
attr = Type.copyAttributes(attributes, board.options, 'axis3d');
|
|
81259
|
+
el = board.create('arrow', [el_start, el_end], attr);
|
|
81260
|
+
|
|
81261
|
+
return el;
|
|
81262
|
+
};
|
|
81263
|
+
JXG.registerElement('axis3d', ThreeD.createAxis);
|
|
81264
|
+
|
|
81265
|
+
ThreeD.createMesh = function (board, parents, attr) {
|
|
81266
|
+
var view = parents[0],
|
|
81267
|
+
point = parents[1],
|
|
81268
|
+
vec1 = parents[2],
|
|
81269
|
+
range1 = parents[3],
|
|
81270
|
+
vec2 = parents[4],
|
|
81271
|
+
range2 = parents[5],
|
|
81272
|
+
el;
|
|
81273
|
+
|
|
81274
|
+
el = board.create('curve', [[], []], attr);
|
|
81275
|
+
el.updateDataArray = function () {
|
|
81276
|
+
var s1 = range1[0],
|
|
81277
|
+
e1 = range1[1],
|
|
81278
|
+
s2 = range2[0],
|
|
81279
|
+
e2 = range2[1],
|
|
81280
|
+
l1, l2, res, i, sol,
|
|
81281
|
+
v1 = [0, 0, 0],
|
|
81282
|
+
v2 = [0, 0, 0],
|
|
81283
|
+
step = 1,
|
|
81284
|
+
q = [0, 0, 0];
|
|
81285
|
+
|
|
81286
|
+
this.dataX = [];
|
|
81287
|
+
this.dataY = [];
|
|
81288
|
+
|
|
81289
|
+
for (i = 0; i < 3; i++) {
|
|
81290
|
+
q[i] = Type.evaluate(point[i]);
|
|
81291
|
+
v1[i] = Type.evaluate(vec1[i]);
|
|
81292
|
+
v2[i] = Type.evaluate(vec2[i]);
|
|
81293
|
+
}
|
|
81294
|
+
l1 = JXG.Math.norm(v1, 3);
|
|
81295
|
+
l2 = JXG.Math.norm(v2, 3);
|
|
81296
|
+
for (i = 0; i < 3; i++) {
|
|
81297
|
+
v1[i] /= l1;
|
|
81298
|
+
v2[i] /= l2;
|
|
81299
|
+
}
|
|
81300
|
+
if (false) {
|
|
81301
|
+
sol = Mat.Geometry.getPlaneBounds(v1, v2, q, s1, e1);
|
|
81302
|
+
if (sol !== null) {
|
|
81303
|
+
s1 = sol[0];
|
|
81304
|
+
e1 = sol[1];
|
|
81305
|
+
s2 = sol[2];
|
|
81306
|
+
e2 = sol[3];
|
|
81307
|
+
}
|
|
81308
|
+
}
|
|
81309
|
+
|
|
81310
|
+
res = view.getMesh(
|
|
81311
|
+
function(u, v) { return q[0] + u * v1[0] + v * v2[0]; },
|
|
81312
|
+
function(u, v) { return q[1] + u * v1[1] + v * v2[1]; },
|
|
81313
|
+
function(u, v) { return q[2] + u * v1[2] + v * v2[2]; },
|
|
81314
|
+
[Math.ceil(s1), Math.floor(e1), (Math.ceil(e1) - Math.floor(s1)) / step],
|
|
81315
|
+
[Math.ceil(s2), Math.floor(e2), (Math.ceil(e2) - Math.floor(s2)) / step]);
|
|
81316
|
+
this.dataX = res[0];
|
|
81317
|
+
this.dataY = res[1];
|
|
81318
|
+
};
|
|
81319
|
+
return el;
|
|
81320
|
+
};
|
|
81321
|
+
JXG.registerElement('mesh3d', ThreeD.createMesh);
|
|
81322
|
+
|
|
81323
|
+
});
|
|
81324
|
+
/*
|
|
81325
|
+
Copyright 2008-2022
|
|
81326
|
+
Matthias Ehmann,
|
|
81327
|
+
Carsten Miller,
|
|
81328
|
+
Andreas Walter,
|
|
81329
|
+
Alfred Wassermann
|
|
81330
|
+
|
|
81331
|
+
This file is part of JSXGraph.
|
|
81332
|
+
|
|
81333
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
81334
|
+
|
|
81335
|
+
You can redistribute it and/or modify it under the terms of the
|
|
81336
|
+
|
|
81337
|
+
* GNU Lesser General Public License as published by
|
|
81338
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
81339
|
+
(at your option) any later version
|
|
81340
|
+
OR
|
|
81341
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
81342
|
+
|
|
81343
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
81344
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
81345
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
81346
|
+
GNU Lesser General Public License for more details.
|
|
81347
|
+
|
|
81348
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
81349
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
81350
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
81351
|
+
*/
|
|
81352
|
+
/*global JXG:true, define: true*/
|
|
81353
|
+
|
|
81354
|
+
define('3d/curve3d',['jxg', 'utils/type', '3d/view3d'
|
|
81355
|
+
], function (JXG, Type, ThreeD) {
|
|
81356
|
+
"use strict";
|
|
81357
|
+
|
|
81358
|
+
ThreeD.createCurve = function (board, parents, attr) {
|
|
81359
|
+
var view = parents[0],
|
|
81360
|
+
D3, el;
|
|
81361
|
+
|
|
81362
|
+
D3 = {
|
|
81363
|
+
elType: 'curve3D',
|
|
81364
|
+
X: parents[1],
|
|
81365
|
+
Y: parents[2],
|
|
81366
|
+
Z: parents[3],
|
|
81367
|
+
};
|
|
81368
|
+
D3.F = [D3.X, D3.Y, D3.Z];
|
|
81369
|
+
|
|
81370
|
+
el = board.create('curve', [[], []], attr);
|
|
81371
|
+
el.D3 = D3;
|
|
81372
|
+
|
|
81373
|
+
if (Type.isFunction(el.D3.X)) {
|
|
81374
|
+
// 3D curve given as t -> [X(t), Y(t), Z(t)]
|
|
81375
|
+
|
|
81376
|
+
el.D3.range = parents[4];
|
|
81377
|
+
el.updateDataArray = function () {
|
|
81378
|
+
var steps = Type.evaluate(this.visProp.numberpointshigh),
|
|
81379
|
+
s = Type.evaluate(this.D3.range[0]),
|
|
81380
|
+
e = Type.evaluate(this.D3.range[1]),
|
|
81381
|
+
delta = (e - s) / (steps - 1),
|
|
81382
|
+
c2d, t, i,
|
|
81383
|
+
p = [0, 0, 0];
|
|
81384
|
+
|
|
81385
|
+
this.dataX = [];
|
|
81386
|
+
this.dataY = [];
|
|
81387
|
+
|
|
81388
|
+
for (t = s; t <= e; t += delta) {
|
|
81389
|
+
for (i = 0; i < 3; i++) {
|
|
81390
|
+
p[i] = this.D3.F[i](t);
|
|
81391
|
+
}
|
|
81392
|
+
c2d = view.project3DTo2D(p);
|
|
81393
|
+
this.dataX.push(c2d[1]);
|
|
81394
|
+
this.dataY.push(c2d[2]);
|
|
81395
|
+
}
|
|
81396
|
+
};
|
|
81397
|
+
} else if (Type.isArray(el.D3.X)) {
|
|
81398
|
+
// 3D curve given as array of 3D points
|
|
81399
|
+
|
|
81400
|
+
el.updateDataArray = function () {
|
|
81401
|
+
var i,
|
|
81402
|
+
le = this.D3.X.length,
|
|
81403
|
+
c2d;
|
|
81404
|
+
|
|
81405
|
+
this.dataX = [];
|
|
81406
|
+
this.dataY = [];
|
|
81407
|
+
|
|
81408
|
+
for (i = 0; i < le; i++) {
|
|
81409
|
+
c2d = view.project3DTo2D([this.D3.X[i], this.D3.Y[i], this.D3.Z[i]]);
|
|
81410
|
+
this.dataX.push(c2d[1]);
|
|
81411
|
+
this.dataY.push(c2d[2]);
|
|
81412
|
+
}
|
|
81413
|
+
};
|
|
81414
|
+
}
|
|
81415
|
+
|
|
81416
|
+
return el;
|
|
81417
|
+
};
|
|
81418
|
+
JXG.registerElement('curve3d', ThreeD.createCurve);
|
|
81419
|
+
|
|
81420
|
+
});
|
|
81421
|
+
/*
|
|
81422
|
+
Copyright 2008-2022
|
|
81423
|
+
Matthias Ehmann,
|
|
81424
|
+
Carsten Miller,
|
|
81425
|
+
Andreas Walter,
|
|
81426
|
+
Alfred Wassermann
|
|
81427
|
+
|
|
81428
|
+
This file is part of JSXGraph.
|
|
81429
|
+
|
|
81430
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
81431
|
+
|
|
81432
|
+
You can redistribute it and/or modify it under the terms of the
|
|
81433
|
+
|
|
81434
|
+
* GNU Lesser General Public License as published by
|
|
81435
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
81436
|
+
(at your option) any later version
|
|
81437
|
+
OR
|
|
81438
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
81439
|
+
|
|
81440
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
81441
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
81442
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
81443
|
+
GNU Lesser General Public License for more details.
|
|
81444
|
+
|
|
81445
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
81446
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
81447
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
81448
|
+
*/
|
|
81449
|
+
/*global JXG:true, define: true*/
|
|
81450
|
+
|
|
81451
|
+
/**
|
|
81452
|
+
* Create linear spaces of dimension at least one,
|
|
81453
|
+
* i.e. lines and planes.
|
|
81454
|
+
*/
|
|
81455
|
+
define('3d/linspace3d',['jxg', 'utils/type', 'math/math', 'math/geometry', '3d/view3d'
|
|
81456
|
+
], function (JXG, Type, Mat, Geometry, ThreeD) {
|
|
81457
|
+
"use strict";
|
|
81458
|
+
|
|
81459
|
+
/**
|
|
81460
|
+
* @class This element is used to provide a constructor for a 3D line.
|
|
81461
|
+
* @pseudo
|
|
81462
|
+
* @description There are two possibilities to create a Line3D object.
|
|
81463
|
+
* <p>
|
|
81464
|
+
* First: the line in 3D is defined by two points in 3D (Point3D).
|
|
81465
|
+
* The points can be either existing points or coordinate arrays of
|
|
81466
|
+
* the form [x, y, z].
|
|
81467
|
+
* <p>Second: the line in 3D is defined by a point (or coordinate array [x, y, z])
|
|
81468
|
+
* a direction given as array [x, y, z] and an optional range
|
|
81469
|
+
* given as array [s, e]. The default value for the range is [-Infinity, Infinity].
|
|
81470
|
+
* <p>
|
|
81471
|
+
* All numbers can also be provided as functions returning a number.
|
|
81472
|
+
*
|
|
81473
|
+
* @name Line3D
|
|
81474
|
+
* @augments JXG.Curve
|
|
81475
|
+
* @constructor
|
|
81476
|
+
* @type JXG.Curve
|
|
81477
|
+
* @throws {Exception} If the element cannot be constructed with the given parent
|
|
81478
|
+
* objects an exception is thrown.
|
|
81479
|
+
* @param {JXG.Point_number,JXG.Point,JXG.Line,JXG.Circle} center,radius The center must be given as a {@link JXG.Point}, see {@link JXG.providePoints}, but the radius can be given
|
|
81480
|
+
* as a number (which will create a circle with a fixed radius), another {@link JXG.Point}, a {@link JXG.Line} (the distance of start and end point of the
|
|
81481
|
+
* line will determine the radius), or another {@link JXG.Circle}.
|
|
81482
|
+
*
|
|
81483
|
+
*/
|
|
81484
|
+
ThreeD.createLine = function (board, parents, attributes) {
|
|
81485
|
+
var view = parents[0],
|
|
81486
|
+
attr, D3, point, point1, point2,
|
|
81487
|
+
el;
|
|
81488
|
+
|
|
81489
|
+
// Range
|
|
81490
|
+
D3 = {
|
|
81491
|
+
elType: 'line3d',
|
|
81492
|
+
range: parents[3] || [-Infinity, Infinity]
|
|
81493
|
+
};
|
|
81494
|
+
|
|
81495
|
+
// Point
|
|
81496
|
+
if (Type.isPoint(parents[1])) {
|
|
81497
|
+
point = parents[1];
|
|
81498
|
+
} else {
|
|
81499
|
+
point = view.create('point3d', parents[1], { visible: false, name: '', withLabel: false });
|
|
81500
|
+
}
|
|
81501
|
+
D3.point = point;
|
|
81502
|
+
|
|
81503
|
+
// Direction
|
|
81504
|
+
if (Type.isPoint(parents[2]) && Type.exists(parents[2].D3)) {
|
|
81505
|
+
// Line defined by two points
|
|
81506
|
+
|
|
81507
|
+
point1 = point;
|
|
81508
|
+
point2 = parents[2];
|
|
81509
|
+
D3.direction = function () {
|
|
81510
|
+
return [
|
|
81511
|
+
point2.D3.X() - point.D3.X(),
|
|
81512
|
+
point2.D3.Y() - point.D3.Y(),
|
|
81513
|
+
point2.D3.Z() - point.D3.Z()
|
|
81514
|
+
];
|
|
81515
|
+
};
|
|
81516
|
+
D3.range = [0, 1];
|
|
81517
|
+
} else {
|
|
81518
|
+
// Line defined by point, direction and range
|
|
81519
|
+
|
|
81520
|
+
// Directions are handled as arrays of length 4,
|
|
81521
|
+
// i.e. with homogeneous coordinates.
|
|
81522
|
+
if (Type.isFunction(parents[2])) {
|
|
81523
|
+
D3.direction = parents[2];
|
|
81524
|
+
} else if (parents[2].length === 3) {
|
|
81525
|
+
D3.direction = [1].concat(parents[2]);
|
|
81526
|
+
} else if (parents[2].length === 4) {
|
|
81527
|
+
D3.direction = parents[2];
|
|
81528
|
+
} else {
|
|
81529
|
+
// Throw error
|
|
81530
|
+
}
|
|
81531
|
+
|
|
81532
|
+
// Direction given as array
|
|
81533
|
+
D3.getPointCoords = function (r) {
|
|
81534
|
+
var p = [],
|
|
81535
|
+
d = [],
|
|
81536
|
+
i;
|
|
81537
|
+
|
|
81538
|
+
p.push(point.D3.X());
|
|
81539
|
+
p.push(point.D3.Y());
|
|
81540
|
+
p.push(point.D3.Z());
|
|
81541
|
+
|
|
81542
|
+
if (Type.isFunction(D3.direction)) {
|
|
81543
|
+
d = D3.direction();
|
|
81544
|
+
} else {
|
|
81545
|
+
for (i = 1; i < 4; i++) {
|
|
81546
|
+
d.push(Type.evaluate(D3.direction[i]));
|
|
81547
|
+
}
|
|
81548
|
+
}
|
|
81549
|
+
if (Math.abs(r) === Infinity) {
|
|
81550
|
+
r = view.intersectionLineCube(p, d, r);
|
|
81551
|
+
}
|
|
81552
|
+
return [
|
|
81553
|
+
p[0] + d[0] * r,
|
|
81554
|
+
p[1] + d[1] * r,
|
|
81555
|
+
p[2] + d[2] * r
|
|
81556
|
+
];
|
|
81557
|
+
|
|
81558
|
+
};
|
|
81559
|
+
|
|
81560
|
+
attr = Type.copyAttributes(attributes, board.options, 'line3d', 'point1');
|
|
81561
|
+
point1 = view.create('point3d', [
|
|
81562
|
+
function () {
|
|
81563
|
+
return D3.getPointCoords(Type.evaluate(D3.range[0]));
|
|
81564
|
+
}
|
|
81565
|
+
], attr);
|
|
81566
|
+
attr = Type.copyAttributes(attributes, board.options, 'line3d', 'point2');
|
|
81567
|
+
point2 = view.create('point3d', [
|
|
81568
|
+
function () {
|
|
81569
|
+
return D3.getPointCoords(Type.evaluate(D3.range[1]));
|
|
81570
|
+
}
|
|
81571
|
+
], attr);
|
|
81572
|
+
}
|
|
81573
|
+
|
|
81574
|
+
attr = Type.copyAttributes(attributes, board.options, 'line3d');
|
|
81575
|
+
el = view.create('segment', [point1, point2], attr);
|
|
81576
|
+
el.point1 = point1;
|
|
81577
|
+
el.point2 = point2;
|
|
81578
|
+
point1.addChild(el);
|
|
81579
|
+
point2.addChild(el);
|
|
81580
|
+
el.D3 = D3;
|
|
81581
|
+
|
|
81582
|
+
return el;
|
|
81583
|
+
};
|
|
81584
|
+
JXG.registerElement('line3d', ThreeD.createLine);
|
|
81585
|
+
|
|
81586
|
+
ThreeD.createPlane = function (board, parents, attributes) {
|
|
81587
|
+
var view = parents[0],
|
|
81588
|
+
attr, D3,
|
|
81589
|
+
point,
|
|
81590
|
+
vec1 = parents[2],
|
|
81591
|
+
vec2 = parents[3],
|
|
81592
|
+
el, grid, update;
|
|
81593
|
+
|
|
81594
|
+
// D3: {
|
|
81595
|
+
// point,
|
|
81596
|
+
// vec1,
|
|
81597
|
+
// vec2,
|
|
81598
|
+
// poin1,
|
|
81599
|
+
// point2,
|
|
81600
|
+
// normal array of len 3
|
|
81601
|
+
// d
|
|
81602
|
+
// }
|
|
81603
|
+
D3 = {
|
|
81604
|
+
elType: 'plane3d',
|
|
81605
|
+
dir1: [],
|
|
81606
|
+
dir2: [],
|
|
81607
|
+
range1: parents[4],
|
|
81608
|
+
range2: parents[5],
|
|
81609
|
+
vec1: vec1,
|
|
81610
|
+
vec2: vec2
|
|
81611
|
+
};
|
|
81612
|
+
|
|
81613
|
+
if (Type.isPoint(parents[1])) {
|
|
81614
|
+
point = parents[1];
|
|
81615
|
+
} else {
|
|
81616
|
+
point = view.create('point3d', parents[1], { visible: false, name: '', withLabel: false });
|
|
81617
|
+
}
|
|
81618
|
+
D3.point = point;
|
|
81619
|
+
|
|
81620
|
+
D3.updateNormal = function () {
|
|
81621
|
+
var i;
|
|
81622
|
+
for (i = 0; i < 3; i++) {
|
|
81623
|
+
D3.dir1[i] = Type.evaluate(D3.vec1[i]);
|
|
81624
|
+
D3.dir2[i] = Type.evaluate(D3.vec2[i]);
|
|
81625
|
+
}
|
|
81626
|
+
D3.normal = Mat.crossProduct(D3.dir1, D3.dir2);
|
|
81627
|
+
D3.d = Mat.innerProduct(D3.point.D3.coords.slice(1), D3.normal, 3);
|
|
81628
|
+
};
|
|
81629
|
+
D3.updateNormal();
|
|
81630
|
+
|
|
81631
|
+
attr = Type.copyAttributes(attributes, board.options, 'plane3d');
|
|
81632
|
+
el = board.create('curve', [[], []], attr);
|
|
81633
|
+
el.D3 = D3;
|
|
81634
|
+
|
|
81635
|
+
el.updateDataArray = function () {
|
|
81636
|
+
var s1, e1, s2, e2,
|
|
81637
|
+
c2d, l1, l2,
|
|
81638
|
+
planes = ['xPlaneRear', 'yPlaneRear', 'zPlaneRear'],
|
|
81639
|
+
points = [],
|
|
81640
|
+
v1 = [0, 0, 0],
|
|
81641
|
+
v2 = [0, 0, 0],
|
|
81642
|
+
q = [0, 0, 0],
|
|
81643
|
+
p = [0, 0, 0], d, i, j, a, b, first, pos, pos_akt;
|
|
81644
|
+
|
|
81645
|
+
this.dataX = [];
|
|
81646
|
+
this.dataY = [];
|
|
81647
|
+
|
|
81648
|
+
this.D3.updateNormal();
|
|
81649
|
+
|
|
81650
|
+
// Infinite plane
|
|
81651
|
+
if (this.D3.elType !== 'axisplane3d' && view.defaultAxes &&
|
|
81652
|
+
(!D3.range1 || !D3.range2)
|
|
81653
|
+
) {
|
|
81654
|
+
|
|
81655
|
+
// Start with the rear plane.
|
|
81656
|
+
// Determine the intersections with the view bbox3d
|
|
81657
|
+
// For each face of the bbox3d we determine two points
|
|
81658
|
+
// which are the ends of the intersection line.
|
|
81659
|
+
// We start with the three rear planes.
|
|
81660
|
+
for (j = 0; j < planes.length; j++) {
|
|
81661
|
+
p = view.intersectionPlanePlane(this, view.defaultAxes[planes[j]]);
|
|
81662
|
+
|
|
81663
|
+
if (p[0].length === 3 && p[1].length === 3) {
|
|
81664
|
+
// This test is necessary to filter out intersection lines which are
|
|
81665
|
+
// identical to intersections of axis planes (they would occur twice).
|
|
81666
|
+
for (i = 0; i < points.length; i++) {
|
|
81667
|
+
if ((Geometry.distance(p[0], points[i][0], 3) < Mat.eps && Geometry.distance(p[1], points[i][1], 3) < Mat.eps) ||
|
|
81668
|
+
(Geometry.distance(p[0], points[i][1], 3) < Mat.eps && Geometry.distance(p[1], points[i][0], 3) < Mat.eps)) {
|
|
81669
|
+
break;
|
|
81670
|
+
}
|
|
81671
|
+
}
|
|
81672
|
+
if (i === points.length) {
|
|
81673
|
+
points.push(p.slice());
|
|
81674
|
+
}
|
|
81675
|
+
}
|
|
81676
|
+
|
|
81677
|
+
// Point on the front plane of the bbox3d
|
|
81678
|
+
p = [0, 0, 0];
|
|
81679
|
+
p[j] = view.D3.bbox3d[j][1];
|
|
81680
|
+
|
|
81681
|
+
// d is the rhs of the Hesse normal form of the front plane.
|
|
81682
|
+
d = Mat.innerProduct(p, view.defaultAxes[planes[j]].D3.normal, 3);
|
|
81683
|
+
p = view.intersectionPlanePlane(this, view.defaultAxes[planes[j]], d);
|
|
81684
|
+
|
|
81685
|
+
if (p[0].length === 3 && p[1].length === 3) {
|
|
81686
|
+
// Do the same test as above
|
|
81687
|
+
for (i = 0; i < points.length; i++) {
|
|
81688
|
+
if ((Geometry.distance(p[0], points[i][0], 3) < Mat.eps && Geometry.distance(p[1], points[i][1], 3) < Mat.eps) ||
|
|
81689
|
+
(Geometry.distance(p[0], points[i][1], 3) < Mat.eps && Geometry.distance(p[1], points[i][0], 3) < Mat.eps)) {
|
|
81690
|
+
break;
|
|
81691
|
+
}
|
|
81692
|
+
}
|
|
81693
|
+
if (i === points.length) {
|
|
81694
|
+
points.push(p.slice());
|
|
81695
|
+
}
|
|
81696
|
+
}
|
|
81697
|
+
}
|
|
81698
|
+
|
|
81699
|
+
// Concatenate the intersection points to a polygon.
|
|
81700
|
+
// If all wents well, each intersection should appear
|
|
81701
|
+
// twice in the list.
|
|
81702
|
+
first = 0;
|
|
81703
|
+
pos = first;
|
|
81704
|
+
i = 0;
|
|
81705
|
+
do {
|
|
81706
|
+
p = points[pos][i];
|
|
81707
|
+
if (p.length === 3) {
|
|
81708
|
+
c2d = view.project3DTo2D(p);
|
|
81709
|
+
this.dataX.push(c2d[1]);
|
|
81710
|
+
this.dataY.push(c2d[2]);
|
|
81711
|
+
}
|
|
81712
|
+
i = (i + 1) % 2;
|
|
81713
|
+
p = points[pos][i];
|
|
81714
|
+
|
|
81715
|
+
pos_akt = pos;
|
|
81716
|
+
for (j = 0; j < points.length; j++) {
|
|
81717
|
+
if (j !== pos && Geometry.distance(p, points[j][0]) < Mat.eps) {
|
|
81718
|
+
pos = j;
|
|
81719
|
+
i = 0;
|
|
81720
|
+
break;
|
|
81721
|
+
}
|
|
81722
|
+
if (j !== pos && Geometry.distance(p, points[j][1]) < Mat.eps) {
|
|
81723
|
+
pos = j;
|
|
81724
|
+
i = 1;
|
|
81725
|
+
break;
|
|
81726
|
+
}
|
|
81727
|
+
}
|
|
81728
|
+
if (pos === pos_akt) {
|
|
81729
|
+
console.log("Error: update plane3d: did not find next", pos);
|
|
81730
|
+
break;
|
|
81731
|
+
}
|
|
81732
|
+
} while (pos !== first);
|
|
81733
|
+
c2d = view.project3DTo2D(points[first][0]);
|
|
81734
|
+
this.dataX.push(c2d[1]);
|
|
81735
|
+
this.dataY.push(c2d[2]);
|
|
81736
|
+
|
|
81737
|
+
} else {
|
|
81738
|
+
// 3D bounded flat
|
|
81739
|
+
s1 = Type.evaluate(this.D3.range1[0]);
|
|
81740
|
+
e1 = Type.evaluate(this.D3.range1[1]);
|
|
81741
|
+
s2 = Type.evaluate(this.D3.range2[0]);
|
|
81742
|
+
e2 = Type.evaluate(this.D3.range2[1]);
|
|
81743
|
+
|
|
81744
|
+
q = this.D3.point.D3.coords.slice(1);
|
|
81745
|
+
|
|
81746
|
+
v1 = this.D3.dir1.slice();
|
|
81747
|
+
v2 = this.D3.dir2.slice();
|
|
81748
|
+
l1 = Mat.norm(v1, 3);
|
|
81749
|
+
l2 = Mat.norm(v2, 3);
|
|
81750
|
+
for (i = 0; i < 3; i++) {
|
|
81751
|
+
v1[i] /= l1;
|
|
81752
|
+
v2[i] /= l2;
|
|
81753
|
+
}
|
|
81754
|
+
|
|
81755
|
+
for (j = 0; j < 4; j++) {
|
|
81756
|
+
switch (j) {
|
|
81757
|
+
case 0: a = s1; b = s2; break;
|
|
81758
|
+
case 1: a = e1; b = s2; break;
|
|
81759
|
+
case 2: a = e1; b = e2; break;
|
|
81760
|
+
case 3: a = s1; b = e2;
|
|
81761
|
+
}
|
|
81762
|
+
for (i = 0; i < 3; i++) {
|
|
81763
|
+
p[i] = q[i] + a * v1[i] + b * v2[i];
|
|
81764
|
+
}
|
|
81765
|
+
c2d = view.project3DTo2D(p);
|
|
81766
|
+
this.dataX.push(c2d[1]);
|
|
81767
|
+
this.dataY.push(c2d[2]);
|
|
81768
|
+
}
|
|
81769
|
+
// Close the curve
|
|
81770
|
+
this.dataX.push(this.dataX[0]);
|
|
81771
|
+
this.dataY.push(this.dataY[0]);
|
|
81772
|
+
}
|
|
81773
|
+
};
|
|
81774
|
+
|
|
81775
|
+
attr = Type.copyAttributes(attributes.mesh3d, board.options, 'mesh3d');
|
|
81776
|
+
|
|
81777
|
+
if (D3.range1 && D3.range2) {
|
|
81778
|
+
grid = view.create('mesh3d', [point.D3.coords.slice(1), vec1, D3.range1, vec2, D3.range2], attr);
|
|
81779
|
+
el.grid = grid;
|
|
81780
|
+
el.inherits.push(grid);
|
|
81781
|
+
}
|
|
81782
|
+
|
|
81783
|
+
// update = el.update;
|
|
81784
|
+
// el.update = function () {
|
|
81785
|
+
// if (el.needsUpdate) {
|
|
81786
|
+
// update.apply(el);
|
|
81787
|
+
// }
|
|
81788
|
+
// return this;
|
|
81789
|
+
// };
|
|
81790
|
+
|
|
81791
|
+
return el;
|
|
81792
|
+
};
|
|
81793
|
+
JXG.registerElement('plane3d', ThreeD.createPlane);
|
|
81794
|
+
|
|
81795
|
+
});
|
|
81796
|
+
/*
|
|
81797
|
+
Copyright 2008-2022
|
|
81798
|
+
Matthias Ehmann,
|
|
81799
|
+
Carsten Miller,
|
|
81800
|
+
Andreas Walter,
|
|
81801
|
+
Alfred Wassermann
|
|
81802
|
+
|
|
81803
|
+
This file is part of JSXGraph.
|
|
81804
|
+
|
|
81805
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
81806
|
+
|
|
81807
|
+
You can redistribute it and/or modify it under the terms of the
|
|
81808
|
+
|
|
81809
|
+
* GNU Lesser General Public License as published by
|
|
81810
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
81811
|
+
(at your option) any later version
|
|
81812
|
+
OR
|
|
81813
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
81814
|
+
|
|
81815
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
81816
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
81817
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
81818
|
+
GNU Lesser General Public License for more details.
|
|
81819
|
+
|
|
81820
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
81821
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
81822
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
81823
|
+
*/
|
|
81824
|
+
/*global JXG:true, define: true*/
|
|
81825
|
+
|
|
81826
|
+
define('3d/point3d',['jxg', 'base/constants', 'math/math', 'math/geometry', 'utils/type', '3d/view3d'
|
|
81827
|
+
], function (JXG, Const, Mat, Geometry, Type, ThreeD) {
|
|
81828
|
+
"use strict";
|
|
81829
|
+
|
|
81830
|
+
/**
|
|
81831
|
+
* @class This element is used to provide a constructor for a 3D Point.
|
|
81832
|
+
* @pseudo
|
|
81833
|
+
* @description There are two possibilities to create a Line3D object.
|
|
81834
|
+
* <p>
|
|
81835
|
+
* First: the line in 3D is defined by two points in 3D (Point3D).
|
|
81836
|
+
* The points can be either existing points or coordinate arrays of
|
|
81837
|
+
* the form [x, y, z].
|
|
81838
|
+
* <p>Second: the line in 3D is defined by a point (or coordinate array [x, y, z])
|
|
81839
|
+
* a direction given as array [x, y, z] and an optional range
|
|
81840
|
+
* given as array [s, e]. The default value for the range is [-Infinity, Infinity].
|
|
81841
|
+
* <p>
|
|
81842
|
+
* All numbers can also be provided as functions returning a number.
|
|
81843
|
+
*
|
|
81844
|
+
* @name Point3D
|
|
81845
|
+
* @augments JXG.Point
|
|
81846
|
+
* @constructor
|
|
81847
|
+
* @type JXG.Point
|
|
81848
|
+
* @throws {Exception} If the element cannot be constructed with the given parent
|
|
81849
|
+
* objects an exception is thrown.
|
|
81850
|
+
* @param {JXG.Point_number,JXG.Point,JXG.Line,JXG.Circle} center,radius The center must be given as a {@link JXG.Point}, see {@link JXG.providePoints}, but the radius can be given
|
|
81851
|
+
* as a number (which will create a circle with a fixed radius), another {@link JXG.Point}, a {@link JXG.Line} (the distance of start and end point of the
|
|
81852
|
+
* line will determine the radius), or another {@link JXG.Circle}.
|
|
81853
|
+
*
|
|
81854
|
+
*/
|
|
81855
|
+
ThreeD.createPoint = function (board, parents, attributes) {
|
|
81856
|
+
var view = parents[0],
|
|
81857
|
+
attr, update2D, D3,
|
|
81858
|
+
i, c2d,
|
|
81859
|
+
el;
|
|
81860
|
+
|
|
81861
|
+
attr = Type.copyAttributes(attributes, board.options, 'point3d');
|
|
81862
|
+
|
|
81863
|
+
D3 = {
|
|
81864
|
+
elType: 'point3d',
|
|
81865
|
+
coords: [1, 0, 0, 0],
|
|
81866
|
+
X: function () { return this.coords[1]; },
|
|
81867
|
+
Y: function () { return this.coords[2]; },
|
|
81868
|
+
Z: function () { return this.coords[3]; }
|
|
81869
|
+
};
|
|
81870
|
+
|
|
81871
|
+
// If the last element of partents is a 3D object, the point is a glider
|
|
81872
|
+
// on that element.
|
|
81873
|
+
if (parents.length > 2 && Type.exists(parents[parents.length - 1].D3)) {
|
|
81874
|
+
D3.slide = parents.pop();
|
|
81875
|
+
} else {
|
|
81876
|
+
D3.slide = null;
|
|
81877
|
+
}
|
|
81878
|
+
|
|
81879
|
+
if (parents.length === 2) {
|
|
81880
|
+
D3.F = parents[1]; // (Array [x, y, z] | function) returning [x, y, z]
|
|
81881
|
+
D3.coords = [1].concat(Type.evaluate(D3.F));
|
|
81882
|
+
} else if (parents.length === 4) {
|
|
81883
|
+
D3.F = parents.slice(1); // 3 numbers | functions
|
|
81884
|
+
for (i = 0; i < 3; i++) {
|
|
81885
|
+
D3.coords[i + 1] = Type.evaluate(D3.F[i]);
|
|
81886
|
+
}
|
|
81887
|
+
} else {
|
|
81888
|
+
// Throw error
|
|
81889
|
+
}
|
|
81890
|
+
|
|
81891
|
+
/**
|
|
81892
|
+
* Update the 4D coords array
|
|
81893
|
+
* @returns Object
|
|
81894
|
+
*/
|
|
81895
|
+
D3.updateCoords = function () {
|
|
81896
|
+
var res, i;
|
|
81897
|
+
if (Type.isFunction(this.F)) {
|
|
81898
|
+
res = Type.evaluate(this.F);
|
|
81899
|
+
this.coords = [1, res[0], res[1], res[2]];
|
|
81900
|
+
} else {
|
|
81901
|
+
this.coords[0] = 1;
|
|
81902
|
+
for (i = 0; i < 3; i++) {
|
|
81903
|
+
if (Type.isFunction(this.F[i])) {
|
|
81904
|
+
this.coords[i + 1] = Type.evaluate(this.F[i]);
|
|
81905
|
+
}
|
|
81906
|
+
}
|
|
81907
|
+
}
|
|
81908
|
+
return this;
|
|
81909
|
+
};
|
|
81910
|
+
D3.updateCoords();
|
|
81911
|
+
|
|
81912
|
+
c2d = view.project3DTo2D(D3.coords);
|
|
81913
|
+
el = board.create('point', c2d, attr);
|
|
81914
|
+
el.D3 = D3;
|
|
81915
|
+
el.D3.c2d = el.coords.usrCoords.slice(); // Copy of the coordinates to detect dragging
|
|
81916
|
+
update2D = el.update;
|
|
81917
|
+
|
|
81918
|
+
if (el.D3.slide) {
|
|
81919
|
+
el._minFunc = function (n, m, x, con) {
|
|
81920
|
+
var surface = el.D3.slide.D3,
|
|
81921
|
+
c3d = [1, surface.X(x[0], x[1]), surface.Y(x[0], x[1]), surface.Z(x[0], x[1])],
|
|
81922
|
+
c2d = view.project3DTo2D(c3d);
|
|
81923
|
+
|
|
81924
|
+
con[0] = el.X() - c2d[1];
|
|
81925
|
+
con[1] = el.Y() - c2d[2];
|
|
81926
|
+
|
|
81927
|
+
return con[0] * con[0] + con[1] * con[1];
|
|
81928
|
+
};
|
|
81929
|
+
|
|
81930
|
+
el.projectCoords2Surface = function () {
|
|
81931
|
+
var n = 2, // # of variables
|
|
81932
|
+
m = 2, // number of constraints
|
|
81933
|
+
x = [0, 0],
|
|
81934
|
+
// Various Cobyla constants, see Cobyla docs in Cobyja.js
|
|
81935
|
+
rhobeg = 5.0,
|
|
81936
|
+
rhoend = 1.0e-6,
|
|
81937
|
+
iprint = 0,
|
|
81938
|
+
maxfun = 200,
|
|
81939
|
+
surface = this.D3.slide.D3,
|
|
81940
|
+
r, c3d, c2d;
|
|
81941
|
+
|
|
81942
|
+
if (Type.exists(this.D3.params)) {
|
|
81943
|
+
x = this.D3.params.slice();
|
|
81944
|
+
}
|
|
81945
|
+
r = Mat.Nlp.FindMinimum(this._minFunc, n, m, x, rhobeg, rhoend, iprint, maxfun);
|
|
81946
|
+
|
|
81947
|
+
c3d = [1, surface.X(x[0], x[1]), surface.Y(x[0], x[1]), surface.Z(x[0], x[1])];
|
|
81948
|
+
c2d = view.project3DTo2D(c3d);
|
|
81949
|
+
this.D3.params = x;
|
|
81950
|
+
this.D3.coords = c3d;
|
|
81951
|
+
this.coords.setCoordinates(Const.COORDS_BY_USER, c2d);
|
|
81952
|
+
this.D3.c2d = c2d;
|
|
81953
|
+
};
|
|
81954
|
+
}
|
|
81955
|
+
|
|
81956
|
+
el.update = function (drag) {
|
|
81957
|
+
var c3d, foot;
|
|
81958
|
+
if (!this.needsUpdate) {
|
|
81959
|
+
return this;
|
|
81960
|
+
}
|
|
81961
|
+
|
|
81962
|
+
// Update is called in from two methods:
|
|
81963
|
+
// Once in setToPositionDirectly and
|
|
81964
|
+
// once in the subsequent board.update
|
|
81965
|
+
if (this.draggable() &&
|
|
81966
|
+
Geometry.distance(this.D3.c2d, this.coords.usrCoords) !== 0) {
|
|
81967
|
+
|
|
81968
|
+
if (this.D3.slide) {
|
|
81969
|
+
this.projectCoords2Surface();
|
|
81970
|
+
} else {
|
|
81971
|
+
// Drag the point in its xy plane
|
|
81972
|
+
foot = [1, 0, 0, this.D3.coords[3]];
|
|
81973
|
+
c3d = view.project2DTo3DPlane(el, [1, 0, 0, 1], foot);
|
|
81974
|
+
if (c3d[0] !== 0) {
|
|
81975
|
+
this.D3.coords = view.project3DToCube(c3d);
|
|
81976
|
+
}
|
|
81977
|
+
}
|
|
81978
|
+
} else {
|
|
81979
|
+
this.D3.updateCoords();
|
|
81980
|
+
// Update 2D point from its 3D view
|
|
81981
|
+
el.coords.setCoordinates(Const.COORDS_BY_USER,
|
|
81982
|
+
view.project3DTo2D([1, this.D3.X(), this.D3.Y(), this.D3.Z()])
|
|
81983
|
+
);
|
|
81984
|
+
}
|
|
81985
|
+
this.D3.c2d = el.coords.usrCoords.slice();
|
|
81986
|
+
|
|
81987
|
+
update2D.apply(this, [drag]);
|
|
81988
|
+
return this;
|
|
81989
|
+
};
|
|
81990
|
+
|
|
81991
|
+
return el;
|
|
81992
|
+
};
|
|
81993
|
+
JXG.registerElement('point3d', ThreeD.createPoint);
|
|
81994
|
+
|
|
81995
|
+
});
|
|
81996
|
+
/*
|
|
81997
|
+
Copyright 2008-2022
|
|
81998
|
+
Matthias Ehmann,
|
|
81999
|
+
Carsten Miller,
|
|
82000
|
+
Andreas Walter,
|
|
82001
|
+
Alfred Wassermann
|
|
82002
|
+
|
|
82003
|
+
This file is part of JSXGraph.
|
|
82004
|
+
|
|
82005
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
82006
|
+
|
|
82007
|
+
You can redistribute it and/or modify it under the terms of the
|
|
82008
|
+
|
|
82009
|
+
* GNU Lesser General Public License as published by
|
|
82010
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
82011
|
+
(at your option) any later version
|
|
82012
|
+
OR
|
|
82013
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
82014
|
+
|
|
82015
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
82016
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
82017
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
82018
|
+
GNU Lesser General Public License for more details.
|
|
82019
|
+
|
|
82020
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
82021
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
82022
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
82023
|
+
*/
|
|
82024
|
+
/*global JXG:true, define: true*/
|
|
82025
|
+
|
|
82026
|
+
define('3d/surface3d',['jxg', 'utils/type', '3d/view3d'
|
|
82027
|
+
], function (JXG, Type, ThreeD) {
|
|
82028
|
+
"use strict";
|
|
82029
|
+
|
|
82030
|
+
|
|
82031
|
+
/**
|
|
82032
|
+
* @class This element creates a 3D parametric surface.
|
|
82033
|
+
* @pseudo
|
|
82034
|
+
* @description A 3D parametric surface is defined by a function
|
|
82035
|
+
* <i>F: R<sup>2</sup> → R<sup>3</sup></i>.
|
|
82036
|
+
*
|
|
82037
|
+
* @name ParametricSurface3D
|
|
82038
|
+
* @augments Curve
|
|
82039
|
+
* @constructor
|
|
82040
|
+
* @type Object
|
|
82041
|
+
* @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
82042
|
+
* @param {Function_Function_Function_Array_Array} F<sub>X</sub>,F<sub>Y</sub>,F<sub>Z</sub>,rangeX,rangeY
|
|
82043
|
+
* F<sub>X</sub>(u,v), F<sub>Y</sub>(u,v), F<sub>Z</sub>(u,v) are functions returning a number, rangeU is the array containing
|
|
82044
|
+
* lower and upper bound for the range of parameter u, rangeV is the array containing
|
|
82045
|
+
* lower and upper bound for the range of parameter v. rangeU and rangeV may also be functions returning an array of length two.
|
|
82046
|
+
* @example
|
|
82047
|
+
* var view = board.create('view3d',
|
|
82048
|
+
* [[-6, -3], [8, 8],
|
|
82049
|
+
* [[-5, 5], [-5, 5], [-5, 5]]]);
|
|
82050
|
+
*
|
|
82051
|
+
* // Sphere
|
|
82052
|
+
* var c = view.create('parametricsurface3d', [
|
|
82053
|
+
* (u, v) => 2 * Math.sin(u) * Math.cos(v),
|
|
82054
|
+
* (u, v) => 2 * Math.sin(u) * Math.sin(v),
|
|
82055
|
+
* (u, v) => 2 * Math.cos(u),
|
|
82056
|
+
* [0, 2 * Math.PI],
|
|
82057
|
+
* [0, Math.PI]
|
|
82058
|
+
* ], {
|
|
82059
|
+
* strokeColor: '#ff0000',
|
|
82060
|
+
* stepsU: 30,
|
|
82061
|
+
* stepsV: 30
|
|
82062
|
+
* });
|
|
82063
|
+
*
|
|
82064
|
+
* </pre><div id="JXG52da0ecc-1ba9-4d41-850c-36e5120025a5" class="jxgbox" style="width: 500px; height: 500px;"></div>
|
|
82065
|
+
* <script type="text/javascript">
|
|
82066
|
+
* (function() {
|
|
82067
|
+
* var board = JXG.JSXGraph.initBoard('JXG52da0ecc-1ba9-4d41-850c-36e5120025a5',
|
|
82068
|
+
* {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
|
|
82069
|
+
* var view = board.create('view3d',
|
|
82070
|
+
* [[-6, -3], [8, 8],
|
|
82071
|
+
* [[-5, 5], [-5, 5], [-5, 5]]]);
|
|
82072
|
+
*
|
|
82073
|
+
* // Sphere
|
|
82074
|
+
* var c = view.create('parametricsurface3d', [
|
|
82075
|
+
* (u, v) => 2 * Math.sin(u) * Math.cos(v),
|
|
82076
|
+
* (u, v) => 2 * Math.sin(u) * Math.sin(v),
|
|
82077
|
+
* (u, v) => 2 * Math.cos(u),
|
|
82078
|
+
* [0, 2 * Math.PI],
|
|
82079
|
+
* [0, Math.PI]
|
|
82080
|
+
* ], {
|
|
82081
|
+
* strokeColor: '#ff0000',
|
|
82082
|
+
* stepsU: 20,
|
|
82083
|
+
* stepsV: 20
|
|
82084
|
+
* });
|
|
82085
|
+
*
|
|
82086
|
+
* })();
|
|
82087
|
+
*
|
|
82088
|
+
* </script><pre>
|
|
82089
|
+
*
|
|
82090
|
+
*/
|
|
82091
|
+
ThreeD.createParametricSurface = function (board, parents, attributes) {
|
|
82092
|
+
var view = parents[0],
|
|
82093
|
+
attr,
|
|
82094
|
+
X = parents[1],
|
|
82095
|
+
Y = parents[2],
|
|
82096
|
+
Z = parents[3],
|
|
82097
|
+
range_u = parents[4],
|
|
82098
|
+
range_v = parents[5],
|
|
82099
|
+
D3, el;
|
|
82100
|
+
|
|
82101
|
+
D3 = {
|
|
82102
|
+
elType: 'surface3d',
|
|
82103
|
+
X: X,
|
|
82104
|
+
Y: Y,
|
|
82105
|
+
Z: Z,
|
|
82106
|
+
range_u: range_u,
|
|
82107
|
+
range_v: range_v
|
|
82108
|
+
};
|
|
82109
|
+
attr = Type.copyAttributes(attributes, board.options, 'surface3d');
|
|
82110
|
+
el = board.create('curve', [[], []], attr);
|
|
82111
|
+
el.updateDataArray = function () {
|
|
82112
|
+
var steps_u = Type.evaluate(this.visProp.stepsu),
|
|
82113
|
+
steps_v = Type.evaluate(this.visProp.stepsv),
|
|
82114
|
+
r_u = Type.evaluate(this.D3.range_u), // Type.evaluate(range_u),
|
|
82115
|
+
r_v = Type.evaluate(this.D3.range_v), // Type.evaluate(range_v),
|
|
82116
|
+
res = view.getMesh(this.D3.X, this.D3.Y, this.D3.Z,
|
|
82117
|
+
r_u.concat([steps_u]),
|
|
82118
|
+
r_v.concat([steps_v]));
|
|
82119
|
+
this.dataX = res[0];
|
|
82120
|
+
this.dataY = res[1];
|
|
82121
|
+
};
|
|
82122
|
+
el.D3 = D3;
|
|
82123
|
+
|
|
82124
|
+
return el;
|
|
82125
|
+
};
|
|
82126
|
+
JXG.registerElement('parametricsurface3d', ThreeD.createParametricSurface);
|
|
82127
|
+
|
|
82128
|
+
/**
|
|
82129
|
+
* @class This element creates a 3D function graph.
|
|
82130
|
+
* @pseudo
|
|
82131
|
+
* @description A 3D function graph is defined by a function
|
|
82132
|
+
* <i>F: R<sup>2</sup> → R</i>.
|
|
82133
|
+
*
|
|
82134
|
+
* @name Functiongraph3D
|
|
82135
|
+
* @augments ParametricSurface3D
|
|
82136
|
+
* @constructor
|
|
82137
|
+
* @type Object
|
|
82138
|
+
* @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
82139
|
+
* @param {Function_Array_Array} F,rangeX,rangeY F(x,y) is a function returning a number, rangeX is the array containing
|
|
82140
|
+
* lower and upper bound for the range of x, rangeY is the array containing
|
|
82141
|
+
* lower and upper bound for the range of y.
|
|
82142
|
+
* @example
|
|
82143
|
+
* var box = [-5, 5];
|
|
82144
|
+
* var view = board.create('view3d',
|
|
82145
|
+
* [
|
|
82146
|
+
* [-6, -3], [8, 8],
|
|
82147
|
+
* [box, box, box]
|
|
82148
|
+
* ],
|
|
82149
|
+
* {
|
|
82150
|
+
* xPlaneRear: {visible: false},
|
|
82151
|
+
* yPlaneRear: {visible: false},
|
|
82152
|
+
* });
|
|
82153
|
+
*
|
|
82154
|
+
* // Function F to be plotted
|
|
82155
|
+
* var F = (x, y) => Math.sin(x * y / 4);
|
|
82156
|
+
*
|
|
82157
|
+
* // 3D surface
|
|
82158
|
+
* var c = view.create('functiongraph3d', [
|
|
82159
|
+
* F,
|
|
82160
|
+
* box, // () => [-s.Value()*5, s.Value() * 5],
|
|
82161
|
+
* box, // () => [-s.Value()*5, s.Value() * 5],
|
|
82162
|
+
* ], {
|
|
82163
|
+
* strokeWidth: 0.5,
|
|
82164
|
+
* stepsU: 70,
|
|
82165
|
+
* stepsV: 70
|
|
82166
|
+
* });
|
|
82167
|
+
*
|
|
82168
|
+
* </pre><div id="JXG87646dd4-9fe5-4c21-8734-089abc612515" class="jxgbox" style="width: 500px; height: 500px;"></div>
|
|
82169
|
+
* <script type="text/javascript">
|
|
82170
|
+
* (function() {
|
|
82171
|
+
* var board = JXG.JSXGraph.initBoard('JXG87646dd4-9fe5-4c21-8734-089abc612515',
|
|
82172
|
+
* {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
|
|
82173
|
+
* var box = [-5, 5];
|
|
82174
|
+
* var view = board.create('view3d',
|
|
82175
|
+
* [
|
|
82176
|
+
* [-6, -3], [8, 8],
|
|
82177
|
+
* [box, box, box]
|
|
82178
|
+
* ],
|
|
82179
|
+
* {
|
|
82180
|
+
* xPlaneRear: {visible: false},
|
|
82181
|
+
* yPlaneRear: {visible: false},
|
|
82182
|
+
* });
|
|
82183
|
+
*
|
|
82184
|
+
* // Function F to be plotted
|
|
82185
|
+
* var F = (x, y) => Math.sin(x * y / 4);
|
|
82186
|
+
*
|
|
82187
|
+
* // 3D surface
|
|
82188
|
+
* var c = view.create('functiongraph3d', [
|
|
82189
|
+
* F,
|
|
82190
|
+
* box, // () => [-s.Value()*5, s.Value() * 5],
|
|
82191
|
+
* box, // () => [-s.Value()*5, s.Value() * 5],
|
|
82192
|
+
* ], {
|
|
82193
|
+
* strokeWidth: 0.5,
|
|
82194
|
+
* stepsU: 70,
|
|
82195
|
+
* stepsV: 70
|
|
82196
|
+
* });
|
|
82197
|
+
*
|
|
82198
|
+
* })();
|
|
82199
|
+
*
|
|
82200
|
+
* </script><pre>
|
|
82201
|
+
*
|
|
82202
|
+
*/
|
|
82203
|
+
ThreeD.createFunctiongraph = function (board, parents, attributes) {
|
|
82204
|
+
var view = parents[0],
|
|
82205
|
+
X = function(u, v) { return u; },
|
|
82206
|
+
Y = function(u, v) { return v; },
|
|
82207
|
+
Z = parents[1],
|
|
82208
|
+
range_u = parents[2],
|
|
82209
|
+
range_v = parents[3];
|
|
82210
|
+
|
|
82211
|
+
return view.create('parametricsurface3d', [X, Y, Z, range_u, range_v], attributes);
|
|
82212
|
+
};
|
|
82213
|
+
JXG.registerElement('functiongraph3d', ThreeD.createFunctiongraph);
|
|
82214
|
+
|
|
82215
|
+
});
|
|
82216
|
+
|
|
79759
82217
|
/*global define: true*/
|
|
79760
82218
|
define('../build/core.deps.js',[
|
|
79761
82219
|
'jxg',
|
|
@@ -79828,7 +82286,15 @@ define('../build/core.deps.js',[
|
|
|
79828
82286
|
'element/checkbox',
|
|
79829
82287
|
'element/input',
|
|
79830
82288
|
'element/button',
|
|
79831
|
-
'base/foreignobject'
|
|
82289
|
+
'base/foreignobject',
|
|
82290
|
+
'options3d',
|
|
82291
|
+
'3d/box3d',
|
|
82292
|
+
'3d/curve3d',
|
|
82293
|
+
'3d/linspace3d',
|
|
82294
|
+
'3d/point3d',
|
|
82295
|
+
'3d/surface3d',
|
|
82296
|
+
'3d/threed',
|
|
82297
|
+
'3d/view3d'
|
|
79832
82298
|
], function (JXG, Env) {
|
|
79833
82299
|
"use strict";
|
|
79834
82300
|
|