jsxgraph 1.4.2 → 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/distrib/README.md +24 -0
- package/distrib/geogebra.min.js +1 -1
- package/distrib/geonext.min.js +1 -1
- package/distrib/index.d.ts +351 -39
- package/distrib/intergeo.min.js +1 -1
- package/distrib/jsxgraphcore.js +4 -4
- package/distrib/jsxgraphsrc.js +2909 -389
- 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 +238 -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 +160 -84
- package/src/base/constants.js +1 -1
- package/src/base/coordselement.js +1 -4
- package/src/base/element.js +22 -13
- package/src/base/foreignobject.js +7 -1
- package/src/base/line.js +1 -1
- package/src/base/polygon.js +88 -33
- package/src/base/text.js +42 -13
- package/src/base/ticks.js +3 -1
- package/src/element/composition.js +62 -23
- package/src/element/slider.js +12 -0
- package/src/jsxgraph.js +8 -5
- 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/math/nlp.js +205 -173
- package/src/options.js +35 -13
- package/src/options3d.js +265 -0
- package/src/parser/jessiecode.js +1 -1
- package/src/reader/sketch.js +2 -2
- package/src/renderer/svg.js +7 -4
- package/src/utils/env.js +10 -10
- 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 = 5,
|
|
846
846
|
add = '', //'dev'
|
|
847
847
|
version = major + '.' + minor + '.' + patch + (add ? '-' + add : ''),
|
|
848
848
|
constants;
|
|
@@ -2026,7 +2026,7 @@ define('utils/type',[
|
|
|
2026
2026
|
}
|
|
2027
2027
|
|
|
2028
2028
|
// options from attributes
|
|
2029
|
-
o = attributes;
|
|
2029
|
+
o = (typeof attributes === 'object') ? attributes : {};
|
|
2030
2030
|
isAvail = true;
|
|
2031
2031
|
for (i = 3; i < len; i++) {
|
|
2032
2032
|
if (this.exists(o[arguments[i]])) {
|
|
@@ -2332,7 +2332,7 @@ define('utils/type',[
|
|
|
2332
2332
|
return html_sanitize(str, function () { return undefined; }, function (id) { return id; });
|
|
2333
2333
|
}
|
|
2334
2334
|
|
|
2335
|
-
if (str) {
|
|
2335
|
+
if (str && typeof str === 'string') {
|
|
2336
2336
|
str = str.replace(/</g, '<').replace(/>/g, '>');
|
|
2337
2337
|
}
|
|
2338
2338
|
|
|
@@ -3198,14 +3198,15 @@ define('utils/env',['jxg', 'utils/type'], function (JXG, Type) {
|
|
|
3198
3198
|
* @param {String} inner_id id of the DOM element which is scaled and shifted
|
|
3199
3199
|
* @param {Number} scale Scaling factor
|
|
3200
3200
|
* @param {Number} vshift Vertical shift (in pixel)
|
|
3201
|
+
* @param {Object} doc document object or shadow root
|
|
3201
3202
|
*
|
|
3202
3203
|
* @private
|
|
3203
3204
|
* @see JXG.Board#toFullscreen
|
|
3204
3205
|
* @see JXG.Board#fullscreenListener
|
|
3205
3206
|
*
|
|
3206
3207
|
*/
|
|
3207
|
-
scaleJSXGraphDiv: function (wrap_id, inner_id, scale, vshift) {
|
|
3208
|
-
var len =
|
|
3208
|
+
scaleJSXGraphDiv: function (wrap_id, inner_id, scale, vshift, doc) {
|
|
3209
|
+
var len = doc.styleSheets.length, style,
|
|
3209
3210
|
|
|
3210
3211
|
pseudo_keys = [':fullscreen', ':-webkit-full-screen', ':-moz-full-screen', ':-ms-fullscreen'],
|
|
3211
3212
|
len_pseudo = pseudo_keys.length, i,
|
|
@@ -3223,22 +3224,21 @@ define('utils/env',['jxg', 'utils/type'], function (JXG, Type) {
|
|
|
3223
3224
|
// WebKit hack :(
|
|
3224
3225
|
style.appendChild(document.createTextNode(''));
|
|
3225
3226
|
// Add the <style> element to the page
|
|
3226
|
-
|
|
3227
|
-
len =
|
|
3227
|
+
doc.appendChild(style);
|
|
3228
|
+
len = doc.styleSheets.length;
|
|
3228
3229
|
}
|
|
3229
3230
|
|
|
3230
3231
|
// Remove a previously installed CSS rule.
|
|
3231
|
-
if (
|
|
3232
|
-
regex.test(
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
document.styleSheets[len - 1].deleteRule(0);
|
|
3232
|
+
if (doc.styleSheets[len - 1].cssRules.length > 0 &&
|
|
3233
|
+
regex.test(doc.styleSheets[len - 1].cssRules[0].cssText) &&
|
|
3234
|
+
doc.styleSheets[len - 1].deleteRule) {
|
|
3235
|
+
doc.styleSheets[len - 1].deleteRule(0);
|
|
3236
3236
|
}
|
|
3237
3237
|
|
|
3238
3238
|
// Install a CSS rule to center the JSXGraph div at the first position of the list.
|
|
3239
3239
|
for (i = 0; i < len_pseudo; i++) {
|
|
3240
3240
|
try {
|
|
3241
|
-
|
|
3241
|
+
doc.styleSheets[len - 1].insertRule('#' + wrap_id + pseudo_keys[i] + ' #' + inner_id + rule_inner, 0);
|
|
3242
3242
|
break;
|
|
3243
3243
|
} catch (err) {
|
|
3244
3244
|
// console.log('JXG.scaleJSXGraphDiv: Could not add CSS rule "' + pseudo_keys[i] + '".');
|
|
@@ -3999,6 +3999,15 @@ define('math/math',['jxg', 'utils/type'], function (JXG, Type) {
|
|
|
3999
3999
|
return Math.sqrt(sum);
|
|
4000
4000
|
},
|
|
4001
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
|
+
|
|
4002
4011
|
/**
|
|
4003
4012
|
* Compute the factorial of a positive integer. If a non-integer value
|
|
4004
4013
|
* is given, the fraction will be ignored.
|
|
@@ -11749,43 +11758,43 @@ define('math/numerics',['jxg', 'utils/type', 'utils/env', 'math/math'], function
|
|
|
11749
11758
|
*/
|
|
11750
11759
|
/*
|
|
11751
11760
|
* jcobyla
|
|
11752
|
-
*
|
|
11761
|
+
*
|
|
11753
11762
|
* The MIT License
|
|
11754
11763
|
*
|
|
11755
11764
|
* Copyright (c) 2012 Anders Gustafsson, Cureos AB.
|
|
11756
11765
|
*
|
|
11757
11766
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
|
|
11758
|
-
* (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
11759
|
-
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
11767
|
+
* (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
11768
|
+
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
11760
11769
|
* subject to the following conditions:
|
|
11761
11770
|
*
|
|
11762
11771
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
11763
11772
|
*
|
|
11764
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
11765
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
11766
|
-
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
11773
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
11774
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
11775
|
+
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
11767
11776
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
11768
|
-
*
|
|
11777
|
+
*
|
|
11769
11778
|
* Remarks:
|
|
11770
|
-
*
|
|
11779
|
+
*
|
|
11771
11780
|
* The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk)
|
|
11772
11781
|
* The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998
|
|
11773
11782
|
*/
|
|
11774
11783
|
|
|
11775
11784
|
/**
|
|
11776
11785
|
* Constrained Optimization BY Linear Approximation in Java.
|
|
11777
|
-
*
|
|
11786
|
+
*
|
|
11778
11787
|
* COBYLA2 is an implementation of Powell's nonlinear derivative free constrained optimization that uses
|
|
11779
11788
|
* a linear approximation approach. The algorithm is a sequential trust region algorithm that employs linear
|
|
11780
11789
|
* approximations to the objective and constraint functions, where the approximations are formed by linear
|
|
11781
11790
|
* interpolation at n + 1 points in the space of the variables and tries to maintain a regular shaped simplex
|
|
11782
11791
|
* over iterations.
|
|
11783
|
-
*
|
|
11792
|
+
*
|
|
11784
11793
|
* It solves nonsmooth NLP with a moderate number of variables (about 100). Inequality constraints only.
|
|
11785
|
-
*
|
|
11794
|
+
*
|
|
11786
11795
|
* The initial point X is taken as one vertex of the initial simplex with zero being another, so, X should
|
|
11787
11796
|
* not be entered as the zero vector.
|
|
11788
|
-
*
|
|
11797
|
+
*
|
|
11789
11798
|
* @author Anders Gustafsson, Cureos AB. Translation to Javascript by Reinhard Oldenburg, Goethe-University
|
|
11790
11799
|
*/
|
|
11791
11800
|
|
|
@@ -11798,7 +11807,7 @@ define('math/numerics',['jxg', 'utils/type', 'utils/env', 'math/math'], function
|
|
|
11798
11807
|
utils/type
|
|
11799
11808
|
*/
|
|
11800
11809
|
|
|
11801
|
-
define('math/nlp',['jxg'], function (JXG) {
|
|
11810
|
+
define('math/nlp',['jxg', 'utils/type'], function (JXG, Type) {
|
|
11802
11811
|
|
|
11803
11812
|
"use strict";
|
|
11804
11813
|
|
|
@@ -11806,20 +11815,29 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
11806
11815
|
* The JXG.Math.Nlp namespace holds numerical algorithms for non-linear optimization.
|
|
11807
11816
|
* @name JXG.Math.Nlp
|
|
11808
11817
|
* @namespace
|
|
11809
|
-
*
|
|
11818
|
+
*
|
|
11810
11819
|
*/
|
|
11811
|
-
JXG.Math.Nlp =
|
|
11820
|
+
JXG.Math.Nlp = {
|
|
11812
11821
|
|
|
11813
|
-
arr: function(n) {
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
|
|
11822
|
+
arr: function (n) {
|
|
11823
|
+
// Is 0 initialized
|
|
11824
|
+
return new Float64Array(n);
|
|
11825
|
+
|
|
11826
|
+
// var a = new Array(n),
|
|
11827
|
+
// i;
|
|
11828
|
+
|
|
11829
|
+
// if (Type.exists(a.fill)) {
|
|
11830
|
+
// a.fill(0.0, 0, n);
|
|
11831
|
+
// } else {
|
|
11832
|
+
// for (i = 0; i < n; i++) {
|
|
11833
|
+
// a[i] = 0.0;
|
|
11834
|
+
// }
|
|
11835
|
+
// }
|
|
11836
|
+
|
|
11837
|
+
// return a;
|
|
11820
11838
|
},
|
|
11821
11839
|
|
|
11822
|
-
arr2: function(n, m) {
|
|
11840
|
+
arr2: function (n, m) {
|
|
11823
11841
|
var i = 0,
|
|
11824
11842
|
a = new Array(n);
|
|
11825
11843
|
|
|
@@ -11830,7 +11848,7 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
11830
11848
|
return a;
|
|
11831
11849
|
},
|
|
11832
11850
|
|
|
11833
|
-
arraycopy: function(x, a, iox, b, n) {
|
|
11851
|
+
arraycopy: function (x, a, iox, b, n) {
|
|
11834
11852
|
var i = 0;
|
|
11835
11853
|
while (i < n) {
|
|
11836
11854
|
iox[i + b] = x[i + a];
|
|
@@ -11860,7 +11878,7 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
11860
11878
|
* @param maxfun Maximum number of function evaluations before terminating.
|
|
11861
11879
|
* @returns {Number} Exit status of the COBYLA2 optimization.
|
|
11862
11880
|
*/
|
|
11863
|
-
FindMinimum: function(calcfc, n,
|
|
11881
|
+
FindMinimum: function (calcfc, n, m, x, rhobeg, rhoend, iprint, maxfun) {
|
|
11864
11882
|
// CobylaExitStatus FindMinimum(final Calcfc calcfc, int n, int m, double[] x, double rhobeg, double rhoend, int iprint, int maxfun)
|
|
11865
11883
|
// This subroutine minimizes an objective function F(X) subject to M
|
|
11866
11884
|
// inequality constraints on X, where X is a vector of variables that has
|
|
@@ -11924,16 +11942,16 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
11924
11942
|
|
|
11925
11943
|
// Internal representation of the objective and constraints calculation method,
|
|
11926
11944
|
// accounting for that X and CON arrays in the cobylb method are base-1 arrays.
|
|
11927
|
-
fcalcfc = function(n, m, thisx, con) { // int n, int m, double[] x, double[] con
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11945
|
+
fcalcfc = function (n, m, thisx, con) { // int n, int m, double[] x, double[] con
|
|
11946
|
+
var ix = that.arr(n),
|
|
11947
|
+
ocon, f;
|
|
11948
|
+
|
|
11949
|
+
that.arraycopy(thisx, 1, ix, 0, n);
|
|
11950
|
+
ocon = that.arr(m);
|
|
11951
|
+
f = calcfc(n, m, ix, ocon);
|
|
11952
|
+
that.arraycopy(ocon, 0, con, 1, m);
|
|
11953
|
+
return f;
|
|
11954
|
+
};
|
|
11937
11955
|
|
|
11938
11956
|
status = this.cobylb(fcalcfc, n, m, mpp, iox, rhobeg, rhoend, iprint, maxfun);
|
|
11939
11957
|
this.arraycopy(iox, 1, x, 0, n);
|
|
@@ -11945,18 +11963,18 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
11945
11963
|
// double rhobeg, double rhoend, int iprint, int maxfun)
|
|
11946
11964
|
/**
|
|
11947
11965
|
* JavaScript implementation of the non-linear optimization method COBYLA.
|
|
11948
|
-
* @param {Function} calcfc
|
|
11949
|
-
* @param {Number} n
|
|
11950
|
-
* @param {Number} m
|
|
11951
|
-
* @param {Number} mpp
|
|
11952
|
-
* @param {Number} x
|
|
11953
|
-
* @param {Number} rhobeg
|
|
11954
|
-
* @param {Number} rhoend
|
|
11955
|
-
* @param {Number} iprint
|
|
11956
|
-
* @param {Number} maxfun
|
|
11966
|
+
* @param {Function} calcfc
|
|
11967
|
+
* @param {Number} n
|
|
11968
|
+
* @param {Number} m
|
|
11969
|
+
* @param {Number} mpp
|
|
11970
|
+
* @param {Number} x
|
|
11971
|
+
* @param {Number} rhobeg
|
|
11972
|
+
* @param {Number} rhoend
|
|
11973
|
+
* @param {Number} iprint
|
|
11974
|
+
* @param {Number} maxfun
|
|
11957
11975
|
* @returns {Number} Exit status of the COBYLA2 optimization
|
|
11958
11976
|
*/
|
|
11959
|
-
cobylb: function (calcfc, n,
|
|
11977
|
+
cobylb: function (calcfc, n, m, mpp, x, rhobeg, rhoend, iprint, maxfun) {
|
|
11960
11978
|
// calcf ist funktion die aufgerufen wird wie calcfc(n, m, ix, ocon)
|
|
11961
11979
|
// N.B. Arguments CON, SIM, SIMI, DATMAT, A, VSIG, VETA, SIGBAR, DX, W & IACT
|
|
11962
11980
|
// have been removed.
|
|
@@ -12132,8 +12150,7 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12132
12150
|
sim[i][np] += temp;
|
|
12133
12151
|
|
|
12134
12152
|
tempa = 0.0;
|
|
12135
|
-
for (k = 1; k <= n; ++k)
|
|
12136
|
-
{
|
|
12153
|
+
for (k = 1; k <= n; ++k) {
|
|
12137
12154
|
sim[i][k] -= temp;
|
|
12138
12155
|
tempa -= simi[k][i];
|
|
12139
12156
|
}
|
|
@@ -12144,13 +12161,17 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12144
12161
|
// Make an error return if SIGI is a poor approximation to the inverse of
|
|
12145
12162
|
// the leading N by N submatrix of SIG.
|
|
12146
12163
|
error = 0.0;
|
|
12147
|
-
|
|
12148
|
-
for (
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12164
|
+
if (false) {
|
|
12165
|
+
for (i = 1; i <= n; ++i) {
|
|
12166
|
+
for (j = 1; j <= n; ++j) {
|
|
12167
|
+
temp = this.DOT_PRODUCT_ROW_COL(simi, i, sim, j, 1, n) - (i === j ? 1.0 : 0.0);
|
|
12168
|
+
// temp = this.DOT_PRODUCT(
|
|
12169
|
+
// this.PART(this.ROW(simi, i), 1, n),
|
|
12170
|
+
// this.PART(this.COL(sim, j), 1, n)
|
|
12171
|
+
// ) - (i === j ? 1.0 : 0.0);
|
|
12172
|
+
|
|
12173
|
+
error = Math.max(error, Math.abs(temp));
|
|
12174
|
+
}
|
|
12154
12175
|
}
|
|
12155
12176
|
}
|
|
12156
12177
|
if (error > 0.1) {
|
|
@@ -12169,8 +12190,9 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12169
12190
|
}
|
|
12170
12191
|
|
|
12171
12192
|
for (i = 1; i <= n; ++i) {
|
|
12172
|
-
a[i][k] = (k === mp ? -1.0 : 1.0) *
|
|
12173
|
-
this.
|
|
12193
|
+
a[i][k] = (k === mp ? -1.0 : 1.0) *
|
|
12194
|
+
this.DOT_PRODUCT_ROW_COL(w, -1, simi, i, 1, n);
|
|
12195
|
+
// this.DOT_PRODUCT(this.PART(w, 1, n), this.PART(this.COL(simi, i), 1, n));
|
|
12174
12196
|
}
|
|
12175
12197
|
}
|
|
12176
12198
|
|
|
@@ -12182,11 +12204,9 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12182
12204
|
|
|
12183
12205
|
for (j = 1; j <= n; ++j) {
|
|
12184
12206
|
wsig = 0.0;
|
|
12185
|
-
for (k = 1; k <= n; ++k) {
|
|
12186
|
-
wsig += simi[j][k] * simi[j][k];
|
|
12187
|
-
}
|
|
12188
12207
|
weta = 0.0;
|
|
12189
12208
|
for (k = 1; k <= n; ++k) {
|
|
12209
|
+
wsig += simi[j][k] * simi[j][k];
|
|
12190
12210
|
weta += sim[k][j] * sim[k][j];
|
|
12191
12211
|
}
|
|
12192
12212
|
vsig[j] = 1.0 / Math.sqrt(wsig);
|
|
@@ -12223,10 +12243,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12223
12243
|
cvmaxm = 0.0;
|
|
12224
12244
|
total = 0.0;
|
|
12225
12245
|
for (k = 1; k <= mp; ++k) {
|
|
12226
|
-
total = this.DOT_PRODUCT(
|
|
12227
|
-
|
|
12228
|
-
this.PART(dx, 1, n)
|
|
12229
|
-
);
|
|
12246
|
+
// total = this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
|
|
12247
|
+
total = this.DOT_PRODUCT_ROW_COL(dx, -1, a, k, 1, n);
|
|
12230
12248
|
if (k < mp) {
|
|
12231
12249
|
temp = datmat[k][np];
|
|
12232
12250
|
cvmaxp = Math.max(cvmaxp, -total - temp);
|
|
@@ -12248,10 +12266,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12248
12266
|
|
|
12249
12267
|
for (j = 1; j <= n; ++j) {
|
|
12250
12268
|
if (j !== jdrop) {
|
|
12251
|
-
temp = this.DOT_PRODUCT(
|
|
12252
|
-
|
|
12253
|
-
this.PART(dx, 1, n)
|
|
12254
|
-
);
|
|
12269
|
+
// temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
|
|
12270
|
+
temp = this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n);
|
|
12255
12271
|
for (k = 1; k <= n; ++k) {
|
|
12256
12272
|
simi[j][k] -= temp * simi[jdrop][k];
|
|
12257
12273
|
}
|
|
@@ -12281,7 +12297,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12281
12297
|
resnew = 0.0;
|
|
12282
12298
|
con[mp] = 0.0;
|
|
12283
12299
|
for (k = 1; k <= mp; ++k) {
|
|
12284
|
-
total = con[k] - this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
|
|
12300
|
+
//total = con[k] - this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
|
|
12301
|
+
total = con[k] - this.DOT_PRODUCT_ROW_COL(dx, -1, a, k, 1, n);
|
|
12285
12302
|
if (k < mp) { resnew = Math.max(resnew, total); }
|
|
12286
12303
|
}
|
|
12287
12304
|
|
|
@@ -12329,7 +12346,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12329
12346
|
ratio = trured <= 0.0 ? 1.0 : 0.0;
|
|
12330
12347
|
jdrop = 0;
|
|
12331
12348
|
for (j = 1; j <= n; ++j) {
|
|
12332
|
-
temp = Math.abs(this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n)));
|
|
12349
|
+
// temp = Math.abs(this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n)));
|
|
12350
|
+
temp = Math.abs(this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n));
|
|
12333
12351
|
if (temp > ratio) {
|
|
12334
12352
|
jdrop = j;
|
|
12335
12353
|
ratio = temp;
|
|
@@ -12369,7 +12387,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12369
12387
|
for (k = 1; k <= n; ++k) { simi[jdrop][k] /= temp; }
|
|
12370
12388
|
for (j = 1; j <= n; ++j) {
|
|
12371
12389
|
if (j !== jdrop) {
|
|
12372
|
-
temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
|
|
12390
|
+
// temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
|
|
12391
|
+
temp = this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n);
|
|
12373
12392
|
for (k = 1; k <= n; ++k) {
|
|
12374
12393
|
simi[j][k] -= temp * simi[jdrop][k];
|
|
12375
12394
|
}
|
|
@@ -12422,7 +12441,7 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12422
12441
|
}
|
|
12423
12442
|
}
|
|
12424
12443
|
if (iprint >= 2) {
|
|
12425
|
-
console.log("Reduction in RHO to "+rho+" and PARMU = "+parmu);
|
|
12444
|
+
console.log("Reduction in RHO to " + rho + " and PARMU = " + parmu);
|
|
12426
12445
|
}
|
|
12427
12446
|
if (iprint === 2) {
|
|
12428
12447
|
this.PrintIterationResult(nfvals, datmat[mp][np], datmat[mpp][np], this.COL(sim, np), n, iprint);
|
|
@@ -12458,7 +12477,7 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12458
12477
|
return status;
|
|
12459
12478
|
},
|
|
12460
12479
|
|
|
12461
|
-
trstlp: function(n,
|
|
12480
|
+
trstlp: function (n, m, a, b, rho, dx) { //(int n, int m, double[][] a, double[] b, double rho, double[] dx)
|
|
12462
12481
|
// N.B. Arguments Z, ZDOTA, VMULTC, SDIRN, DXNEW, VMULTD & IACT have been removed.
|
|
12463
12482
|
|
|
12464
12483
|
// This subroutine calculates an N-component vector DX by applying the
|
|
@@ -12572,9 +12591,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12572
12591
|
|
|
12573
12592
|
L_70:
|
|
12574
12593
|
do {
|
|
12575
|
-
optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT(
|
|
12576
|
-
|
|
12577
|
-
);
|
|
12594
|
+
// optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT(this.PART(dx, 1, n), this.PART(this.COL(a, mcon), 1, n));
|
|
12595
|
+
optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT_ROW_COL(dx, -1, a, mcon, 1, n);
|
|
12578
12596
|
|
|
12579
12597
|
if (icount === 0 || optnew < optold) {
|
|
12580
12598
|
optold = optnew;
|
|
@@ -12605,9 +12623,9 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12605
12623
|
kp = k + 1;
|
|
12606
12624
|
kk = iact[kp];
|
|
12607
12625
|
sp = this.DOT_PRODUCT(
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12626
|
+
this.PART(this.COL(z, k), 1, n),
|
|
12627
|
+
this.PART(this.COL(a, kk), 1, n)
|
|
12628
|
+
);
|
|
12611
12629
|
temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]);
|
|
12612
12630
|
alpha = zdota[kp] / temp;
|
|
12613
12631
|
beta = sp / temp;
|
|
@@ -12635,9 +12653,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12635
12653
|
temp = 1.0 / zdota[nact];
|
|
12636
12654
|
for (k = 1; k <= n; ++k) { sdirn[k] = temp * z[k][nact]; }
|
|
12637
12655
|
} else {
|
|
12638
|
-
temp = this.DOT_PRODUCT(
|
|
12639
|
-
|
|
12640
|
-
);
|
|
12656
|
+
// temp = this.DOT_PRODUCT(this.PART(sdirn, 1, n), this.PART(this.COL(z, nact + 1), 1, n));
|
|
12657
|
+
temp = this.DOT_PRODUCT_ROW_COL(sdirn, -1, z, nact + 1, 1, n);
|
|
12641
12658
|
for (k = 1; k <= n; ++k) { sdirn[k] -= temp * z[k][nact + 1]; }
|
|
12642
12659
|
}
|
|
12643
12660
|
} else {
|
|
@@ -12646,34 +12663,34 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12646
12663
|
tot = 0.0;
|
|
12647
12664
|
|
|
12648
12665
|
// {
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12666
|
+
k = n;
|
|
12667
|
+
while (k > nact) {
|
|
12668
|
+
sp = 0.0;
|
|
12669
|
+
spabs = 0.0;
|
|
12670
|
+
for (i = 1; i <= n; ++i) {
|
|
12671
|
+
temp = z[i][k] * dxnew[i];
|
|
12672
|
+
sp += temp;
|
|
12673
|
+
spabs += Math.abs(temp);
|
|
12674
|
+
}
|
|
12675
|
+
acca = spabs + 0.1 * Math.abs(sp);
|
|
12676
|
+
accb = spabs + 0.2 * Math.abs(sp);
|
|
12677
|
+
if (spabs >= acca || acca >= accb) { sp = 0.0; }
|
|
12678
|
+
if (tot === 0.0) {
|
|
12679
|
+
tot = sp;
|
|
12680
|
+
} else {
|
|
12681
|
+
kp = k + 1;
|
|
12682
|
+
temp = Math.sqrt(sp * sp + tot * tot);
|
|
12683
|
+
alpha = sp / temp;
|
|
12684
|
+
beta = tot / temp;
|
|
12685
|
+
tot = temp;
|
|
12653
12686
|
for (i = 1; i <= n; ++i) {
|
|
12654
|
-
temp = z[i][k] *
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
}
|
|
12658
|
-
acca = spabs + 0.1 * Math.abs(sp);
|
|
12659
|
-
accb = spabs + 0.2 * Math.abs(sp);
|
|
12660
|
-
if (spabs >= acca || acca >= accb) { sp = 0.0; }
|
|
12661
|
-
if (tot === 0.0) {
|
|
12662
|
-
tot = sp;
|
|
12663
|
-
} else {
|
|
12664
|
-
kp = k + 1;
|
|
12665
|
-
temp = Math.sqrt(sp * sp + tot * tot);
|
|
12666
|
-
alpha = sp / temp;
|
|
12667
|
-
beta = tot / temp;
|
|
12668
|
-
tot = temp;
|
|
12669
|
-
for (i = 1; i <= n; ++i) {
|
|
12670
|
-
temp = alpha * z[i][k] + beta * z[i][kp];
|
|
12671
|
-
z[i][kp] = alpha * z[i][kp] - beta * z[i][k];
|
|
12672
|
-
z[i][k] = temp;
|
|
12673
|
-
}
|
|
12687
|
+
temp = alpha * z[i][k] + beta * z[i][kp];
|
|
12688
|
+
z[i][kp] = alpha * z[i][kp] - beta * z[i][k];
|
|
12689
|
+
z[i][k] = temp;
|
|
12674
12690
|
}
|
|
12675
|
-
--k;
|
|
12676
12691
|
}
|
|
12692
|
+
--k;
|
|
12693
|
+
}
|
|
12677
12694
|
// }
|
|
12678
12695
|
|
|
12679
12696
|
if (tot === 0.0) {
|
|
@@ -12686,34 +12703,34 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12686
12703
|
|
|
12687
12704
|
ratio = -1.0;
|
|
12688
12705
|
//{
|
|
12689
|
-
|
|
12690
|
-
|
|
12691
|
-
|
|
12692
|
-
|
|
12706
|
+
k = nact;
|
|
12707
|
+
do {
|
|
12708
|
+
zdotv = 0.0;
|
|
12709
|
+
zdvabs = 0.0;
|
|
12693
12710
|
|
|
12694
|
-
|
|
12695
|
-
|
|
12696
|
-
|
|
12697
|
-
|
|
12711
|
+
for (i = 1; i <= n; ++i) {
|
|
12712
|
+
temp = z[i][k] * dxnew[i];
|
|
12713
|
+
zdotv += temp;
|
|
12714
|
+
zdvabs += Math.abs(temp);
|
|
12715
|
+
}
|
|
12716
|
+
acca = zdvabs + 0.1 * Math.abs(zdotv);
|
|
12717
|
+
accb = zdvabs + 0.2 * Math.abs(zdotv);
|
|
12718
|
+
if (zdvabs < acca && acca < accb) {
|
|
12719
|
+
temp = zdotv / zdota[k];
|
|
12720
|
+
if (temp > 0.0 && iact[k] <= m) {
|
|
12721
|
+
tempa = vmultc[k] / temp;
|
|
12722
|
+
if (ratio < 0.0 || tempa < ratio) { ratio = tempa; }
|
|
12698
12723
|
}
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
if (temp > 0.0 && iact[k] <= m) {
|
|
12704
|
-
tempa = vmultc[k] / temp;
|
|
12705
|
-
if (ratio < 0.0 || tempa < ratio) { ratio = tempa; }
|
|
12706
|
-
}
|
|
12707
|
-
|
|
12708
|
-
if (k >= 2) {
|
|
12709
|
-
kw = iact[k];
|
|
12710
|
-
for (i = 1; i <= n; ++i) { dxnew[i] -= temp * a[i][kw]; }
|
|
12711
|
-
}
|
|
12712
|
-
vmultd[k] = temp;
|
|
12713
|
-
} else {
|
|
12714
|
-
vmultd[k] = 0.0;
|
|
12724
|
+
|
|
12725
|
+
if (k >= 2) {
|
|
12726
|
+
kw = iact[k];
|
|
12727
|
+
for (i = 1; i <= n; ++i) { dxnew[i] -= temp * a[i][kw]; }
|
|
12715
12728
|
}
|
|
12716
|
-
|
|
12729
|
+
vmultd[k] = temp;
|
|
12730
|
+
} else {
|
|
12731
|
+
vmultd[k] = 0.0;
|
|
12732
|
+
}
|
|
12733
|
+
} while (--k > 0);
|
|
12717
12734
|
//}
|
|
12718
12735
|
if (ratio < 0.0) { break L_60; }
|
|
12719
12736
|
|
|
@@ -12732,9 +12749,9 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12732
12749
|
kp = k + 1;
|
|
12733
12750
|
kw = iact[kp];
|
|
12734
12751
|
sp = this.DOT_PRODUCT(
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12752
|
+
this.PART(this.COL(z, k), 1, n),
|
|
12753
|
+
this.PART(this.COL(a, kw), 1, n)
|
|
12754
|
+
);
|
|
12738
12755
|
temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]);
|
|
12739
12756
|
alpha = zdota[kp] / temp;
|
|
12740
12757
|
beta = sp / temp;
|
|
@@ -12753,9 +12770,9 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12753
12770
|
vmultc[k] = vsave;
|
|
12754
12771
|
}
|
|
12755
12772
|
temp = this.DOT_PRODUCT(
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12773
|
+
this.PART(this.COL(z, nact), 1, n),
|
|
12774
|
+
this.PART(this.COL(a, kk), 1, n)
|
|
12775
|
+
);
|
|
12759
12776
|
if (temp === 0.0) { break L_60; }
|
|
12760
12777
|
zdota[nact] = temp;
|
|
12761
12778
|
vmultc[icon] = 0.0;
|
|
@@ -12778,9 +12795,9 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12778
12795
|
if (mcon > m && kk !== mcon) {
|
|
12779
12796
|
k = nact - 1;
|
|
12780
12797
|
sp = this.DOT_PRODUCT(
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12798
|
+
this.PART(this.COL(z, k), 1, n),
|
|
12799
|
+
this.PART(this.COL(a, kk), 1, n)
|
|
12800
|
+
);
|
|
12784
12801
|
temp = Math.sqrt(sp * sp + zdota[nact] * zdota[nact]);
|
|
12785
12802
|
alpha = zdota[nact] / temp;
|
|
12786
12803
|
beta = sp / temp;
|
|
@@ -12806,10 +12823,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12806
12823
|
for (k = 1; k <= n; ++k) { sdirn[k] = temp * z[k][nact]; }
|
|
12807
12824
|
} else {
|
|
12808
12825
|
kk = iact[nact];
|
|
12809
|
-
temp = (this.DOT_PRODUCT(
|
|
12810
|
-
|
|
12811
|
-
this.PART(this.COL(a, kk), 1, n)
|
|
12812
|
-
) - 1.0) / zdota[nact];
|
|
12826
|
+
// temp = (this.DOT_PRODUCT(this.PART(sdirn, 1, n),this.PART(this.COL(a, kk), 1, n)) - 1.0) / zdota[nact];
|
|
12827
|
+
temp = (this.DOT_PRODUCT_ROW_COL(sdirn, -1, a, kk, 1, n) - 1.0) / zdota[nact];
|
|
12813
12828
|
for (k = 1; k <= n; ++k) { sdirn[k] -= temp * z[k][nact]; }
|
|
12814
12829
|
}
|
|
12815
12830
|
}
|
|
@@ -12849,9 +12864,8 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12849
12864
|
resmax = 0.0;
|
|
12850
12865
|
for (k = 1; k <= nact; ++k) {
|
|
12851
12866
|
kk = iact[k];
|
|
12852
|
-
temp = b[kk] - this.DOT_PRODUCT(
|
|
12853
|
-
|
|
12854
|
-
);
|
|
12867
|
+
// temp = b[kk] - this.DOT_PRODUCT(this.PART(this.COL(a, kk), 1, n), this.PART(dxnew, 1, n));
|
|
12868
|
+
temp = b[kk] - this.DOT_PRODUCT_ROW_COL(dxnew, -1, a, kk, 1, n);
|
|
12855
12869
|
resmax = Math.max(resmax, temp);
|
|
12856
12870
|
}
|
|
12857
12871
|
}
|
|
@@ -12861,25 +12875,25 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12861
12875
|
// can be attributed to computer rounding errors. First calculate the new
|
|
12862
12876
|
// Lagrange multipliers.
|
|
12863
12877
|
//{
|
|
12864
|
-
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12878
|
+
k = nact;
|
|
12879
|
+
do {
|
|
12880
|
+
zdotw = 0.0;
|
|
12881
|
+
zdwabs = 0.0;
|
|
12882
|
+
for (i = 1; i <= n; ++i) {
|
|
12883
|
+
temp = z[i][k] * dxnew[i];
|
|
12884
|
+
zdotw += temp;
|
|
12885
|
+
zdwabs += Math.abs(temp);
|
|
12886
|
+
}
|
|
12887
|
+
acca = zdwabs + 0.1 * Math.abs(zdotw);
|
|
12888
|
+
accb = zdwabs + 0.2 * Math.abs(zdotw);
|
|
12889
|
+
if (zdwabs >= acca || acca >= accb) { zdotw = 0.0; }
|
|
12890
|
+
vmultd[k] = zdotw / zdota[k];
|
|
12891
|
+
if (k >= 2) {
|
|
12892
|
+
kk = iact[k];
|
|
12893
|
+
for (i = 1; i <= n; ++i) { dxnew[i] -= vmultd[k] * a[i][kk]; }
|
|
12894
|
+
}
|
|
12895
|
+
} while (k-- >= 2);
|
|
12896
|
+
if (mcon > m) { vmultd[nact] = Math.max(0.0, vmultd[nact]); }
|
|
12883
12897
|
//}
|
|
12884
12898
|
|
|
12885
12899
|
// Complete VMULTC by finding the new constraint residuals.
|
|
@@ -12944,12 +12958,12 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12944
12958
|
return false;
|
|
12945
12959
|
},
|
|
12946
12960
|
|
|
12947
|
-
PrintIterationResult: function(nfvals, f, resmax,
|
|
12948
|
-
if (iprint > 1) { console.log("NFVALS = "+nfvals+" F = "+f+" MAXCV = "+resmax); }
|
|
12961
|
+
PrintIterationResult: function (nfvals, f, resmax, x, n, iprint) {
|
|
12962
|
+
if (iprint > 1) { console.log("NFVALS = " + nfvals + " F = " + f + " MAXCV = " + resmax); }
|
|
12949
12963
|
if (iprint > 1) { console.log("X = " + this.PART(x, 1, n)); }
|
|
12950
12964
|
},
|
|
12951
12965
|
|
|
12952
|
-
ROW: function(src, rowidx) {
|
|
12966
|
+
ROW: function (src, rowidx) {
|
|
12953
12967
|
return src[rowidx].slice();
|
|
12954
12968
|
// var col,
|
|
12955
12969
|
// cols = src[0].length,
|
|
@@ -12961,17 +12975,18 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12961
12975
|
// return dest;
|
|
12962
12976
|
},
|
|
12963
12977
|
|
|
12964
|
-
COL: function(src, colidx) {
|
|
12978
|
+
COL: function (src, colidx) {
|
|
12965
12979
|
var row,
|
|
12966
12980
|
rows = src.length,
|
|
12967
|
-
dest = this.arr(rows);
|
|
12981
|
+
dest = []; // this.arr(rows);
|
|
12982
|
+
|
|
12968
12983
|
for (row = 0; row < rows; ++row) {
|
|
12969
12984
|
dest[row] = src[row][colidx];
|
|
12970
12985
|
}
|
|
12971
12986
|
return dest;
|
|
12972
12987
|
},
|
|
12973
12988
|
|
|
12974
|
-
PART: function(src, from, to) {
|
|
12989
|
+
PART: function (src, from, to) {
|
|
12975
12990
|
return src.slice(from, to + 1);
|
|
12976
12991
|
// var srcidx,
|
|
12977
12992
|
// dest = this.arr(to - from + 1),
|
|
@@ -12982,7 +12997,7 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12982
12997
|
// return dest;
|
|
12983
12998
|
},
|
|
12984
12999
|
|
|
12985
|
-
FORMAT: function(x) {
|
|
13000
|
+
FORMAT: function (x) {
|
|
12986
13001
|
return x.join(',');
|
|
12987
13002
|
// var i, fmt = "";
|
|
12988
13003
|
// for (i = 0; i < x.length; ++i) {
|
|
@@ -12991,12 +13006,38 @@ define('math/nlp',['jxg'], function (JXG) {
|
|
|
12991
13006
|
// return fmt;
|
|
12992
13007
|
},
|
|
12993
13008
|
|
|
12994
|
-
DOT_PRODUCT: function(lhs,
|
|
13009
|
+
DOT_PRODUCT: function (lhs, rhs) {
|
|
12995
13010
|
var i, sum = 0.0,
|
|
12996
13011
|
len = lhs.length;
|
|
12997
13012
|
for (i = 0; i < len; ++i) {
|
|
12998
13013
|
sum += lhs[i] * rhs[i];
|
|
12999
13014
|
}
|
|
13015
|
+
return sum;
|
|
13016
|
+
},
|
|
13017
|
+
|
|
13018
|
+
DOT_PRODUCT_ROW_COL: function (lhs, row, rhs, col, start, end) {
|
|
13019
|
+
var i, sum = 0.0;
|
|
13020
|
+
|
|
13021
|
+
if (row === -1) {
|
|
13022
|
+
// lhs is vector
|
|
13023
|
+
for (i = start; i <= end; ++i) {
|
|
13024
|
+
sum += lhs[i] * rhs[i][col];
|
|
13025
|
+
}
|
|
13026
|
+
} else {
|
|
13027
|
+
// lhs is row of matrix
|
|
13028
|
+
if (col === -1) {
|
|
13029
|
+
// rhs is vector
|
|
13030
|
+
for (i = start; i <= end; ++i) {
|
|
13031
|
+
sum += lhs[row][i] * rhs[i];
|
|
13032
|
+
}
|
|
13033
|
+
} else {
|
|
13034
|
+
// rhs is column of matrix
|
|
13035
|
+
for (i = start; i <= end; ++i) {
|
|
13036
|
+
sum += lhs[row][i] * rhs[i][col];
|
|
13037
|
+
}
|
|
13038
|
+
}
|
|
13039
|
+
}
|
|
13040
|
+
|
|
13000
13041
|
return sum;
|
|
13001
13042
|
}
|
|
13002
13043
|
|
|
@@ -14728,6 +14769,30 @@ define('math/geometry',[
|
|
|
14728
14769
|
return that.meetCurveLine(el1, el2, i, el1.board, alwaysintersect);
|
|
14729
14770
|
};
|
|
14730
14771
|
|
|
14772
|
+
} else if (el1.type === Const.OBJECT_TYPE_POLYGON || el2.type === Const.OBJECT_TYPE_POLYGON) {
|
|
14773
|
+
// polygon - other
|
|
14774
|
+
// Uses the Greiner-Hormann clipping algorithm
|
|
14775
|
+
// Not implemented: polygon - point
|
|
14776
|
+
|
|
14777
|
+
if (el1.elementClass === Const.OBJECT_CLASS_LINE) {
|
|
14778
|
+
// line - path
|
|
14779
|
+
/** @ignore */
|
|
14780
|
+
func = function () {
|
|
14781
|
+
return that.meetPolygonLine(el2, el1, i, el1.board, alwaysintersect);
|
|
14782
|
+
};
|
|
14783
|
+
} else if (el2.elementClass === Const.OBJECT_CLASS_LINE) {
|
|
14784
|
+
// path - line
|
|
14785
|
+
func = function () {
|
|
14786
|
+
return that.meetPolygonLine(el1, el2, i, el1.board, alwaysintersect);
|
|
14787
|
+
};
|
|
14788
|
+
} else {
|
|
14789
|
+
// path - path
|
|
14790
|
+
/** @ignore */
|
|
14791
|
+
func = function () {
|
|
14792
|
+
return that.meetPathPath(el1, el2, i, el1.board);
|
|
14793
|
+
};
|
|
14794
|
+
}
|
|
14795
|
+
|
|
14731
14796
|
} else if (el1.elementClass === Const.OBJECT_CLASS_LINE && el2.elementClass === Const.OBJECT_CLASS_LINE) {
|
|
14732
14797
|
// line - line, lines may also be segments.
|
|
14733
14798
|
/** @ignore */
|
|
@@ -15143,6 +15208,8 @@ define('math/geometry',[
|
|
|
15143
15208
|
* @param {JXG.Line} li Line
|
|
15144
15209
|
* @param {Number} nr Will return the nr-th intersection point.
|
|
15145
15210
|
* @param {JXG.Board} board
|
|
15211
|
+
* @param {Boolean} testSegment Test if intersection has to be inside of the segment or somewhere on the
|
|
15212
|
+
* line defined by the segment
|
|
15146
15213
|
* @returns {JXG.Coords} Coords object containing the intersection.
|
|
15147
15214
|
*/
|
|
15148
15215
|
meetCurveLineContinuous: function (cu, li, nr, board, testSegment) {
|
|
@@ -15207,7 +15274,6 @@ define('math/geometry',[
|
|
|
15207
15274
|
return (new Coords(Const.COORDS_BY_USER, [z, cu.X(t), cu.Y(t)], board));
|
|
15208
15275
|
},
|
|
15209
15276
|
|
|
15210
|
-
|
|
15211
15277
|
/**
|
|
15212
15278
|
* Intersection of line and curve, discrete case.
|
|
15213
15279
|
* Segments are treated as lines.
|
|
@@ -15394,6 +15460,87 @@ define('math/geometry',[
|
|
|
15394
15460
|
return [c, t, u];
|
|
15395
15461
|
},
|
|
15396
15462
|
|
|
15463
|
+
/**
|
|
15464
|
+
* Find the n-th intersection point of two pathes, usually given by polygons. Uses parts of the
|
|
15465
|
+
* Greiner-Hormann algorithm in JXG.Math.Clip.
|
|
15466
|
+
*
|
|
15467
|
+
* @param {JXG.Circle|JXG.Curve|JXG.Polygon} path1
|
|
15468
|
+
* @param {JXG.Circle|JXG.Curve|JXG.Polygon} path2
|
|
15469
|
+
* @param {Number} n
|
|
15470
|
+
* @param {JXG.Board} board
|
|
15471
|
+
*
|
|
15472
|
+
* @returns {JXG.Coords} Intersection point. In case no intersection point is detected,
|
|
15473
|
+
* the ideal point [0,0,0] is returned.
|
|
15474
|
+
*
|
|
15475
|
+
*/
|
|
15476
|
+
meetPathPath: function(path1, path2, nr, board) {
|
|
15477
|
+
var S, C, len, intersections;
|
|
15478
|
+
|
|
15479
|
+
S = JXG.Math.Clip._getPath(path1, board);
|
|
15480
|
+
len = S.length;
|
|
15481
|
+
if (len > 0 && this.distance(S[0].coords.usrCoords, S[len - 1].coords.usrCoords, 3) < Mat.eps) {
|
|
15482
|
+
S.pop();
|
|
15483
|
+
}
|
|
15484
|
+
|
|
15485
|
+
C = JXG.Math.Clip._getPath(path2, board);
|
|
15486
|
+
len = C.length;
|
|
15487
|
+
if (len > 0 && this.distance(C[0].coords.usrCoords, C[len - 1].coords.usrCoords, 3) < Mat.eps * Mat.eps) {
|
|
15488
|
+
C.pop();
|
|
15489
|
+
}
|
|
15490
|
+
|
|
15491
|
+
// Handle cases where at least one of the paths is empty
|
|
15492
|
+
if (nr < 0 || JXG.Math.Clip.isEmptyCase(S, C, 'intersection')) {
|
|
15493
|
+
return (new Coords(Const.COORDS_BY_USER, [0, 0, 0], board));
|
|
15494
|
+
}
|
|
15495
|
+
|
|
15496
|
+
JXG.Math.Clip.makeDoublyLinkedList(S);
|
|
15497
|
+
JXG.Math.Clip.makeDoublyLinkedList(C);
|
|
15498
|
+
|
|
15499
|
+
intersections = JXG.Math.Clip.findIntersections(S, C, board)[0];
|
|
15500
|
+
if (nr < intersections.length) {
|
|
15501
|
+
return intersections[nr].coords;
|
|
15502
|
+
}
|
|
15503
|
+
return (new Coords(Const.COORDS_BY_USER, [0, 0, 0], board));
|
|
15504
|
+
},
|
|
15505
|
+
|
|
15506
|
+
/**
|
|
15507
|
+
* Find the n-th intersection point between a polygon and a line.
|
|
15508
|
+
* @param {JXG.Polygon} path
|
|
15509
|
+
* @param {JXG.Line} line
|
|
15510
|
+
* @param {Number} nr
|
|
15511
|
+
* @param {JXG.Board} board
|
|
15512
|
+
* @param {Boolean} alwaysIntersect If false just the segment between the two defining points of the line are tested for intersection.
|
|
15513
|
+
*
|
|
15514
|
+
* @returns {JXG.Coords} Intersection point. In case no intersection point is detected,
|
|
15515
|
+
* the ideal point [0,0,0] is returned.
|
|
15516
|
+
*/
|
|
15517
|
+
meetPolygonLine: function(path, line, nr, board, alwaysIntersect) {
|
|
15518
|
+
var i, res, border,
|
|
15519
|
+
crds = [0,0,0],
|
|
15520
|
+
len = path.borders.length,
|
|
15521
|
+
intersections = [];
|
|
15522
|
+
|
|
15523
|
+
for (i = 0; i < len; i++) {
|
|
15524
|
+
border = path.borders[i];
|
|
15525
|
+
res = this.meetSegmentSegment(
|
|
15526
|
+
border.point1.coords.usrCoords,
|
|
15527
|
+
border.point2.coords.usrCoords,
|
|
15528
|
+
line.point1.coords.usrCoords,
|
|
15529
|
+
line.point2.coords.usrCoords);
|
|
15530
|
+
|
|
15531
|
+
if (
|
|
15532
|
+
(!alwaysIntersect || (res[2] >= 0 && res[2] < 1)) &&
|
|
15533
|
+
res[1] >= 0 && res[1] < 1) {
|
|
15534
|
+
intersections.push(res[0]);
|
|
15535
|
+
}
|
|
15536
|
+
}
|
|
15537
|
+
|
|
15538
|
+
if (nr >= 0 && nr < intersections.length) {
|
|
15539
|
+
crds = intersections[nr];
|
|
15540
|
+
}
|
|
15541
|
+
return (new Coords(Const.COORDS_BY_USER, crds, board));
|
|
15542
|
+
},
|
|
15543
|
+
|
|
15397
15544
|
/****************************************/
|
|
15398
15545
|
/**** BEZIER CURVE ALGORITHMS ****/
|
|
15399
15546
|
/****************************************/
|
|
@@ -16334,7 +16481,86 @@ define('math/geometry',[
|
|
|
16334
16481
|
};
|
|
16335
16482
|
|
|
16336
16483
|
return [makeFct('X', 'cos'), makeFct('Y', 'sin'), 0, pi2];
|
|
16337
|
-
}
|
|
16484
|
+
},
|
|
16485
|
+
|
|
16486
|
+
|
|
16487
|
+
meet3Planes: function (n1, d1, n2, d2, n3, d3) {
|
|
16488
|
+
var p = [0, 0, 0],
|
|
16489
|
+
n31, n12, n23, denom,
|
|
16490
|
+
i;
|
|
16491
|
+
|
|
16492
|
+
n31 = Mat.crossProduct(n3, n1);
|
|
16493
|
+
n12 = Mat.crossProduct(n1, n2);
|
|
16494
|
+
n23 = Mat.crossProduct(n2, n3);
|
|
16495
|
+
denom = Mat.innerProduct(n1, n23, 3);
|
|
16496
|
+
for (i = 0; i < 3; i++) {
|
|
16497
|
+
p[i] = (d1 * n23[i] + d2 * n31[i] + d3 * n12[i]) / denom;
|
|
16498
|
+
}
|
|
16499
|
+
return p;
|
|
16500
|
+
},
|
|
16501
|
+
|
|
16502
|
+
|
|
16503
|
+
meetPlanePlane: function (v11, v12, v21, v22) {
|
|
16504
|
+
var i, no1, no2,
|
|
16505
|
+
v = [0, 0, 0],
|
|
16506
|
+
w = [0, 0, 0];
|
|
16507
|
+
|
|
16508
|
+
for (i = 0; i < 3; i++) {
|
|
16509
|
+
v[i] = Type.evaluate(v11[i]);
|
|
16510
|
+
w[i] = Type.evaluate(v12[i]);
|
|
16511
|
+
}
|
|
16512
|
+
no1 = Mat.crossProduct(v, w);
|
|
16513
|
+
|
|
16514
|
+
for (i = 0; i < 3; i++) {
|
|
16515
|
+
v[i] = Type.evaluate(v21[i]);
|
|
16516
|
+
w[i] = Type.evaluate(v22[i]);
|
|
16517
|
+
}
|
|
16518
|
+
no2 = Mat.crossProduct(v, w);
|
|
16519
|
+
|
|
16520
|
+
return Mat.crossProduct(no1, no2);
|
|
16521
|
+
},
|
|
16522
|
+
|
|
16523
|
+
project3DTo3DPlane: function (point, normal, foot) {
|
|
16524
|
+
// TODO: homogeneous 3D coordinates
|
|
16525
|
+
var sol = [0, 0, 0],
|
|
16526
|
+
le, d1, d2, lbda;
|
|
16527
|
+
|
|
16528
|
+
foot = foot || [0, 0, 0];
|
|
16529
|
+
|
|
16530
|
+
le = Mat.norm(normal);
|
|
16531
|
+
d1 = Mat.innerProduct(point, normal, 3);
|
|
16532
|
+
d2 = Mat.innerProduct(foot, normal, 3);
|
|
16533
|
+
// (point - lbda * normal / le) * normal / le == foot * normal / le
|
|
16534
|
+
// => (point * normal - foot * normal) == lbda * le
|
|
16535
|
+
lbda = (d1 - d2) / le;
|
|
16536
|
+
sol = Mat.axpy(-lbda, normal, point);
|
|
16537
|
+
|
|
16538
|
+
return sol;
|
|
16539
|
+
},
|
|
16540
|
+
|
|
16541
|
+
getPlaneBounds: function (v1, v2, q, s, e) {
|
|
16542
|
+
var s1, s2, e1, e2, mat, rhs, sol;
|
|
16543
|
+
|
|
16544
|
+
if (v1[2] + v2[0] !== 0) {
|
|
16545
|
+
mat = [
|
|
16546
|
+
[v1[0], v2[0]],
|
|
16547
|
+
[v1[1], v2[1]]
|
|
16548
|
+
];
|
|
16549
|
+
rhs = [s - q[0], s - q[1]];
|
|
16550
|
+
|
|
16551
|
+
sol = Numerics.Gauss(mat, rhs);
|
|
16552
|
+
s1 = sol[0];
|
|
16553
|
+
s2 = sol[1];
|
|
16554
|
+
|
|
16555
|
+
rhs = [e - q[0], e - q[1]];
|
|
16556
|
+
sol = Numerics.Gauss(mat, rhs);
|
|
16557
|
+
e1 = sol[0];
|
|
16558
|
+
e2 = sol[1];
|
|
16559
|
+
return [s1, e1, s2, e2];
|
|
16560
|
+
}
|
|
16561
|
+
return null;
|
|
16562
|
+
},
|
|
16563
|
+
|
|
16338
16564
|
});
|
|
16339
16565
|
|
|
16340
16566
|
return Mat.Geometry;
|
|
@@ -23140,7 +23366,6 @@ define('math/clip',[
|
|
|
23140
23366
|
|
|
23141
23367
|
// Collect all points into clip array C
|
|
23142
23368
|
C = this._getPath(clip, board);
|
|
23143
|
-
|
|
23144
23369
|
len = C.length;
|
|
23145
23370
|
if (len > 0 && Geometry.distance(C[0].coords.usrCoords, C[len - 1].coords.usrCoords, 3) < Mat.eps * Mat.eps) {
|
|
23146
23371
|
C.pop();
|
|
@@ -25837,6 +26062,10 @@ define('options',[
|
|
|
25837
26062
|
* visible: false // Initial visibility. Should be set to false always
|
|
25838
26063
|
* }
|
|
25839
26064
|
* </pre>
|
|
26065
|
+
* <p>
|
|
26066
|
+
* Board events triggered by selection manipulation:
|
|
26067
|
+
* 'startselecting', 'stopselecting', 'mousestartselecting', 'mousestopselecting',
|
|
26068
|
+
* 'pointerstartselecting', 'pointerstopselecting', 'touchstartselecting', 'touchstopselecting'.
|
|
25840
26069
|
*
|
|
25841
26070
|
* @example
|
|
25842
26071
|
* board.on('stopselecting', function(){
|
|
@@ -25850,14 +26079,10 @@ define('options',[
|
|
|
25850
26079
|
* });
|
|
25851
26080
|
*
|
|
25852
26081
|
* @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
|
|
26082
|
+
*
|
|
26083
|
+
* @see JXG.Board#startSelectionMode
|
|
26084
|
+
* @see JXG.Board#stopSelectionMode
|
|
26085
|
+
*
|
|
25861
26086
|
* @type Object
|
|
25862
26087
|
* @default
|
|
25863
26088
|
*/
|
|
@@ -26465,14 +26690,33 @@ define('options',[
|
|
|
26465
26690
|
* <p>
|
|
26466
26691
|
* In case the element is a polygon or line and it has the attribute "scalable:false",
|
|
26467
26692
|
* moving the element with two fingers results in a rotation or translation.
|
|
26693
|
+
* <p>
|
|
26694
|
+
* If an element is set to be neither scalable nor rotatable, it can only be translated.
|
|
26468
26695
|
*
|
|
26469
26696
|
* @type Boolean
|
|
26470
26697
|
* @default true
|
|
26471
26698
|
* @name JXG.GeometryElement#scalable
|
|
26472
26699
|
* @see JXG.Ticks#fixed
|
|
26700
|
+
* @see JXG.GeometryElement#rotatable
|
|
26473
26701
|
*/
|
|
26474
26702
|
scalable: true,
|
|
26475
26703
|
|
|
26704
|
+
/**
|
|
26705
|
+
* Determines whether two-finger manipulation may rotate this object.
|
|
26706
|
+
* If set to false, the object can only be scaled and translated.
|
|
26707
|
+
* <p>
|
|
26708
|
+
* In case the element is a polygon or line and it has the attribute "rotatable:false",
|
|
26709
|
+
* moving the element with two fingers results in a rotation or translation.
|
|
26710
|
+
* <p>
|
|
26711
|
+
* If an element is set to be neither scalable nor rotatable, it can only be translated.
|
|
26712
|
+
*
|
|
26713
|
+
* @type Boolean
|
|
26714
|
+
* @default true
|
|
26715
|
+
* @name JXG.GeometryElement#rotatable
|
|
26716
|
+
* @see JXG.GeometryElement#scalable
|
|
26717
|
+
*/
|
|
26718
|
+
rotatable: true,
|
|
26719
|
+
|
|
26476
26720
|
/**
|
|
26477
26721
|
* If the element is dragged it will be moved on mousedown or touchstart to the
|
|
26478
26722
|
* top of its layer. Works only for SVG renderer and for simple elements
|
|
@@ -26544,6 +26788,7 @@ define('options',[
|
|
|
26544
26788
|
|
|
26545
26789
|
/**
|
|
26546
26790
|
* Controls if an element can get the focus with the tab key.
|
|
26791
|
+
* tabindex corresponds to the HTML attribute of the same name.
|
|
26547
26792
|
* See <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex">descriptiona at MDN</a>.
|
|
26548
26793
|
* The additional value null completely disables focus of an element.
|
|
26549
26794
|
* The value will be ignored if keyboard control of the board is not enabled or
|
|
@@ -26573,6 +26818,8 @@ define('options',[
|
|
|
26573
26818
|
/**
|
|
26574
26819
|
* A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the
|
|
26575
26820
|
* tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).
|
|
26821
|
+
* The tird parameter is a null, number or a string. In the latter two cases, this value is taken.
|
|
26822
|
+
* Returns a string.
|
|
26576
26823
|
*
|
|
26577
26824
|
* @type function
|
|
26578
26825
|
* @name Ticks#generateLabelText
|
|
@@ -26583,7 +26830,7 @@ define('options',[
|
|
|
26583
26830
|
* A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the
|
|
26584
26831
|
* tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).
|
|
26585
26832
|
*
|
|
26586
|
-
* @deprecated Use {@link JGX.Options@
|
|
26833
|
+
* @deprecated Use {@link JGX.Options@generateLabelText}
|
|
26587
26834
|
* @type function
|
|
26588
26835
|
* @name Ticks#generateLabelValue
|
|
26589
26836
|
*/
|
|
@@ -28559,7 +28806,6 @@ define('options',[
|
|
|
28559
28806
|
*/
|
|
28560
28807
|
lastArrow: false,
|
|
28561
28808
|
|
|
28562
|
-
|
|
28563
28809
|
/**
|
|
28564
28810
|
* This number (pixel value) controls where infinite lines end at the canvas border. If zero, the line
|
|
28565
28811
|
* ends exactly at the border, if negative there is a margin to the inside, if positive the line
|
|
@@ -28736,7 +28982,6 @@ define('options',[
|
|
|
28736
28982
|
*/
|
|
28737
28983
|
lineCap: 'butt'
|
|
28738
28984
|
|
|
28739
|
-
|
|
28740
28985
|
/**#@-*/
|
|
28741
28986
|
},
|
|
28742
28987
|
|
|
@@ -30677,8 +30922,10 @@ define('options',[
|
|
|
30677
30922
|
display: 'html',
|
|
30678
30923
|
|
|
30679
30924
|
/**
|
|
30680
|
-
* Anchor element {@link Point}, {@link Text} or {@link Image} of the text.
|
|
30681
|
-
*
|
|
30925
|
+
* Anchor element {@link Point}, {@link Text} or {@link Image} of the text.
|
|
30926
|
+
* If it exists, the coordinates of the text are relative
|
|
30927
|
+
* to this anchor element. In this case, only numbers are possible coordinates,
|
|
30928
|
+
* functions are not supported.
|
|
30682
30929
|
*
|
|
30683
30930
|
* @name anchor
|
|
30684
30931
|
* @memberOf Text.prototype
|
|
@@ -35099,26 +35346,35 @@ define('base/element',[
|
|
|
35099
35346
|
},
|
|
35100
35347
|
|
|
35101
35348
|
/**
|
|
35102
|
-
* Resolves
|
|
35103
|
-
* Writes the expanded
|
|
35104
|
-
* @param {Object}
|
|
35105
|
-
* @returns {Object} The given
|
|
35349
|
+
* Resolves attribute shortcuts like <tt>color</tt> and expands them, e.g. <tt>strokeColor</tt> and <tt>fillColor</tt>.
|
|
35350
|
+
* Writes the expanded attributes back to the given <tt>attributes</tt>.
|
|
35351
|
+
* @param {Object} attributes object
|
|
35352
|
+
* @returns {Object} The given attributes object with shortcuts expanded.
|
|
35353
|
+
* @private
|
|
35106
35354
|
*/
|
|
35107
|
-
resolveShortcuts: function (
|
|
35108
|
-
var key, i
|
|
35355
|
+
resolveShortcuts: function (attributes) {
|
|
35356
|
+
var key, i,
|
|
35357
|
+
j,
|
|
35358
|
+
subattr = ['traceattributes', 'traceAttributes'];
|
|
35109
35359
|
|
|
35110
35360
|
for (key in Options.shortcuts) {
|
|
35111
35361
|
if (Options.shortcuts.hasOwnProperty(key)) {
|
|
35112
|
-
|
|
35113
|
-
|
|
35114
|
-
|
|
35115
|
-
|
|
35362
|
+
|
|
35363
|
+
if (Type.exists(attributes[key])) {
|
|
35364
|
+
for (i = 0; i < Options.shortcuts[key].length; i++) {
|
|
35365
|
+
if (!Type.exists(attributes[Options.shortcuts[key][i]])) {
|
|
35366
|
+
attributes[Options.shortcuts[key][i]] = attributes[key];
|
|
35367
|
+
}
|
|
35368
|
+
}
|
|
35369
|
+
}
|
|
35370
|
+
for (j = 0; j < subattr.length; j++) {
|
|
35371
|
+
if (Type.isObject(attributes[subattr[j]])) {
|
|
35372
|
+
attributes[subattr[j]] = this.resolveShortcuts(attributes[subattr[j]]);
|
|
35373
|
+
}
|
|
35116
35374
|
}
|
|
35117
35375
|
}
|
|
35118
|
-
}
|
|
35119
|
-
}
|
|
35120
35376
|
}
|
|
35121
|
-
return
|
|
35377
|
+
return attributes;
|
|
35122
35378
|
},
|
|
35123
35379
|
|
|
35124
35380
|
/**
|
|
@@ -36546,8 +36802,6 @@ define('base/coordselement',[
|
|
|
36546
36802
|
* @private
|
|
36547
36803
|
*/
|
|
36548
36804
|
updateCoords: function (fromParent) {
|
|
36549
|
-
var i;
|
|
36550
|
-
|
|
36551
36805
|
if (!this.needsUpdate) {
|
|
36552
36806
|
return this;
|
|
36553
36807
|
}
|
|
@@ -36674,7 +36928,6 @@ define('base/coordselement',[
|
|
|
36674
36928
|
doRound = true;
|
|
36675
36929
|
newPos = 0.0;
|
|
36676
36930
|
} else {
|
|
36677
|
-
//this.coords.setCoordinates(Const.COORDS_BY_USER, Geometry.projectPointToLine(this, slide, this.board).usrCoords, false);
|
|
36678
36931
|
newCoords = Geometry.projectPointToLine(this, slide, this.board);
|
|
36679
36932
|
p1c = p1c.usrCoords.slice(0);
|
|
36680
36933
|
p2c = p2c.usrCoords.slice(0);
|
|
@@ -38181,7 +38434,7 @@ define('base/coordselement',[
|
|
|
38181
38434
|
if (direction < 0) {
|
|
38182
38435
|
alpha *= this.intervalCount / stepCount;
|
|
38183
38436
|
} else {
|
|
38184
|
-
alpha *= (stepCount - this.intervalCount);
|
|
38437
|
+
alpha *= (stepCount - this.intervalCount) / stepCount;
|
|
38185
38438
|
}
|
|
38186
38439
|
radius = this.slideObject.Radius();
|
|
38187
38440
|
|
|
@@ -38486,6 +38739,7 @@ define('base/text',[
|
|
|
38486
38739
|
|
|
38487
38740
|
this.orgText = text;
|
|
38488
38741
|
if (Type.isFunction(text)) {
|
|
38742
|
+
// <value> tags will not be evaluated.
|
|
38489
38743
|
this.updateText = function () {
|
|
38490
38744
|
resolvedText = text().toString();
|
|
38491
38745
|
if (ev_p && !ev_um && !ev_uk) {
|
|
@@ -38506,14 +38760,20 @@ define('base/text',[
|
|
|
38506
38760
|
// Convert via ASCIIMathML
|
|
38507
38761
|
this.content = "'`" + text + "`'";
|
|
38508
38762
|
} else if (ev_um || ev_uk) {
|
|
38509
|
-
|
|
38763
|
+
if (ev_p) {
|
|
38764
|
+
this.content = this.generateTerm(text, true, true, true); // Replace value-tags
|
|
38765
|
+
this.content = this.content.replace(/\\/g, "\\\\");
|
|
38766
|
+
} else {
|
|
38767
|
+
this.content = "'" + text + "'";
|
|
38768
|
+
}
|
|
38510
38769
|
} else {
|
|
38511
38770
|
// Converts GEONExT syntax into JavaScript string
|
|
38512
38771
|
// Short math is allowed
|
|
38513
38772
|
// Avoid geonext2JS calls
|
|
38514
|
-
this.content = this.generateTerm(text, true, true);
|
|
38773
|
+
this.content = this.generateTerm(text, true, true, false);
|
|
38515
38774
|
}
|
|
38516
38775
|
}
|
|
38776
|
+
// Convert JessieCode to JS function
|
|
38517
38777
|
updateText = this.board.jc.snippet(this.content, true, '', false);
|
|
38518
38778
|
this.updateText = function () {
|
|
38519
38779
|
this.plaintext = updateText();
|
|
@@ -38869,30 +39129,43 @@ define('base/text',[
|
|
|
38869
39129
|
/**
|
|
38870
39130
|
* Converts the GEONExT syntax of the <value> terms into JavaScript.
|
|
38871
39131
|
* Also, all Objects whose name appears in the term are searched and
|
|
38872
|
-
* the text is added as child to these objects.
|
|
39132
|
+
* the text is added as child to these objects.
|
|
39133
|
+
* This method is called if the attribute parse==true is set.
|
|
38873
39134
|
*
|
|
38874
39135
|
* @param{String} contentStr String to be parsed
|
|
38875
39136
|
* @param{Boolean} [expand] Optional flag if shortened math syntax is allowed (e.g. 3x instead of 3*x).
|
|
38876
39137
|
* @param{Boolean} [avoidGeonext2JS] Optional flag if geonext2JS should be called. For backwards compatibility
|
|
38877
39138
|
* this has to be set explicitely to true.
|
|
39139
|
+
* @param{Boolean} [outputTeX] Optional flag which has to be true if the resulting term will be sent to MathJax or KaTeX.
|
|
39140
|
+
* If true, "_" and "^" are NOT replaced by HTML tags sub and sup. Default: false, i.e. the replacement is done.
|
|
39141
|
+
* This flag allows the combination of <value> tag containing calculations with TeX output.
|
|
39142
|
+
*
|
|
38878
39143
|
* @private
|
|
38879
39144
|
* @see JXG.GeonextParser.geonext2JS
|
|
38880
39145
|
*/
|
|
38881
|
-
generateTerm: function (contentStr, expand, avoidGeonext2JS) {
|
|
39146
|
+
generateTerm: function (contentStr, expand, avoidGeonext2JS, outputTeX) {
|
|
38882
39147
|
var res, term, i, j,
|
|
38883
39148
|
plaintext = '""';
|
|
38884
39149
|
|
|
38885
|
-
|
|
39150
|
+
outputTeX = outputTeX || false;
|
|
39151
|
+
|
|
39152
|
+
// Revert possible jc replacement
|
|
38886
39153
|
contentStr = contentStr || '';
|
|
38887
39154
|
contentStr = contentStr.replace(/\r/g, '');
|
|
38888
39155
|
contentStr = contentStr.replace(/\n/g, '');
|
|
38889
39156
|
contentStr = contentStr.replace(/"/g, '\'');
|
|
38890
39157
|
contentStr = contentStr.replace(/'/g, "\\'");
|
|
38891
39158
|
|
|
38892
|
-
|
|
38893
|
-
|
|
38894
|
-
|
|
38895
|
-
|
|
39159
|
+
if (!outputTeX) {
|
|
39160
|
+
// Old GEONExT syntax, not (yet) supported as TeX output.
|
|
39161
|
+
// Otherwise, the else clause should be used.
|
|
39162
|
+
// That means, i.e. the <arc> tag and <sqrt> tag are not
|
|
39163
|
+
// converted into TeX syntax.
|
|
39164
|
+
contentStr = contentStr.replace(/&arc;/g, '∠');
|
|
39165
|
+
contentStr = contentStr.replace(/<arc\s*\/>/g, '∠');
|
|
39166
|
+
contentStr = contentStr.replace(/<arc\s*\/>/g, '∠');
|
|
39167
|
+
contentStr = contentStr.replace(/<sqrt\s*\/>/g, '√');
|
|
39168
|
+
}
|
|
38896
39169
|
|
|
38897
39170
|
contentStr = contentStr.replace(/<value>/g, '<value>');
|
|
38898
39171
|
contentStr = contentStr.replace(/<\/value>/g, '</value>');
|
|
@@ -38902,7 +39175,12 @@ define('base/text',[
|
|
|
38902
39175
|
j = contentStr.indexOf('</value>');
|
|
38903
39176
|
if (i >= 0) {
|
|
38904
39177
|
while (i >= 0) {
|
|
38905
|
-
|
|
39178
|
+
if (!outputTeX) {
|
|
39179
|
+
plaintext += ' + "' + this.replaceSub(this.replaceSup(contentStr.slice(0, i))) + '"';
|
|
39180
|
+
// plaintext += ' + "' + this.replaceSub(contentStr.slice(0, i)) + '"';
|
|
39181
|
+
} else {
|
|
39182
|
+
plaintext += ' + "' + contentStr.slice(0, i) + '"';
|
|
39183
|
+
}
|
|
38906
39184
|
term = contentStr.slice(i + 7, j);
|
|
38907
39185
|
term = term.replace(/\s+/g, ''); // Remove all whitespace
|
|
38908
39186
|
if (expand === true) {
|
|
@@ -38935,10 +39213,14 @@ define('base/text',[
|
|
|
38935
39213
|
}
|
|
38936
39214
|
}
|
|
38937
39215
|
|
|
38938
|
-
|
|
38939
|
-
|
|
39216
|
+
if (!outputTeX) {
|
|
39217
|
+
plaintext += ' + "' + this.replaceSub(this.replaceSup(contentStr)) + '"';
|
|
39218
|
+
plaintext = this.convertGeonextAndSketchometry2CSS(plaintext);
|
|
39219
|
+
} else {
|
|
39220
|
+
plaintext += ' + "' + contentStr + '"';
|
|
39221
|
+
}
|
|
38940
39222
|
|
|
38941
|
-
// This should replace &pi; by π
|
|
39223
|
+
// This should replace e.g. &pi; by π
|
|
38942
39224
|
plaintext = plaintext.replace(/&/g, '&');
|
|
38943
39225
|
plaintext = plaintext.replace(/"/g, "'");
|
|
38944
39226
|
|
|
@@ -41095,7 +41377,7 @@ define('parser/jessiecode',[
|
|
|
41095
41377
|
case 'node_str':
|
|
41096
41378
|
//ret = node.value.replace(/\\'/, "'").replace(/\\"/, '"').replace(/\\\\/, '\\');
|
|
41097
41379
|
/*jslint regexp:true*/
|
|
41098
|
-
ret = node.value.replace(/\\(.)
|
|
41380
|
+
ret = node.value.replace(/\\(.)/g, '$1'); // Remove backslash, important in JessieCode tags
|
|
41099
41381
|
/*jslint regexp:false*/
|
|
41100
41382
|
break;
|
|
41101
41383
|
}
|
|
@@ -44161,8 +44443,12 @@ define('base/board',[
|
|
|
44161
44443
|
*/
|
|
44162
44444
|
getCoordsTopLeftCorner: function () {
|
|
44163
44445
|
var cPos, doc, crect,
|
|
44164
|
-
|
|
44165
|
-
|
|
44446
|
+
// In ownerDoc we need the "real" document object.
|
|
44447
|
+
// The first version is used in the case of shadowDom,
|
|
44448
|
+
// the second case in the "normal" case.
|
|
44449
|
+
ownerDoc = this.document.ownerDocument || this.document,
|
|
44450
|
+
docElement = ownerDoc.documentElement || this.document.body.parentNode,
|
|
44451
|
+
docBody = ownerDoc.body,
|
|
44166
44452
|
container = this.containerObj,
|
|
44167
44453
|
// viewport, content,
|
|
44168
44454
|
zoom, o;
|
|
@@ -44537,7 +44823,8 @@ define('base/board',[
|
|
|
44537
44823
|
*/
|
|
44538
44824
|
twoFingerTouchObject: function (tar, drag, id) {
|
|
44539
44825
|
var np, op, nd, od,
|
|
44540
|
-
d,
|
|
44826
|
+
d,
|
|
44827
|
+
alpha = 0,
|
|
44541
44828
|
S, t1, t3, t4, t5,
|
|
44542
44829
|
ar, i, len,
|
|
44543
44830
|
fixEl, moveEl, fix;
|
|
@@ -44571,7 +44858,9 @@ define('base/board',[
|
|
|
44571
44858
|
return;
|
|
44572
44859
|
}
|
|
44573
44860
|
|
|
44574
|
-
|
|
44861
|
+
if (Type.evaluate(drag.visProp.rotatable)) {
|
|
44862
|
+
alpha = Geometry.rad(op.slice(1), fix.slice(1), np.slice(1));
|
|
44863
|
+
}
|
|
44575
44864
|
|
|
44576
44865
|
t1 = this.create('transform', [alpha, [fix[1], fix[2]]], {type: 'rotate'});
|
|
44577
44866
|
t1.update();
|
|
@@ -45742,7 +46031,8 @@ define('base/board',[
|
|
|
45742
46031
|
* @returns {Boolean}
|
|
45743
46032
|
*/
|
|
45744
46033
|
pointerUpListener: function (evt) {
|
|
45745
|
-
var i, j, found, touchTargets
|
|
46034
|
+
var i, j, found, touchTargets,
|
|
46035
|
+
updateNeeded = false;
|
|
45746
46036
|
|
|
45747
46037
|
this.triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
|
|
45748
46038
|
this.displayInfobox(false);
|
|
@@ -45762,10 +46052,14 @@ define('base/board',[
|
|
|
45762
46052
|
}
|
|
45763
46053
|
}
|
|
45764
46054
|
|
|
46055
|
+
this.originMoveEnd();
|
|
46056
|
+
this.update();
|
|
46057
|
+
|
|
45765
46058
|
// selection
|
|
45766
46059
|
if (this.selectingMode) {
|
|
45767
46060
|
this._stopSelecting(evt);
|
|
45768
46061
|
this.triggerEventHandlers(['touchstopselecting', 'pointerstopselecting', 'stopselecting'], [evt]);
|
|
46062
|
+
this.stopSelectionMode();
|
|
45769
46063
|
} else {
|
|
45770
46064
|
for (i = this.downObjects.length - 1; i > -1; i--) {
|
|
45771
46065
|
found = false;
|
|
@@ -45776,32 +46070,38 @@ define('base/board',[
|
|
|
45776
46070
|
}
|
|
45777
46071
|
if (!found) {
|
|
45778
46072
|
this.downObjects[i].triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
|
|
45779
|
-
this.downObjects[i].
|
|
45780
|
-
|
|
46073
|
+
if (!Type.exists(this.downObjects[i].coords)) {
|
|
46074
|
+
// snapTo methods have to be called e.g. for line elements here.
|
|
46075
|
+
// For coordsElements there might be a conflict with
|
|
46076
|
+
// attractors, see commit from 2022.04.08, 11:12:18.
|
|
46077
|
+
this.downObjects[i].snapToGrid();
|
|
46078
|
+
this.downObjects[i].snapToPoints();
|
|
46079
|
+
updateNeeded = true;
|
|
46080
|
+
}
|
|
45781
46081
|
this.downObjects.splice(i, 1);
|
|
45782
46082
|
}
|
|
45783
46083
|
}
|
|
45784
46084
|
}
|
|
45785
46085
|
|
|
45786
|
-
|
|
45787
|
-
|
|
45788
|
-
|
|
45789
|
-
|
|
45790
|
-
|
|
45791
|
-
|
|
45792
|
-
Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
|
|
45793
|
-
Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
|
|
45794
|
-
}
|
|
45795
|
-
this.hasPointerUp = false;
|
|
46086
|
+
if (this.hasPointerUp) {
|
|
46087
|
+
if (window.navigator.msPointerEnabled) { // IE10-
|
|
46088
|
+
Env.removeEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);
|
|
46089
|
+
} else {
|
|
46090
|
+
Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
|
|
46091
|
+
Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
|
|
45796
46092
|
}
|
|
46093
|
+
this.hasPointerUp = false;
|
|
46094
|
+
}
|
|
45797
46095
|
|
|
45798
|
-
|
|
45799
|
-
|
|
45800
|
-
|
|
46096
|
+
// this.dehighlightAll();
|
|
46097
|
+
// this.updateQuality = this.BOARD_QUALITY_HIGH;
|
|
46098
|
+
// this.mode = this.BOARD_MODE_NONE;
|
|
45801
46099
|
|
|
45802
|
-
|
|
46100
|
+
// this.originMoveEnd();
|
|
46101
|
+
if (updateNeeded) {
|
|
45803
46102
|
this.update();
|
|
45804
|
-
|
|
46103
|
+
}
|
|
46104
|
+
|
|
45805
46105
|
// After one finger leaves the screen the gesture is stopped.
|
|
45806
46106
|
this._pointerClearTouches();
|
|
45807
46107
|
return true;
|
|
@@ -46135,7 +46435,8 @@ define('base/board',[
|
|
|
46135
46435
|
eps = this.options.precision.touch,
|
|
46136
46436
|
tmpTouches = [], found, foundNumber,
|
|
46137
46437
|
evtTouches = evt && evt[JXG.touchProperty],
|
|
46138
|
-
touchTargets
|
|
46438
|
+
touchTargets,
|
|
46439
|
+
updateNeeded = false;
|
|
46139
46440
|
|
|
46140
46441
|
this.triggerEventHandlers(['touchend', 'up'], [evt]);
|
|
46141
46442
|
this.displayInfobox(false);
|
|
@@ -46144,6 +46445,7 @@ define('base/board',[
|
|
|
46144
46445
|
if (this.selectingMode) {
|
|
46145
46446
|
this._stopSelecting(evt);
|
|
46146
46447
|
this.triggerEventHandlers(['touchstopselecting', 'stopselecting'], [evt]);
|
|
46448
|
+
this.stopSelectionMode();
|
|
46147
46449
|
} else if (evtTouches && evtTouches.length > 0) {
|
|
46148
46450
|
for (i = 0; i < this.touches.length; i++) {
|
|
46149
46451
|
tmpTouches[i] = this.touches[i];
|
|
@@ -46235,8 +46537,14 @@ define('base/board',[
|
|
|
46235
46537
|
}
|
|
46236
46538
|
if (!found) {
|
|
46237
46539
|
this.downObjects[i].triggerEventHandlers(['touchup', 'up'], [evt]);
|
|
46238
|
-
this.downObjects[i].
|
|
46239
|
-
|
|
46540
|
+
if (!Type.exists(this.downObjects[i].coords)) {
|
|
46541
|
+
// snapTo methods have to be called e.g. for line elements here.
|
|
46542
|
+
// For coordsElements there might be a conflict with
|
|
46543
|
+
// attractors, see commit from 2022.04.08, 11:12:18.
|
|
46544
|
+
this.downObjects[i].snapToGrid();
|
|
46545
|
+
this.downObjects[i].snapToPoints();
|
|
46546
|
+
updateNeeded = true;
|
|
46547
|
+
}
|
|
46240
46548
|
this.downObjects.splice(i, 1);
|
|
46241
46549
|
}
|
|
46242
46550
|
}
|
|
@@ -46252,7 +46560,9 @@ define('base/board',[
|
|
|
46252
46560
|
this.updateQuality = this.BOARD_QUALITY_HIGH;
|
|
46253
46561
|
|
|
46254
46562
|
this.originMoveEnd();
|
|
46255
|
-
|
|
46563
|
+
if (updateNeeded) {
|
|
46564
|
+
this.update();
|
|
46565
|
+
}
|
|
46256
46566
|
}
|
|
46257
46567
|
|
|
46258
46568
|
return true;
|
|
@@ -46400,9 +46710,14 @@ define('base/board',[
|
|
|
46400
46710
|
this.updateQuality = this.BOARD_QUALITY_HIGH;
|
|
46401
46711
|
|
|
46402
46712
|
if (this.mouse && this.mouse.obj) {
|
|
46403
|
-
|
|
46404
|
-
|
|
46405
|
-
|
|
46713
|
+
if (!Type.exists(this.mouse.obj.coords)) {
|
|
46714
|
+
// snapTo methods have to be called e.g. for line elements here.
|
|
46715
|
+
// For coordsElements there might be a conflict with
|
|
46716
|
+
// attractors, see commit from 2022.04.08, 11:12:18.
|
|
46717
|
+
// The parameter is needed for lines with snapToGrid enabled
|
|
46718
|
+
this.mouse.obj.snapToGrid(this.mouse.targets[0]);
|
|
46719
|
+
this.mouse.obj.snapToPoints();
|
|
46720
|
+
}
|
|
46406
46721
|
}
|
|
46407
46722
|
|
|
46408
46723
|
this.originMoveEnd();
|
|
@@ -46413,6 +46728,7 @@ define('base/board',[
|
|
|
46413
46728
|
if (this.selectingMode) {
|
|
46414
46729
|
this._stopSelecting(evt);
|
|
46415
46730
|
this.triggerEventHandlers(['mousestopselecting', 'stopselecting'], [evt]);
|
|
46731
|
+
this.stopSelectionMode();
|
|
46416
46732
|
} else {
|
|
46417
46733
|
for (i = 0; i < this.downObjects.length; i++) {
|
|
46418
46734
|
this.downObjects[i].triggerEventHandlers(['mouseup', 'up'], [evt]);
|
|
@@ -46458,11 +46774,18 @@ define('base/board',[
|
|
|
46458
46774
|
},
|
|
46459
46775
|
|
|
46460
46776
|
/**
|
|
46461
|
-
* Allow moving of JSXGraph elements with arrow keys
|
|
46462
|
-
*
|
|
46777
|
+
* Allow moving of JSXGraph elements with arrow keys.
|
|
46778
|
+
* The selection of the element is done with the tab key. For this,
|
|
46779
|
+
* the attribute "tabindex" of the element has to be set to some number (default=0).
|
|
46780
|
+
* tabindex corresponds to the HTML attribute of the same name.
|
|
46781
|
+
* <p>
|
|
46463
46782
|
* Panning of the construction is done with arrow keys
|
|
46464
|
-
* if the pan key (shift or ctrl) is pressed.
|
|
46465
|
-
*
|
|
46783
|
+
* if the pan key (shift or ctrl - depending on the board attributes) is pressed.
|
|
46784
|
+
* <p>
|
|
46785
|
+
* Zooming is triggered with the keys +, o, -, if
|
|
46786
|
+
* the pan key (shift or ctrl - depending on the board attributes) is pressed.
|
|
46787
|
+
* <p>
|
|
46788
|
+
* Keyboard control (move, pan, and zoom) is disabled if an HTML element of type input or textarea has received focus.
|
|
46466
46789
|
*
|
|
46467
46790
|
* @param {Event} evt The browser's event object
|
|
46468
46791
|
*
|
|
@@ -46473,7 +46796,7 @@ define('base/board',[
|
|
|
46473
46796
|
*/
|
|
46474
46797
|
keyDownListener: function (evt) {
|
|
46475
46798
|
var id_node = evt.target.id,
|
|
46476
|
-
id, el, res,
|
|
46799
|
+
id, el, res, doc,
|
|
46477
46800
|
sX = 0,
|
|
46478
46801
|
sY = 0,
|
|
46479
46802
|
// dx, dy are provided in screen units and
|
|
@@ -46488,6 +46811,15 @@ define('base/board',[
|
|
|
46488
46811
|
return false;
|
|
46489
46812
|
}
|
|
46490
46813
|
|
|
46814
|
+
// An element of type input or textarea has foxus, get out of here.
|
|
46815
|
+
doc = this.containerObj.shadowRoot || document;
|
|
46816
|
+
if (doc.activeElement) {
|
|
46817
|
+
el = doc.activeElement;
|
|
46818
|
+
if (el.tagName === 'INPUT' || el.tagName === 'textarea') {
|
|
46819
|
+
return false;
|
|
46820
|
+
}
|
|
46821
|
+
}
|
|
46822
|
+
|
|
46491
46823
|
// Get the JSXGraph id from the id of the SVG node.
|
|
46492
46824
|
id = id_node.replace(this.containerObj.id + '_', '');
|
|
46493
46825
|
el = this.select(id);
|
|
@@ -46496,12 +46828,15 @@ define('base/board',[
|
|
|
46496
46828
|
actPos = el.coords.usrCoords.slice(1);
|
|
46497
46829
|
}
|
|
46498
46830
|
|
|
46499
|
-
if (Type.evaluate(this.attr.keyboard.panshift) || Type.evaluate(this.attr.keyboard.panctrl)) {
|
|
46500
|
-
doZoom = true;
|
|
46501
|
-
}
|
|
46502
|
-
|
|
46503
46831
|
if ((Type.evaluate(this.attr.keyboard.panshift) && evt.shiftKey) ||
|
|
46504
46832
|
(Type.evaluate(this.attr.keyboard.panctrl) && evt.ctrlKey)) {
|
|
46833
|
+
// Pan key has been pressed
|
|
46834
|
+
|
|
46835
|
+
if (Type.evaluate(this.attr.zoom.enabled) === true) {
|
|
46836
|
+
doZoom = true;
|
|
46837
|
+
}
|
|
46838
|
+
|
|
46839
|
+
// Arrow keys
|
|
46505
46840
|
if (evt.keyCode === 38) { // up
|
|
46506
46841
|
this.clickUpArrow();
|
|
46507
46842
|
} else if (evt.keyCode === 40) { // down
|
|
@@ -46510,10 +46845,20 @@ define('base/board',[
|
|
|
46510
46845
|
this.clickLeftArrow();
|
|
46511
46846
|
} else if (evt.keyCode === 39) { // right
|
|
46512
46847
|
this.clickRightArrow();
|
|
46848
|
+
|
|
46849
|
+
// Zoom keys
|
|
46850
|
+
} else if (doZoom && evt.keyCode === 171) { // +
|
|
46851
|
+
this.zoomIn();
|
|
46852
|
+
} else if (doZoom && evt.keyCode === 173) { // -
|
|
46853
|
+
this.zoomOut();
|
|
46854
|
+
} else if (doZoom && evt.keyCode === 79) { // o
|
|
46855
|
+
this.zoom100();
|
|
46856
|
+
|
|
46513
46857
|
} else {
|
|
46514
46858
|
done = false;
|
|
46515
46859
|
}
|
|
46516
46860
|
} else {
|
|
46861
|
+
|
|
46517
46862
|
// Adapt dx, dy to snapToGrid and attractToGrid
|
|
46518
46863
|
// snapToGrid has priority.
|
|
46519
46864
|
if (Type.exists(el.visProp)) {
|
|
@@ -46556,14 +46901,6 @@ define('base/board',[
|
|
|
46556
46901
|
dir = [-dx, 0];
|
|
46557
46902
|
} else if (evt.keyCode === 39) { // right
|
|
46558
46903
|
dir = [dx, 0];
|
|
46559
|
-
// } else if (evt.keyCode === 9) { // tab
|
|
46560
|
-
|
|
46561
|
-
} else if (doZoom && evt.key === '+') { // +
|
|
46562
|
-
this.zoomIn();
|
|
46563
|
-
} else if (doZoom && evt.key === '-') { // -
|
|
46564
|
-
this.zoomOut();
|
|
46565
|
-
} else if (doZoom && evt.key === 'o') { // o
|
|
46566
|
-
this.zoom100();
|
|
46567
46904
|
} else {
|
|
46568
46905
|
done = false;
|
|
46569
46906
|
}
|
|
@@ -46593,15 +46930,16 @@ define('base/board',[
|
|
|
46593
46930
|
|
|
46594
46931
|
this.update();
|
|
46595
46932
|
|
|
46596
|
-
if (done) {
|
|
46933
|
+
if (done && Type.exists(evt.preventDefault)) {
|
|
46597
46934
|
evt.preventDefault();
|
|
46598
46935
|
}
|
|
46599
|
-
return
|
|
46936
|
+
return done;
|
|
46600
46937
|
},
|
|
46601
46938
|
|
|
46602
46939
|
/**
|
|
46603
46940
|
* Event listener for SVG elements getting focus.
|
|
46604
46941
|
* This is needed for highlighting when using keyboard control.
|
|
46942
|
+
* Only elements having the attribute "tabindex" can receive focus.
|
|
46605
46943
|
*
|
|
46606
46944
|
* @see JXG.Board#keyFocusOutListener
|
|
46607
46945
|
* @see JXG.Board#keyDownListener
|
|
@@ -46631,6 +46969,7 @@ define('base/board',[
|
|
|
46631
46969
|
/**
|
|
46632
46970
|
* Event listener for SVG elements losing focus.
|
|
46633
46971
|
* This is needed for dehighlighting when using keyboard control.
|
|
46972
|
+
* Only elements having the attribute "tabindex" can receive focus.
|
|
46634
46973
|
*
|
|
46635
46974
|
* @see JXG.Board#keyFocusInListener
|
|
46636
46975
|
* @see JXG.Board#keyDownListener
|
|
@@ -46681,8 +47020,8 @@ define('base/board',[
|
|
|
46681
47020
|
}
|
|
46682
47021
|
|
|
46683
47022
|
// If div is invisible - do nothing
|
|
46684
|
-
if (w <= 0 || h <= 0) {
|
|
46685
|
-
|
|
47023
|
+
if (w <= 0 || h <= 0 || isNaN(w) || isNaN(h)) {
|
|
47024
|
+
return;
|
|
46686
47025
|
}
|
|
46687
47026
|
|
|
46688
47027
|
// If bounding box is not yet initialized, do it now.
|
|
@@ -48087,12 +48426,12 @@ define('base/board',[
|
|
|
48087
48426
|
this.inUpdate = true;
|
|
48088
48427
|
|
|
48089
48428
|
if (this.attr.minimizereflow === 'all' && this.containerObj && this.renderer.type !== 'vml') {
|
|
48090
|
-
storeActiveEl = document.activeElement; // Store focus element
|
|
48429
|
+
storeActiveEl = this.document.activeElement; // Store focus element
|
|
48091
48430
|
insert = this.renderer.removeToInsertLater(this.containerObj);
|
|
48092
48431
|
}
|
|
48093
48432
|
|
|
48094
48433
|
if (this.attr.minimizereflow === 'svg' && this.renderer.type === 'svg') {
|
|
48095
|
-
storeActiveEl = document.activeElement;
|
|
48434
|
+
storeActiveEl = this.document.activeElement;
|
|
48096
48435
|
insert = this.renderer.removeToInsertLater(this.renderer.svgRoot);
|
|
48097
48436
|
}
|
|
48098
48437
|
|
|
@@ -48696,31 +49035,43 @@ define('base/board',[
|
|
|
48696
49035
|
*/
|
|
48697
49036
|
updateCSSTransforms: function () {
|
|
48698
49037
|
var obj = this.containerObj,
|
|
48699
|
-
o = obj
|
|
48700
|
-
o2 = obj;
|
|
49038
|
+
o = obj;
|
|
49039
|
+
// o2 = obj;
|
|
48701
49040
|
|
|
48702
49041
|
this.cssTransMat = Env.getCSSTransformMatrix(o);
|
|
48703
49042
|
|
|
49043
|
+
// Newer variant of walking up the tree.
|
|
49044
|
+
// We walk up all parent nodes and collect possible CSS transforms.
|
|
49045
|
+
// Works also for ShadowDOM
|
|
49046
|
+
o = o.parentNode === o.getRootNode() ? o.parentNode.host : o.parentNode;
|
|
49047
|
+
while (o) {
|
|
49048
|
+
this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
|
|
49049
|
+
o = o.parentNode === o.getRootNode() ? o.parentNode.host : o.parentNode;
|
|
49050
|
+
}
|
|
49051
|
+
this.cssTransMat = Mat.inverse(this.cssTransMat);
|
|
49052
|
+
|
|
48704
49053
|
/*
|
|
48705
49054
|
* In Mozilla and Webkit: offsetParent seems to jump at least to the next iframe,
|
|
48706
49055
|
* if not to the body. In IE and if we are in an position:absolute environment
|
|
48707
49056
|
* offsetParent walks up the DOM hierarchy.
|
|
48708
49057
|
* In order to walk up the DOM hierarchy also in Mozilla and Webkit
|
|
48709
49058
|
* we need the parentNode steps.
|
|
49059
|
+
*
|
|
49060
|
+
* Seems to be outdated
|
|
48710
49061
|
*/
|
|
48711
|
-
o = o.offsetParent;
|
|
48712
|
-
while (o) {
|
|
48713
|
-
|
|
48714
|
-
|
|
48715
|
-
|
|
48716
|
-
|
|
48717
|
-
|
|
48718
|
-
|
|
48719
|
-
|
|
49062
|
+
// o = o.offsetParent;
|
|
49063
|
+
// while (o) {
|
|
49064
|
+
// this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
|
|
49065
|
+
|
|
49066
|
+
// o2 = o2.parentNode;
|
|
49067
|
+
// while (o2 !== o) {
|
|
49068
|
+
// this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
|
|
49069
|
+
// o2 = o2.parentNode;
|
|
49070
|
+
// }
|
|
48720
49071
|
|
|
48721
|
-
|
|
48722
|
-
}
|
|
48723
|
-
this.cssTransMat = Mat.inverse(this.cssTransMat);
|
|
49072
|
+
// o = o.offsetParent;
|
|
49073
|
+
// }
|
|
49074
|
+
// this.cssTransMat = Mat.inverse(this.cssTransMat);
|
|
48724
49075
|
|
|
48725
49076
|
return this;
|
|
48726
49077
|
},
|
|
@@ -49281,16 +49632,17 @@ define('base/board',[
|
|
|
49281
49632
|
*
|
|
49282
49633
|
*/
|
|
49283
49634
|
toFullscreen: function (id) {
|
|
49284
|
-
var wrap_id, wrap_node, inner_node
|
|
49635
|
+
var wrap_id, wrap_node, inner_node,
|
|
49636
|
+
doc = this.document;
|
|
49285
49637
|
|
|
49286
49638
|
id = id || this.container;
|
|
49287
49639
|
this._fullscreen_inner_id = id;
|
|
49288
|
-
inner_node =
|
|
49640
|
+
inner_node = doc.getElementById(id);
|
|
49289
49641
|
wrap_id = 'fullscreenwrap_' + id;
|
|
49290
49642
|
|
|
49291
49643
|
// Wrap a div around the JSXGraph div.
|
|
49292
|
-
if (
|
|
49293
|
-
wrap_node =
|
|
49644
|
+
if (doc.getElementById(wrap_id)) {
|
|
49645
|
+
wrap_node = doc.getElementById(wrap_id);
|
|
49294
49646
|
} else {
|
|
49295
49647
|
wrap_node = document.createElement('div');
|
|
49296
49648
|
wrap_node.classList.add('JXG_wrap_private');
|
|
@@ -49309,8 +49661,14 @@ define('base/board',[
|
|
|
49309
49661
|
wrap_node.mozRequestFullScreen ||
|
|
49310
49662
|
wrap_node.msRequestFullscreen;
|
|
49311
49663
|
|
|
49312
|
-
if (
|
|
49313
|
-
|
|
49664
|
+
if (doc.fullscreenElement === null) {
|
|
49665
|
+
// Start fullscreen mode
|
|
49666
|
+
if (wrap_node.requestFullscreen) {
|
|
49667
|
+
wrap_node.requestFullscreen();
|
|
49668
|
+
}
|
|
49669
|
+
} else {
|
|
49670
|
+
// Leave fullscreen mode (e.g. when clicking on the icon)
|
|
49671
|
+
document.exitFullscreen();
|
|
49314
49672
|
}
|
|
49315
49673
|
|
|
49316
49674
|
return this;
|
|
@@ -49324,23 +49682,24 @@ define('base/board',[
|
|
|
49324
49682
|
* @param {Object} evt fullscreen event object (unused)
|
|
49325
49683
|
*/
|
|
49326
49684
|
fullscreenListener: function (evt) {
|
|
49327
|
-
var res, inner_id, inner_node
|
|
49685
|
+
var res, inner_id, inner_node,
|
|
49686
|
+
doc = this.document;
|
|
49328
49687
|
|
|
49329
49688
|
inner_id = this._fullscreen_inner_id;
|
|
49330
49689
|
if (!Type.exists(inner_id)) {
|
|
49331
49690
|
return;
|
|
49332
49691
|
}
|
|
49333
49692
|
|
|
49334
|
-
|
|
49335
|
-
|
|
49336
|
-
|
|
49337
|
-
|
|
49693
|
+
doc.fullscreenElement = doc.fullscreenElement ||
|
|
49694
|
+
doc.webkitFullscreenElement ||
|
|
49695
|
+
doc.mozFullscreenElement ||
|
|
49696
|
+
doc.msFullscreenElement;
|
|
49338
49697
|
|
|
49339
|
-
inner_node =
|
|
49698
|
+
inner_node = doc.getElementById(inner_id);
|
|
49340
49699
|
// If full screen mode is started we have to remove CSS margin around the JSXGraph div.
|
|
49341
49700
|
// Otherwise, the positioning of the fullscreen div will be false.
|
|
49342
49701
|
// When leaving the fullscreen mode, the margin is put back in.
|
|
49343
|
-
if (
|
|
49702
|
+
if (doc.fullscreenElement) {
|
|
49344
49703
|
// Just entered fullscreen mode
|
|
49345
49704
|
|
|
49346
49705
|
// Get the data computed in board.toFullscreen()
|
|
@@ -49352,7 +49711,7 @@ define('base/board',[
|
|
|
49352
49711
|
// Further, the CSS margin has to be removed when in fullscreen mode,
|
|
49353
49712
|
// and must be restored later.
|
|
49354
49713
|
inner_node._cssFullscreenStore = {
|
|
49355
|
-
id:
|
|
49714
|
+
id: doc.fullscreenElement.id,
|
|
49356
49715
|
isFullscreen: true,
|
|
49357
49716
|
margin: inner_node.style.margin,
|
|
49358
49717
|
width: inner_node.style.width,
|
|
@@ -49366,18 +49725,18 @@ define('base/board',[
|
|
|
49366
49725
|
// Do the shifting and scaling via CSS pseudo rules
|
|
49367
49726
|
// We do this after fullscreen mode has been established to get the correct size
|
|
49368
49727
|
// of the JSXGraph div.
|
|
49369
|
-
Env.scaleJSXGraphDiv(
|
|
49728
|
+
Env.scaleJSXGraphDiv(doc.fullscreenElement.id, inner_id, res.scale, res.vshift, doc);
|
|
49370
49729
|
|
|
49371
|
-
// Clear document.fullscreenElement, because Safari doesn't to it and
|
|
49730
|
+
// Clear this.document.fullscreenElement, because Safari doesn't to it and
|
|
49372
49731
|
// when leaving full screen mode it is still set.
|
|
49373
|
-
|
|
49732
|
+
doc.fullscreenElement = null;
|
|
49374
49733
|
|
|
49375
49734
|
} else if (Type.exists(inner_node._cssFullscreenStore)) {
|
|
49376
49735
|
// Just left the fullscreen mode
|
|
49377
49736
|
|
|
49378
49737
|
// Remove the CSS rules added in Env.scaleJSXGraphDiv
|
|
49379
49738
|
try {
|
|
49380
|
-
|
|
49739
|
+
doc.styleSheets[doc.styleSheets.length - 1].deleteRule(0);
|
|
49381
49740
|
} catch (err) {
|
|
49382
49741
|
console.log('JSXGraph: Could not remove CSS rules for full screen mode');
|
|
49383
49742
|
}
|
|
@@ -49385,7 +49744,6 @@ define('base/board',[
|
|
|
49385
49744
|
inner_node._cssFullscreenStore.isFullscreen = false;
|
|
49386
49745
|
inner_node.style.margin = inner_node._cssFullscreenStore.margin;
|
|
49387
49746
|
inner_node.style.width = inner_node._cssFullscreenStore.width;
|
|
49388
|
-
|
|
49389
49747
|
}
|
|
49390
49748
|
|
|
49391
49749
|
this.updateCSSTransforms();
|
|
@@ -51295,10 +51653,11 @@ define('renderer/svg',[
|
|
|
51295
51653
|
* setTimeout(function() { console.log('done'); }, 400);
|
|
51296
51654
|
*/
|
|
51297
51655
|
dumpToCanvas: function (canvasId, w, h, ignoreTexts) {
|
|
51298
|
-
var svg, tmpImg, cv, ctx
|
|
51656
|
+
var svg, tmpImg, cv, ctx,
|
|
51657
|
+
doc = this.container.ownerDocument;
|
|
51299
51658
|
|
|
51300
51659
|
// Prepare the canvas element
|
|
51301
|
-
cv =
|
|
51660
|
+
cv = doc.getElementById(canvasId);
|
|
51302
51661
|
|
|
51303
51662
|
// Clear the canvas
|
|
51304
51663
|
/* eslint-disable no-self-assign */
|
|
@@ -51434,7 +51793,8 @@ define('renderer/svg',[
|
|
|
51434
51793
|
} else {
|
|
51435
51794
|
// Debug: use canvas element 'jxgbox_canvas' from jsxdev/dump.html
|
|
51436
51795
|
id = 'jxgbox_canvas';
|
|
51437
|
-
canvas = document.getElementById(id);
|
|
51796
|
+
// canvas = document.getElementById(id);
|
|
51797
|
+
canvas = doc.getElementById(id);
|
|
51438
51798
|
}
|
|
51439
51799
|
|
|
51440
51800
|
if (newImg) {
|
|
@@ -51454,7 +51814,8 @@ define('renderer/svg',[
|
|
|
51454
51814
|
}
|
|
51455
51815
|
|
|
51456
51816
|
// Hide navigation bar in board
|
|
51457
|
-
zbar = document.getElementById(this.container.id + '_navigationbar');
|
|
51817
|
+
// zbar = document.getElementById(this.container.id + '_navigationbar');
|
|
51818
|
+
zbar = doc.getElementById(this.container.id + '_navigationbar');
|
|
51458
51819
|
if (Type.exists(zbar)) {
|
|
51459
51820
|
zbarDisplay = zbar.style.display;
|
|
51460
51821
|
zbar.style.display = 'none';
|
|
@@ -54990,6 +55351,7 @@ define('jsxgraph',[
|
|
|
54990
55351
|
*/
|
|
54991
55352
|
_setARIA: function(container, attr) {
|
|
54992
55353
|
var doc = attr.document || document,
|
|
55354
|
+
doc_glob,
|
|
54993
55355
|
node_jsx, newNode, parent,
|
|
54994
55356
|
id_label, id_description;
|
|
54995
55357
|
|
|
@@ -54998,18 +55360,19 @@ define('jsxgraph',[
|
|
|
54998
55360
|
}
|
|
54999
55361
|
|
|
55000
55362
|
node_jsx = doc.getElementById(container);
|
|
55363
|
+
doc_glob = node_jsx.ownerDocument; // This is the window.document element, needed below.
|
|
55001
55364
|
parent = node_jsx.parentNode;
|
|
55002
55365
|
|
|
55003
55366
|
id_label = container + '_ARIAlabel';
|
|
55004
55367
|
id_description = container + '_ARIAdescription';
|
|
55005
55368
|
|
|
55006
|
-
newNode =
|
|
55369
|
+
newNode = doc_glob.createElement('div');
|
|
55007
55370
|
newNode.innerHTML = attr.title;
|
|
55008
55371
|
newNode.setAttribute('id', id_label);
|
|
55009
55372
|
newNode.style.display = 'none';
|
|
55010
55373
|
parent.insertBefore(newNode, node_jsx);
|
|
55011
55374
|
|
|
55012
|
-
newNode =
|
|
55375
|
+
newNode = doc_glob.createElement('div');
|
|
55013
55376
|
newNode.innerHTML = attr.description;
|
|
55014
55377
|
newNode.setAttribute('id', id_description);
|
|
55015
55378
|
newNode.style.display = 'none';
|
|
@@ -55035,12 +55398,12 @@ define('jsxgraph',[
|
|
|
55035
55398
|
}
|
|
55036
55399
|
|
|
55037
55400
|
id = board.containerObj.getAttribute('aria-labelledby');
|
|
55038
|
-
node =
|
|
55401
|
+
node = doc.getElementById(id);
|
|
55039
55402
|
if (node && node.parentNode) {
|
|
55040
55403
|
node.parentNode.removeChild(node);
|
|
55041
55404
|
}
|
|
55042
55405
|
id = board.containerObj.getAttribute('aria-describedby');
|
|
55043
|
-
node =
|
|
55406
|
+
node = doc.getElementById(id);
|
|
55044
55407
|
if (node && node.parentNode) {
|
|
55045
55408
|
node.parentNode.removeChild(node);
|
|
55046
55409
|
}
|
|
@@ -55306,7 +55669,8 @@ define('jsxgraph',[
|
|
|
55306
55669
|
}
|
|
55307
55670
|
};
|
|
55308
55671
|
|
|
55309
|
-
// JessieScript/JessieCode startup:
|
|
55672
|
+
// JessieScript/JessieCode startup:
|
|
55673
|
+
// Search for script tags of type text/jessiescript and interprete them.
|
|
55310
55674
|
if (Env.isBrowser && typeof window === 'object' && typeof document === 'object') {
|
|
55311
55675
|
Env.addEvent(window, 'load', function () {
|
|
55312
55676
|
var type, i, j, div,
|
|
@@ -57018,7 +57382,7 @@ define('base/line',[
|
|
|
57018
57382
|
if (this.parents.length < 3) { // Line through two points
|
|
57019
57383
|
this.point1.handleSnapToGrid(true, true);
|
|
57020
57384
|
this.point2.handleSnapToGrid(true, true);
|
|
57021
|
-
|
|
57385
|
+
} else if (Type.exists(pos)) { // Free line
|
|
57022
57386
|
sX = Type.evaluate(this.visProp.snapsizex);
|
|
57023
57387
|
sY = Type.evaluate(this.visProp.snapsizey);
|
|
57024
57388
|
|
|
@@ -61697,8 +62061,35 @@ define('base/polygon',[
|
|
|
61697
62061
|
|
|
61698
62062
|
/**
|
|
61699
62063
|
* Add more points to the polygon. The new points will be inserted at the end.
|
|
61700
|
-
*
|
|
62064
|
+
* The attributes of new border segments are set to the same values
|
|
62065
|
+
* as those used when the polygon was created.
|
|
62066
|
+
* If new vertices are supplied by coordinates, the default attributes of polygon
|
|
62067
|
+
* vertices are taken as their attributes. Therefore, the visual attributes of
|
|
62068
|
+
* new vertices and borders may have to be adapted afterwards.
|
|
62069
|
+
* @param {JXG.Point} p Arbitrary number of points or coordinate arrays
|
|
61701
62070
|
* @returns {JXG.Polygon} Reference to the polygon
|
|
62071
|
+
* @example
|
|
62072
|
+
* const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
|
|
62073
|
+
* var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
|
|
62074
|
+
* var newPoint = board.create('point', [-1, -1]);
|
|
62075
|
+
* var newPoint2 = board.create('point', [-1, -2]);
|
|
62076
|
+
* pg.addPoints(newPoint, newPoint2, [1, -2]);
|
|
62077
|
+
*
|
|
62078
|
+
* </pre><div id="JXG70eb0fd2-d20f-4ba9-9ab6-0eac92aabfa5" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
62079
|
+
* <script type="text/javascript">
|
|
62080
|
+
* (function() {
|
|
62081
|
+
* var board = JXG.JSXGraph.initBoard('JXG70eb0fd2-d20f-4ba9-9ab6-0eac92aabfa5',
|
|
62082
|
+
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
62083
|
+
* const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
|
|
62084
|
+
* var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
|
|
62085
|
+
* var newPoint = board.create('point', [-1, -1]);
|
|
62086
|
+
* var newPoint2 = board.create('point', [-1, -2]);
|
|
62087
|
+
* pg.addPoints(newPoint, newPoint2, [1, -2]);
|
|
62088
|
+
*
|
|
62089
|
+
* })();
|
|
62090
|
+
*
|
|
62091
|
+
* </script><pre>
|
|
62092
|
+
*
|
|
61702
62093
|
*/
|
|
61703
62094
|
addPoints: function (p) {
|
|
61704
62095
|
var args = Array.prototype.slice.call(arguments);
|
|
@@ -61707,44 +62098,72 @@ define('base/polygon',[
|
|
|
61707
62098
|
},
|
|
61708
62099
|
|
|
61709
62100
|
/**
|
|
61710
|
-
*
|
|
61711
|
-
*
|
|
61712
|
-
*
|
|
62101
|
+
* Insert points to the vertex list of the polygon after index <tt><idx</tt>.
|
|
62102
|
+
* The attributes of new border segments are set to the same values
|
|
62103
|
+
* as those used when the polygon was created.
|
|
62104
|
+
* If new vertices are supplied by coordinates, the default attributes of polygon
|
|
62105
|
+
* vertices are taken as their attributes. Therefore, the visual attributes of
|
|
62106
|
+
* new vertices and borders may have to be adapted afterwards.
|
|
62107
|
+
*
|
|
62108
|
+
* @param {Number} idx The position after which the new vertices are inserted.
|
|
62109
|
+
* Setting idx to -1 inserts the new points at the front, i.e. at position 0.
|
|
62110
|
+
* @param {JXG.Point} p Arbitrary number of points or coordinate arrays to insert.
|
|
61713
62111
|
* @returns {JXG.Polygon} Reference to the polygon object
|
|
62112
|
+
*
|
|
62113
|
+
* @example
|
|
62114
|
+
* const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
|
|
62115
|
+
* var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
|
|
62116
|
+
* var newPoint = board.create('point', [-1, -1]);
|
|
62117
|
+
* pg.insertPoints(0, newPoint, newPoint, [1, -2]);
|
|
62118
|
+
*
|
|
62119
|
+
* </pre><div id="JXG17b84b2a-a851-4e3f-824f-7f6a60f166ca" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
62120
|
+
* <script type="text/javascript">
|
|
62121
|
+
* (function() {
|
|
62122
|
+
* var board = JXG.JSXGraph.initBoard('JXG17b84b2a-a851-4e3f-824f-7f6a60f166ca',
|
|
62123
|
+
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
62124
|
+
* const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
|
|
62125
|
+
* var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
|
|
62126
|
+
* var newPoint = board.create('point', [-1, -1]);
|
|
62127
|
+
* pg.insertPoints(0, newPoint, newPoint, [1, -2]);
|
|
62128
|
+
*
|
|
62129
|
+
* })();
|
|
62130
|
+
*
|
|
62131
|
+
* </script><pre>
|
|
62132
|
+
*
|
|
61714
62133
|
*/
|
|
61715
62134
|
insertPoints: function (idx, p) {
|
|
61716
|
-
var i,
|
|
62135
|
+
var i, le;
|
|
61717
62136
|
|
|
61718
62137
|
if (arguments.length === 0) {
|
|
61719
62138
|
return this;
|
|
61720
62139
|
}
|
|
61721
62140
|
|
|
61722
62141
|
|
|
61723
|
-
if (idx <
|
|
62142
|
+
if (idx < -1 || idx > this.vertices.length - 2) {
|
|
61724
62143
|
return this;
|
|
61725
62144
|
}
|
|
61726
62145
|
|
|
61727
|
-
|
|
61728
|
-
|
|
61729
|
-
|
|
61730
|
-
|
|
62146
|
+
le = arguments.length - 1;
|
|
62147
|
+
for (i = 1; i < le + 1; i++) {
|
|
62148
|
+
this.vertices.splice(idx + i, 0,
|
|
62149
|
+
Type.providePoints(this.board, [arguments[i]], {}, 'polygon', ['vertices'])[0]
|
|
62150
|
+
);
|
|
62151
|
+
}
|
|
62152
|
+
if (idx === -1) {
|
|
62153
|
+
this.vertices[this.vertices.length - 1] = this.vertices[0];
|
|
61731
62154
|
}
|
|
61732
|
-
|
|
61733
|
-
tmp = this.vertices.slice(0, idx + 1).concat(npoints);
|
|
61734
|
-
this.vertices = tmp.concat(this.vertices.slice(idx + 1));
|
|
61735
|
-
|
|
61736
62155
|
if (this.withLines) {
|
|
61737
|
-
|
|
61738
|
-
|
|
61739
|
-
|
|
61740
|
-
|
|
61741
|
-
|
|
62156
|
+
if (idx < 0) {
|
|
62157
|
+
this.borders[this.borders.length - 1].point2 = this.vertices[this.vertices.length - 1];
|
|
62158
|
+
} else {
|
|
62159
|
+
this.borders[idx].point2 = this.vertices[idx + 1];
|
|
62160
|
+
}
|
|
62161
|
+
for (i = idx + 1; i < idx + 1 + le; i++) {
|
|
62162
|
+
this.borders.splice(i, 0,
|
|
62163
|
+
this.board.create('segment', [this.vertices[i], this.vertices[i + 1]], this.attr_line)
|
|
62164
|
+
);
|
|
61742
62165
|
}
|
|
61743
|
-
|
|
61744
|
-
tmp.push(this.board.create('segment', [this.vertices[idx + npoints.length], this.vertices[idx + npoints.length + 1]], this.attr_line));
|
|
61745
|
-
this.borders = tmp.concat(this.borders.slice(idx + 1));
|
|
61746
62166
|
}
|
|
61747
|
-
|
|
61748
62167
|
this.board.update();
|
|
61749
62168
|
|
|
61750
62169
|
return this;
|
|
@@ -61759,7 +62178,7 @@ define('base/polygon',[
|
|
|
61759
62178
|
var i, j, idx, nvertices = [], nborders = [],
|
|
61760
62179
|
nidx = [], partition = [];
|
|
61761
62180
|
|
|
61762
|
-
//
|
|
62181
|
+
// Partition:
|
|
61763
62182
|
// in order to keep the borders which could be recycled, we have to partition
|
|
61764
62183
|
// the set of removed points. I.e. if the points 1, 2, 5, 6, 7, 10 are removed,
|
|
61765
62184
|
// the partitions are
|
|
@@ -61767,10 +62186,10 @@ define('base/polygon',[
|
|
|
61767
62186
|
// this gives us the borders, that can be removed and the borders we have to create.
|
|
61768
62187
|
|
|
61769
62188
|
|
|
61770
|
-
//
|
|
62189
|
+
// Remove the last vertex which is identical to the first
|
|
61771
62190
|
this.vertices = this.vertices.slice(0, this.vertices.length - 1);
|
|
61772
62191
|
|
|
61773
|
-
//
|
|
62192
|
+
// Collect all valid parameters as indices in nidx
|
|
61774
62193
|
for (i = 0; i < arguments.length; i++) {
|
|
61775
62194
|
idx = arguments[i];
|
|
61776
62195
|
if (Type.isPoint(idx)) {
|
|
@@ -61782,22 +62201,22 @@ define('base/polygon',[
|
|
|
61782
62201
|
}
|
|
61783
62202
|
}
|
|
61784
62203
|
|
|
61785
|
-
//
|
|
62204
|
+
// Remove the polygon from each removed point's children
|
|
61786
62205
|
for (i = 0; i < nidx.length; i++) {
|
|
61787
62206
|
this.vertices[nidx[i]].removeChild(this);
|
|
61788
62207
|
}
|
|
61789
62208
|
|
|
61790
|
-
//
|
|
62209
|
+
// Sort the elements to be eliminated
|
|
61791
62210
|
nidx = nidx.sort();
|
|
61792
62211
|
nvertices = this.vertices.slice();
|
|
61793
62212
|
nborders = this.borders.slice();
|
|
61794
62213
|
|
|
61795
|
-
//
|
|
62214
|
+
// Initialize the partition
|
|
61796
62215
|
if (this.withLines) {
|
|
61797
62216
|
partition.push([nidx[nidx.length - 1]]);
|
|
61798
62217
|
}
|
|
61799
62218
|
|
|
61800
|
-
//
|
|
62219
|
+
// Run through all existing vertices and copy all remaining ones to nvertices,
|
|
61801
62220
|
// compute the partition
|
|
61802
62221
|
for (i = nidx.length - 1; i > -1; i--) {
|
|
61803
62222
|
nvertices[nidx[i]] = -1;
|
|
@@ -61808,12 +62227,12 @@ define('base/polygon',[
|
|
|
61808
62227
|
}
|
|
61809
62228
|
}
|
|
61810
62229
|
|
|
61811
|
-
//
|
|
62230
|
+
// Finalize the partition computation
|
|
61812
62231
|
if (this.withLines) {
|
|
61813
62232
|
partition[partition.length - 1][1] = nidx[0];
|
|
61814
62233
|
}
|
|
61815
62234
|
|
|
61816
|
-
//
|
|
62235
|
+
// Update vertices
|
|
61817
62236
|
this.vertices = [];
|
|
61818
62237
|
for (i = 0; i < nvertices.length; i++) {
|
|
61819
62238
|
if (Type.isPoint(nvertices[i])) {
|
|
@@ -61824,7 +62243,7 @@ define('base/polygon',[
|
|
|
61824
62243
|
this.vertices.push(this.vertices[0]);
|
|
61825
62244
|
}
|
|
61826
62245
|
|
|
61827
|
-
//
|
|
62246
|
+
// Delete obsolete and create missing borders
|
|
61828
62247
|
if (this.withLines) {
|
|
61829
62248
|
for (i = 0; i < partition.length; i++) {
|
|
61830
62249
|
for (j = partition[i][1] - 1; j < partition[i][0] + 1; j++) {
|
|
@@ -68684,9 +69103,6 @@ define('element/composition',[
|
|
|
68684
69103
|
b.addChild(t);
|
|
68685
69104
|
}
|
|
68686
69105
|
|
|
68687
|
-
|
|
68688
|
-
|
|
68689
|
-
|
|
68690
69106
|
t.elType = 'midpoint';
|
|
68691
69107
|
t.setParents([a.id, b.id]);
|
|
68692
69108
|
|
|
@@ -68896,14 +69312,21 @@ define('element/composition',[
|
|
|
68896
69312
|
};
|
|
68897
69313
|
|
|
68898
69314
|
/**
|
|
68899
|
-
* @class A parallel is a line through a given point with the same slope as a given line
|
|
69315
|
+
* @class A parallel is a line through a given point with the same slope as a given line or
|
|
69316
|
+
* the line through two given point.
|
|
69317
|
+
* <p>
|
|
69318
|
+
* If original line is given as a JSXGraph line object, the resulting parallel line will be defined by the given point and an
|
|
69319
|
+
* infinitely far away point (an ideal point). That means, the line can not be shortened to a segment.
|
|
69320
|
+
* <p>
|
|
69321
|
+
* If the original line is given as two points, the resulting parallel line can be shortened to a a segment.
|
|
68900
69322
|
* @pseudo
|
|
68901
69323
|
* @name Parallel
|
|
68902
69324
|
* @augments Line
|
|
68903
69325
|
* @constructor
|
|
68904
69326
|
* @type JXG.Line
|
|
68905
69327
|
* @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
68906
|
-
* @param {JXG.Line_JXG.Point} l,p The constructed line contains p and has the same slope as l.
|
|
69328
|
+
* @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
|
|
69329
|
+
* constructed line contains p and has the same slope as the line through p1 and p2.
|
|
68907
69330
|
* @example
|
|
68908
69331
|
* // Create a parallel
|
|
68909
69332
|
* var p1 = board.create('point', [0.0, 2.0]);
|
|
@@ -68921,22 +69344,47 @@ define('element/composition',[
|
|
|
68921
69344
|
* var plex1_p3 = plex1_board.create('point', [3.0, 3.0]);
|
|
68922
69345
|
* var plex1_pl1 = plex1_board.create('parallel', [plex1_l1, plex1_p3]);
|
|
68923
69346
|
* </script><pre>
|
|
69347
|
+
* @example
|
|
69348
|
+
* var p1, p2, p3, l1, pl1;
|
|
69349
|
+
*
|
|
69350
|
+
* p1 = board.create('point', [0.0, 2.0]);
|
|
69351
|
+
* p2 = board.create('point', [2.0, 1.0]);
|
|
69352
|
+
* l1 = board.create('line', [p1, p2]);
|
|
69353
|
+
*
|
|
69354
|
+
* p3 = board.create('point', [1.0, 3.0]);
|
|
69355
|
+
* pl1 = board.create('parallel', [p1, p2, p3], {straightFirst: false, straightLast: false});
|
|
69356
|
+
*
|
|
69357
|
+
* </pre><div id="JXGd643305d-20c3-4a88-91f9-8d0c4448594f" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
69358
|
+
* <script type="text/javascript">
|
|
69359
|
+
* (function() {
|
|
69360
|
+
* var board = JXG.JSXGraph.initBoard('JXGd643305d-20c3-4a88-91f9-8d0c4448594f',
|
|
69361
|
+
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
69362
|
+
* var p1, p2, p3, l1, pl1;
|
|
69363
|
+
*
|
|
69364
|
+
* p1 = board.create('point', [0.0, 2.0]);
|
|
69365
|
+
* p2 = board.create('point', [2.0, 1.0]);
|
|
69366
|
+
* l1 = board.create('line', [p1, p2]);
|
|
69367
|
+
*
|
|
69368
|
+
* p3 = board.create('point', [1.0, 3.0]);
|
|
69369
|
+
* pl1 = board.create('parallel', [p1, p2, p3], {straightFirst: false, straightLast: false});
|
|
69370
|
+
*
|
|
69371
|
+
* })();
|
|
69372
|
+
*
|
|
69373
|
+
* </script><pre>
|
|
69374
|
+
*
|
|
68924
69375
|
*/
|
|
68925
69376
|
JXG.createParallel = function (board, parents, attributes) {
|
|
68926
|
-
var p, pp, pl, li, i, attr;
|
|
69377
|
+
var p, pp, pl, li, i, attr, ty = 1;
|
|
68927
69378
|
|
|
68928
69379
|
for (i = 0; i < parents.length; ++i) {
|
|
68929
69380
|
parents[i] = board.select(parents[i]);
|
|
68930
69381
|
}
|
|
68931
69382
|
p = null;
|
|
68932
69383
|
if (parents.length === 3) {
|
|
69384
|
+
// Line / segment through point parents[2] which is parallel to line through parents[0] and parents[1]
|
|
68933
69385
|
parents = Type.providePoints(board, parents, attributes, 'point');
|
|
68934
|
-
// line through point parents[2] which is parallel to line through parents[0] and parents[1]
|
|
68935
69386
|
p = parents[2];
|
|
68936
|
-
|
|
68937
|
-
li = function () {
|
|
68938
|
-
return Mat.crossProduct(parents[0].coords.usrCoords, parents[1].coords.usrCoords);
|
|
68939
|
-
};
|
|
69387
|
+
ty = 0;
|
|
68940
69388
|
} else if (Type.isPointType(board, parents[0])) {
|
|
68941
69389
|
// Parallel to line parents[1] through point parents[0]
|
|
68942
69390
|
p = Type.providePoints(board, [parents[0]], attributes, 'point')[0];
|
|
@@ -68958,11 +69406,19 @@ define('element/composition',[
|
|
|
68958
69406
|
}
|
|
68959
69407
|
|
|
68960
69408
|
attr = Type.copyAttributes(attributes, board.options, 'parallel', 'point');
|
|
68961
|
-
|
|
68962
|
-
|
|
68963
|
-
|
|
68964
|
-
|
|
68965
|
-
|
|
69409
|
+
if (ty === 1) {
|
|
69410
|
+
// Line is given by line element. The parallel line is
|
|
69411
|
+
// constructed as line through an ideal point.
|
|
69412
|
+
pp = board.create('point', [
|
|
69413
|
+
function () {
|
|
69414
|
+
return Mat.crossProduct([1, 0, 0], li());
|
|
69415
|
+
}
|
|
69416
|
+
], attr);
|
|
69417
|
+
} else {
|
|
69418
|
+
// Line is given by two points. The parallel line is
|
|
69419
|
+
// constructed as line through two finite point.
|
|
69420
|
+
pp = board.create('parallelpoint', parents, attr);
|
|
69421
|
+
}
|
|
68966
69422
|
pp.isDraggable = true;
|
|
68967
69423
|
|
|
68968
69424
|
attr = Type.copyAttributes(attributes, board.options, 'parallel');
|
|
@@ -68996,31 +69452,33 @@ define('element/composition',[
|
|
|
68996
69452
|
};
|
|
68997
69453
|
|
|
68998
69454
|
/**
|
|
68999
|
-
* @class An arrow parallel is a
|
|
69455
|
+
* @class An arrow parallel is a segment with an arrow attached which is parallel through a given segment, given by its defining two points,
|
|
69456
|
+
* through a given point.
|
|
69457
|
+
* <p>
|
|
69000
69458
|
* @pseudo
|
|
69001
69459
|
* @constructor
|
|
69002
69460
|
* @name Arrowparallel
|
|
69003
69461
|
* @type Parallel
|
|
69004
69462
|
* @augments Parallel
|
|
69005
69463
|
* @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
69006
|
-
* @param
|
|
69464
|
+
* @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.
|
|
69007
69465
|
* @example
|
|
69008
69466
|
* // Create a parallel
|
|
69009
69467
|
* var p1 = board.create('point', [0.0, 2.0]);
|
|
69010
69468
|
* var p2 = board.create('point', [2.0, 1.0]);
|
|
69011
|
-
* var l1 = board.create('
|
|
69469
|
+
* var l1 = board.create('segment', [p1, p2]);
|
|
69012
69470
|
*
|
|
69013
69471
|
* var p3 = board.create('point', [3.0, 3.0]);
|
|
69014
|
-
* var pl1 = board.create('arrowparallel', [
|
|
69472
|
+
* var pl1 = board.create('arrowparallel', [p1, p2, p3]);
|
|
69015
69473
|
* </pre><div class="jxgbox" id="JXGeeacdf99-036f-4e83-aeb6-f7388423e369" style="width: 400px; height: 400px;"></div>
|
|
69016
69474
|
* <script type="text/javascript">
|
|
69017
69475
|
* (function () {
|
|
69018
69476
|
* var plex1_board = JXG.JSXGraph.initBoard('JXGeeacdf99-036f-4e83-aeb6-f7388423e369', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});
|
|
69019
69477
|
* var plex1_p1 = plex1_board.create('point', [0.0, 2.0]);
|
|
69020
69478
|
* var plex1_p2 = plex1_board.create('point', [2.0, 1.0]);
|
|
69021
|
-
* var plex1_l1 = plex1_board.create('
|
|
69479
|
+
* var plex1_l1 = plex1_board.create('segment', [plex1_p1, plex1_p2]);
|
|
69022
69480
|
* var plex1_p3 = plex1_board.create('point', [3.0, 3.0]);
|
|
69023
|
-
* var plex1_pl1 = plex1_board.create('arrowparallel', [
|
|
69481
|
+
* var plex1_pl1 = plex1_board.create('arrowparallel', [plex1_p1, plex1_p2, plex1_p3]);
|
|
69024
69482
|
* })();
|
|
69025
69483
|
* </script><pre>
|
|
69026
69484
|
*/
|
|
@@ -69467,7 +69925,7 @@ define('element/composition',[
|
|
|
69467
69925
|
};
|
|
69468
69926
|
|
|
69469
69927
|
/**
|
|
69470
|
-
* @class Bisector lines are similar to {@link Bisector} but
|
|
69928
|
+
* @class Bisector lines are similar to {@link Bisector} but take two lines as parent elements. The resulting element is
|
|
69471
69929
|
* a composition of two lines.
|
|
69472
69930
|
* @pseudo
|
|
69473
69931
|
* @constructor
|
|
@@ -72224,6 +72682,10 @@ define('element/slider',[
|
|
|
72224
72682
|
p2.dump = false;
|
|
72225
72683
|
l1.dump = false;
|
|
72226
72684
|
l2.dump = false;
|
|
72685
|
+
if (withText) {
|
|
72686
|
+
t.dump = false;
|
|
72687
|
+
}
|
|
72688
|
+
|
|
72227
72689
|
|
|
72228
72690
|
p3.elType = 'slider';
|
|
72229
72691
|
p3.parents = parents;
|
|
@@ -72241,6 +72703,14 @@ define('element/slider',[
|
|
|
72241
72703
|
p3.inherits.push(ti);
|
|
72242
72704
|
}
|
|
72243
72705
|
|
|
72706
|
+
p3.getParents = function() {
|
|
72707
|
+
return [
|
|
72708
|
+
this.point1.coords.usrCoords.slice(1),
|
|
72709
|
+
this.point2.coords.usrCoords.slice(1),
|
|
72710
|
+
[this._smin, this.position * (this._smax - this._smin) + this._smin, this._smax]
|
|
72711
|
+
];
|
|
72712
|
+
};
|
|
72713
|
+
|
|
72244
72714
|
p3.baseline.on('up', function(evt) {
|
|
72245
72715
|
var pos, c;
|
|
72246
72716
|
|
|
@@ -75969,7 +76439,7 @@ define('base/ticks',[
|
|
|
75969
76439
|
|
|
75970
76440
|
// if value is Number
|
|
75971
76441
|
if (Type.isNumber(value)) {
|
|
75972
|
-
labelText = (Math.round(value * 1.
|
|
76442
|
+
labelText = (Math.round(value * 1.e11) / 1.e11).toString();
|
|
75973
76443
|
if (labelText.length > Type.evaluate(this.visProp.maxlabellength) ||
|
|
75974
76444
|
labelText.indexOf('e') !== -1) {
|
|
75975
76445
|
|
|
@@ -76214,6 +76684,8 @@ define('base/ticks',[
|
|
|
76214
76684
|
attr.id = this.id + ld.i + 'Label' + this.labelCounter;
|
|
76215
76685
|
|
|
76216
76686
|
label = Text.createText(this.board, [ld.x, ld.y, ld.t], attr);
|
|
76687
|
+
this.addChild(label);
|
|
76688
|
+
label.setParents(this);
|
|
76217
76689
|
label.isDraggable = false;
|
|
76218
76690
|
label.dump = false;
|
|
76219
76691
|
this.labels.push(label);
|
|
@@ -79755,7 +80227,13 @@ define('element/button',[
|
|
|
79755
80227
|
* an SVG foreignObject container.
|
|
79756
80228
|
* <p>
|
|
79757
80229
|
* Instead of board.create('foreignobject') the shortcut board.create('fo') may be used.
|
|
79758
|
-
*
|
|
80230
|
+
*
|
|
80231
|
+
* <p style="background-color:#dddddd; padding:10px"><b>NOTE:</b> In Safari up to version 15, a foreignObject does not obey the layer structure
|
|
80232
|
+
* if it contains <video> or <iframe> tags, as well as elements which are
|
|
80233
|
+
* positioned with <tt>position:absolute|relative|fixed</tt>. In this case, the foreignobject will be
|
|
80234
|
+
* "above" the JSXGraph construction.
|
|
80235
|
+
* </p>
|
|
80236
|
+
*
|
|
79759
80237
|
* @pseudo
|
|
79760
80238
|
* @description
|
|
79761
80239
|
* @name ForeignObject
|
|
@@ -79893,6 +80371,2040 @@ define('element/button',[
|
|
|
79893
80371
|
};
|
|
79894
80372
|
});
|
|
79895
80373
|
|
|
80374
|
+
/*global JXG:true, define: true*/
|
|
80375
|
+
|
|
80376
|
+
define('options3d',[
|
|
80377
|
+
'jxg', 'options'
|
|
80378
|
+
], function (JXG, Options) {
|
|
80379
|
+
|
|
80380
|
+
"use strict";
|
|
80381
|
+
|
|
80382
|
+
JXG.extend(Options, {
|
|
80383
|
+
|
|
80384
|
+
infobox: {
|
|
80385
|
+
strokeColor: 'black'
|
|
80386
|
+
},
|
|
80387
|
+
|
|
80388
|
+
axes3d: {
|
|
80389
|
+
/**#@+
|
|
80390
|
+
* @visprop
|
|
80391
|
+
*/
|
|
80392
|
+
|
|
80393
|
+
/**
|
|
80394
|
+
* Position of the main axes in a View3D element. Possible values are
|
|
80395
|
+
* 'center' and 'border'.
|
|
80396
|
+
*
|
|
80397
|
+
* @type String
|
|
80398
|
+
* @name View3D#axesPosition
|
|
80399
|
+
* @default 'center'
|
|
80400
|
+
*/
|
|
80401
|
+
axesPosition: 'center', // Possible values: 'center', otherwise: border
|
|
80402
|
+
|
|
80403
|
+
// Main axes
|
|
80404
|
+
|
|
80405
|
+
/**
|
|
80406
|
+
* Attributes of the 3D x-axis.
|
|
80407
|
+
*
|
|
80408
|
+
* @type Line3D
|
|
80409
|
+
* @name View3D#xAxis
|
|
80410
|
+
*/
|
|
80411
|
+
xAxis: { visible: true, point2: {name: 'x'}},
|
|
80412
|
+
|
|
80413
|
+
/**
|
|
80414
|
+
* Attributes of the 3D y-axis.
|
|
80415
|
+
*
|
|
80416
|
+
* @type Line3D
|
|
80417
|
+
* @name View3D#yAxis
|
|
80418
|
+
*/
|
|
80419
|
+
yAxis: { visible: true, point2: {name: 'y'}},
|
|
80420
|
+
|
|
80421
|
+
/**
|
|
80422
|
+
* Attributes of the 3D z-axis.
|
|
80423
|
+
*
|
|
80424
|
+
* @type Line3D
|
|
80425
|
+
* @name View3D#zAxis
|
|
80426
|
+
*/
|
|
80427
|
+
zAxis: { visible: true, point2: {name: 'z'}},
|
|
80428
|
+
|
|
80429
|
+
// Planes
|
|
80430
|
+
/**
|
|
80431
|
+
* Attributes of the 3D plane orthogonal to the x-axis at the "rear" of the cube.
|
|
80432
|
+
* @type Plane3D
|
|
80433
|
+
* @name View3D#xPlaneRear
|
|
80434
|
+
*/
|
|
80435
|
+
xPlaneRear: { visible: true, layer: 0, mesh3d: { layer: 1 } },
|
|
80436
|
+
/**
|
|
80437
|
+
* Attributes of the 3D plane orthogonal to the y-axis at the "rear" of the cube.
|
|
80438
|
+
* @type Plane3D
|
|
80439
|
+
* @name View3D#yPlaneRear
|
|
80440
|
+
*/
|
|
80441
|
+
yPlaneRear: { visible: true, layer: 0, mesh3d: { layer: 1 } },
|
|
80442
|
+
/**
|
|
80443
|
+
* Attributes of the 3D plane orthogonal to the z-axis at the "rear" of the cube.
|
|
80444
|
+
* @type Plane3D
|
|
80445
|
+
* @name View3D#zPlaneRear
|
|
80446
|
+
*/
|
|
80447
|
+
zPlaneRear: { visible: true, layer: 0, mesh3d: { layer: 1 } },
|
|
80448
|
+
|
|
80449
|
+
/**
|
|
80450
|
+
* Attributes of the 3D plane orthogonal to the x-axis at the "front" of the cube.
|
|
80451
|
+
* @type Plane3D
|
|
80452
|
+
* @name View3D#xPlaneFront
|
|
80453
|
+
*/
|
|
80454
|
+
xPlaneFront: { visible: false, layer: 0, mesh3d: { layer: 1 } },
|
|
80455
|
+
/**
|
|
80456
|
+
* Attributes of the 3D plane orthogonal to the y-axis at the "front" of the cube.
|
|
80457
|
+
* @type Plane3D
|
|
80458
|
+
* @name View3D#yPlaneFront
|
|
80459
|
+
*/
|
|
80460
|
+
yPlaneFront: { visible: false, layer: 0, mesh3d: { layer: 1 } },
|
|
80461
|
+
/**
|
|
80462
|
+
* Attributes of the 3D plane orthogonal to the z-axis at the "front" of the cube.
|
|
80463
|
+
* @type Plane3D
|
|
80464
|
+
* @name View3D#zPlaneFront
|
|
80465
|
+
*/
|
|
80466
|
+
zPlaneFront: { visible: false, layer: 0, mesh3d: { layer: 1 } },
|
|
80467
|
+
|
|
80468
|
+
// Axes on the planes
|
|
80469
|
+
/**
|
|
80470
|
+
* Attributes of the 3D y-axis on the 3D plane orthogonal to the x-axis at the "rear" of the cube.
|
|
80471
|
+
* @type Plane3D
|
|
80472
|
+
* @name View3D#xPlaneRearYAxis
|
|
80473
|
+
*/
|
|
80474
|
+
xPlaneRearYAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80475
|
+
/**
|
|
80476
|
+
* Attributes of the 3D z-axis on the 3D plane orthogonal to the x-axis at the "rear" of the cube.
|
|
80477
|
+
* @type Plane3D
|
|
80478
|
+
* @name View3D#xPlaneRearZAxis
|
|
80479
|
+
*/
|
|
80480
|
+
xPlaneRearZAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80481
|
+
/**
|
|
80482
|
+
* Attributes of the 3D y-axis on the 3D plane orthogonal to the x-axis at the "front" of the cube.
|
|
80483
|
+
* @type Plane3D
|
|
80484
|
+
* @name View3D#xPlaneFrontYAxis
|
|
80485
|
+
*/
|
|
80486
|
+
xPlaneFrontYAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80487
|
+
/**
|
|
80488
|
+
* Attributes of the 3D z-axis on the 3D plane orthogonal to the x-axis at the "front" of the cube.
|
|
80489
|
+
* @type Plane3D
|
|
80490
|
+
* @name View3D#xPlaneFrontZAxis
|
|
80491
|
+
*/
|
|
80492
|
+
xPlaneFrontZAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80493
|
+
|
|
80494
|
+
/**
|
|
80495
|
+
* Attributes of the 3D x-axis on the 3D plane orthogonal to the y-axis at the "rear" of the cube.
|
|
80496
|
+
* @type Plane3D
|
|
80497
|
+
* @name View3D#yPlaneRearXAxis
|
|
80498
|
+
*/
|
|
80499
|
+
yPlaneRearXAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80500
|
+
/**
|
|
80501
|
+
* Attributes of the 3D z-axis on the 3D plane orthogonal to the y-axis at the "rear" of the cube.
|
|
80502
|
+
* @type Plane3D
|
|
80503
|
+
* @name View3D#yPlaneRearZAxis
|
|
80504
|
+
*/
|
|
80505
|
+
yPlaneRearZAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80506
|
+
/**
|
|
80507
|
+
* Attributes of the 3D x-axis on the 3D plane orthogonal to the y-axis at the "front" of the cube.
|
|
80508
|
+
* @type Plane3D
|
|
80509
|
+
* @name View3D#yPlaneFrontXAxis
|
|
80510
|
+
*/
|
|
80511
|
+
yPlaneFrontXAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80512
|
+
/**
|
|
80513
|
+
* Attributes of the 3D z-axis on the 3D plane orthogonal to the y-axis at the "front" of the cube.
|
|
80514
|
+
* @type Plane3D
|
|
80515
|
+
* @name View3D#yPlaneFrontZAxis
|
|
80516
|
+
*/
|
|
80517
|
+
yPlaneFrontZAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80518
|
+
|
|
80519
|
+
/**
|
|
80520
|
+
* Attributes of the 3D x-axis on the 3D plane orthogonal to the z-axis at the "rear" of the cube.
|
|
80521
|
+
* @type Plane3D
|
|
80522
|
+
* @name View3D#zPlaneRearXAxis
|
|
80523
|
+
*/
|
|
80524
|
+
zPlaneRearXAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80525
|
+
/**
|
|
80526
|
+
* Attributes of the 3D y-axis on the 3D plane orthogonal to the z-axis at the "rear" of the cube.
|
|
80527
|
+
* @type Plane3D
|
|
80528
|
+
* @name View3D#zPlaneRearYAxis
|
|
80529
|
+
*/
|
|
80530
|
+
zPlaneRearYAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80531
|
+
/**
|
|
80532
|
+
* Attributes of the 3D x-axis on the 3D plane orthogonal to the z-axis at the "front" of the cube.
|
|
80533
|
+
* @type Plane3D
|
|
80534
|
+
* @name View3D#zPlaneFrontXAxis
|
|
80535
|
+
*/
|
|
80536
|
+
zPlaneFrontXAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1},
|
|
80537
|
+
/**
|
|
80538
|
+
* Attributes of the 3D y-axis on the 3D plane orthogonal to the z-axis at the "front" of the cube.
|
|
80539
|
+
* @type Plane3D
|
|
80540
|
+
* @name View3D#zPlaneFrontYAxis
|
|
80541
|
+
*/
|
|
80542
|
+
zPlaneFrontYAxis: {visible: 'inherit', strokeColor: '#888888', strokeWidth: 1}
|
|
80543
|
+
|
|
80544
|
+
/**#@-*/
|
|
80545
|
+
},
|
|
80546
|
+
|
|
80547
|
+
axis3d: {
|
|
80548
|
+
highlight: false,
|
|
80549
|
+
strokecolor: 'black',
|
|
80550
|
+
strokeWidth: 1,
|
|
80551
|
+
tabindex: null,
|
|
80552
|
+
|
|
80553
|
+
point1: { visible: false, name: '' },
|
|
80554
|
+
point2: { visible: false, name: '', label: { visible: true } }
|
|
80555
|
+
},
|
|
80556
|
+
|
|
80557
|
+
mesh3d: {
|
|
80558
|
+
strokeWidth: 1,
|
|
80559
|
+
strokeColor: '#9a9a9a',
|
|
80560
|
+
strokeOpacity: 0.6,
|
|
80561
|
+
highlight: false,
|
|
80562
|
+
fillColor: '#9a9a9a',
|
|
80563
|
+
fillOpacity: 0.1,
|
|
80564
|
+
tabindex: null,
|
|
80565
|
+
|
|
80566
|
+
visible: 'inherit'
|
|
80567
|
+
},
|
|
80568
|
+
|
|
80569
|
+
line3d: {
|
|
80570
|
+
strokeWidth: 1,
|
|
80571
|
+
strokeColor: 'black',
|
|
80572
|
+
fixed: true,
|
|
80573
|
+
tabindex: null,
|
|
80574
|
+
|
|
80575
|
+
gradient: 'linear',
|
|
80576
|
+
gradientSecondColor: '#ffffff',
|
|
80577
|
+
|
|
80578
|
+
point1: {visible: false, name: ''},
|
|
80579
|
+
point2: {visible: false, name: ''}
|
|
80580
|
+
},
|
|
80581
|
+
|
|
80582
|
+
plane3d: {
|
|
80583
|
+
strokeWidth: 0,
|
|
80584
|
+
strokeColor: 'black',
|
|
80585
|
+
strokeOpacity: 1,
|
|
80586
|
+
highlight: false,
|
|
80587
|
+
tabindex: null,
|
|
80588
|
+
|
|
80589
|
+
gradient: 'linear',
|
|
80590
|
+
gradientSecondColor: '#ffffff',
|
|
80591
|
+
gradientAngle: Math.PI,
|
|
80592
|
+
fillColor: '#a7a7a7',
|
|
80593
|
+
fillOpacity: 0.6
|
|
80594
|
+
},
|
|
80595
|
+
|
|
80596
|
+
point3d: {
|
|
80597
|
+
strokeWidth: 0,
|
|
80598
|
+
gradient: 'radial',
|
|
80599
|
+
gradientSecondColor: '#555555',
|
|
80600
|
+
fillColor: 'yellow',
|
|
80601
|
+
highlightStrokeColor: '#555555'
|
|
80602
|
+
},
|
|
80603
|
+
|
|
80604
|
+
surface3d: {
|
|
80605
|
+
/**#@+
|
|
80606
|
+
* @visprop
|
|
80607
|
+
*/
|
|
80608
|
+
|
|
80609
|
+
highlight: false,
|
|
80610
|
+
tabindex: -1,
|
|
80611
|
+
strokeWidth: 1,
|
|
80612
|
+
|
|
80613
|
+
/**
|
|
80614
|
+
* Number of intervals the mesh is divided into in direction of parameter u.
|
|
80615
|
+
* @type Number
|
|
80616
|
+
* @name Surface3D#stepsU
|
|
80617
|
+
*/
|
|
80618
|
+
stepsU: 30,
|
|
80619
|
+
|
|
80620
|
+
/**
|
|
80621
|
+
* Number of intervals the mesh is divided into in direction of parameter v.
|
|
80622
|
+
* @type Number
|
|
80623
|
+
* @name Surface3D#stepsV
|
|
80624
|
+
*/
|
|
80625
|
+
stepsV: 30
|
|
80626
|
+
|
|
80627
|
+
/**#@-*/
|
|
80628
|
+
},
|
|
80629
|
+
|
|
80630
|
+
view3d: {
|
|
80631
|
+
needsRegularUpdate: true
|
|
80632
|
+
}
|
|
80633
|
+
|
|
80634
|
+
});
|
|
80635
|
+
|
|
80636
|
+
return JXG.Options;
|
|
80637
|
+
});
|
|
80638
|
+
|
|
80639
|
+
|
|
80640
|
+
/*
|
|
80641
|
+
Copyright 2008-2022
|
|
80642
|
+
Matthias Ehmann,
|
|
80643
|
+
Carsten Miller,
|
|
80644
|
+
Andreas Walter,
|
|
80645
|
+
Alfred Wassermann
|
|
80646
|
+
|
|
80647
|
+
This file is part of JSXGraph.
|
|
80648
|
+
|
|
80649
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
80650
|
+
|
|
80651
|
+
You can redistribute it and/or modify it under the terms of the
|
|
80652
|
+
|
|
80653
|
+
* GNU Lesser General Public License as published by
|
|
80654
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
80655
|
+
(at your option) any later version
|
|
80656
|
+
OR
|
|
80657
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
80658
|
+
|
|
80659
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
80660
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
80661
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
80662
|
+
GNU Lesser General Public License for more details.
|
|
80663
|
+
|
|
80664
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
80665
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
80666
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
80667
|
+
*/
|
|
80668
|
+
/*global JXG:true, define: true*/
|
|
80669
|
+
|
|
80670
|
+
define('3d/threed',['jxg'
|
|
80671
|
+
], function (JXG) {
|
|
80672
|
+
"use strict";
|
|
80673
|
+
|
|
80674
|
+
JXG.ThreeD = {};
|
|
80675
|
+
|
|
80676
|
+
return JXG.ThreeD;
|
|
80677
|
+
});
|
|
80678
|
+
|
|
80679
|
+
/*
|
|
80680
|
+
Copyright 2008-2022
|
|
80681
|
+
Matthias Ehmann,
|
|
80682
|
+
Carsten Miller,
|
|
80683
|
+
Andreas Walter,
|
|
80684
|
+
Alfred Wassermann
|
|
80685
|
+
|
|
80686
|
+
This file is part of JSXGraph.
|
|
80687
|
+
|
|
80688
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
80689
|
+
|
|
80690
|
+
You can redistribute it and/or modify it under the terms of the
|
|
80691
|
+
|
|
80692
|
+
* GNU Lesser General Public License as published by
|
|
80693
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
80694
|
+
(at your option) any later version
|
|
80695
|
+
OR
|
|
80696
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
80697
|
+
|
|
80698
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
80699
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
80700
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
80701
|
+
GNU Lesser General Public License for more details.
|
|
80702
|
+
|
|
80703
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
80704
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
80705
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
80706
|
+
*/
|
|
80707
|
+
/*global JXG:true, define: true*/
|
|
80708
|
+
|
|
80709
|
+
define('3d/view3d',['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/element', '3d/threed',
|
|
80710
|
+
], function (JXG, Options, Const, Type, Mat, GeometryElement, ThreeD) {
|
|
80711
|
+
"use strict";
|
|
80712
|
+
|
|
80713
|
+
ThreeD.View3D = function (board, parents, attributes) {
|
|
80714
|
+
var bbox3d, coords, size;
|
|
80715
|
+
this.constructor(board, attributes, Const.OBJECT_TYPE_VIEW3D, Const.OBJECT_CLASS_CURVE);
|
|
80716
|
+
|
|
80717
|
+
bbox3d = parents[2]; // [[x1, x2], [y1,y2], [z1,z2]]
|
|
80718
|
+
coords = parents[0]; // llft corner
|
|
80719
|
+
size = parents[1]; // [w, h]
|
|
80720
|
+
|
|
80721
|
+
/**
|
|
80722
|
+
* "Namespace" for all 3D handling
|
|
80723
|
+
*/
|
|
80724
|
+
this.D3 = {};
|
|
80725
|
+
|
|
80726
|
+
/**
|
|
80727
|
+
* An associative array containing all geometric objects belonging to the view.
|
|
80728
|
+
* Key is the id of the object and value is a reference to the object.
|
|
80729
|
+
* @type Object
|
|
80730
|
+
*/
|
|
80731
|
+
this.D3.objects = {};
|
|
80732
|
+
|
|
80733
|
+
/**
|
|
80734
|
+
* An array containing all geometric objects in this view in the order of construction.
|
|
80735
|
+
* @type Array
|
|
80736
|
+
*/
|
|
80737
|
+
this.D3.objectsList = [];
|
|
80738
|
+
|
|
80739
|
+
/**
|
|
80740
|
+
* @type {Object} contains the axes of the view or null
|
|
80741
|
+
* @default null
|
|
80742
|
+
*/
|
|
80743
|
+
this.D3.defaultAxes = null;
|
|
80744
|
+
|
|
80745
|
+
/**
|
|
80746
|
+
* 3D-to-2D transformation matrix
|
|
80747
|
+
* @type {Array} 3 x 4 mattrix
|
|
80748
|
+
*/
|
|
80749
|
+
this.D3.matrix = [
|
|
80750
|
+
[1, 0, 0, 0],
|
|
80751
|
+
[0, 1, 0, 0],
|
|
80752
|
+
[0, 0, 1, 0]
|
|
80753
|
+
];
|
|
80754
|
+
|
|
80755
|
+
// Bounding box (cube) [[x1, x2], [y1,y2], [z1,z2]]:
|
|
80756
|
+
this.D3.bbox3d = bbox3d;
|
|
80757
|
+
this.D3.coords = coords;
|
|
80758
|
+
this.D3.size = size;
|
|
80759
|
+
|
|
80760
|
+
/**
|
|
80761
|
+
* Distance of the view to the origin. In other words, its
|
|
80762
|
+
* the radius of the sphere where the camera sits.
|
|
80763
|
+
*/
|
|
80764
|
+
this.D3.r = -1;
|
|
80765
|
+
|
|
80766
|
+
this.timeoutAzimuth = null;
|
|
80767
|
+
|
|
80768
|
+
this.id = this.board.setId(this, 'V');
|
|
80769
|
+
this.board.finalizeAdding(this);
|
|
80770
|
+
this.elType = 'view3d';
|
|
80771
|
+
this.methodMap = Type.deepCopy(this.methodMap, {
|
|
80772
|
+
});
|
|
80773
|
+
};
|
|
80774
|
+
ThreeD.View3D.prototype = new GeometryElement();
|
|
80775
|
+
|
|
80776
|
+
JXG.extend(ThreeD.View3D.prototype, /** @lends ThreeD.View3D.prototype */ {
|
|
80777
|
+
create: function (elementType, parents, attributes) {
|
|
80778
|
+
var prefix = [],
|
|
80779
|
+
is3D = false,
|
|
80780
|
+
el;
|
|
80781
|
+
|
|
80782
|
+
if (elementType.indexOf('3d') > 0) {
|
|
80783
|
+
is3D = true;
|
|
80784
|
+
prefix.push(this);
|
|
80785
|
+
}
|
|
80786
|
+
el = this.board.create(elementType, prefix.concat(parents), attributes);
|
|
80787
|
+
if (true || is3D) {
|
|
80788
|
+
this.add(el);
|
|
80789
|
+
}
|
|
80790
|
+
return el;
|
|
80791
|
+
},
|
|
80792
|
+
|
|
80793
|
+
add: function (el) {
|
|
80794
|
+
this.D3.objects[el.id] = el;
|
|
80795
|
+
this.D3.objectsList.push(el);
|
|
80796
|
+
},
|
|
80797
|
+
|
|
80798
|
+
/**
|
|
80799
|
+
* Update 3D-to-2D transformation matrix with the actual
|
|
80800
|
+
* elevation and azimuth angles.
|
|
80801
|
+
*
|
|
80802
|
+
* @private
|
|
80803
|
+
*/
|
|
80804
|
+
update: function () {
|
|
80805
|
+
var D3 = this.D3,
|
|
80806
|
+
e, r, a, f, mat;
|
|
80807
|
+
|
|
80808
|
+
if (!Type.exists(D3.el_slide) ||
|
|
80809
|
+
!Type.exists(D3.az_slide) ||
|
|
80810
|
+
!this.needsUpdate) {
|
|
80811
|
+
return this;
|
|
80812
|
+
}
|
|
80813
|
+
|
|
80814
|
+
e = D3.el_slide.Value();
|
|
80815
|
+
r = D3.r;
|
|
80816
|
+
a = D3.az_slide.Value();
|
|
80817
|
+
f = r * Math.sin(e);
|
|
80818
|
+
mat = [[1, 0, 0,], [0, 1, 0], [0, 0, 1]];
|
|
80819
|
+
|
|
80820
|
+
D3.matrix = [
|
|
80821
|
+
[1, 0, 0, 0],
|
|
80822
|
+
[0, 1, 0, 0],
|
|
80823
|
+
[0, 0, 1, 0]
|
|
80824
|
+
];
|
|
80825
|
+
|
|
80826
|
+
D3.matrix[1][1] = r * Math.cos(a);
|
|
80827
|
+
D3.matrix[1][2] = -r * Math.sin(a);
|
|
80828
|
+
D3.matrix[2][1] = f * Math.sin(a);
|
|
80829
|
+
D3.matrix[2][2] = f * Math.cos(a);
|
|
80830
|
+
D3.matrix[2][3] = Math.cos(e);
|
|
80831
|
+
|
|
80832
|
+
if (true) {
|
|
80833
|
+
mat[1][1] = D3.size[0] / (D3.bbox3d[0][1] - D3.bbox3d[0][0]); // w / d_x
|
|
80834
|
+
mat[2][2] = D3.size[1] / (D3.bbox3d[1][1] - D3.bbox3d[1][0]); // h / d_y
|
|
80835
|
+
mat[1][0] = D3.coords[0] - mat[1][1] * D3.bbox3d[0][0]; // llft_x
|
|
80836
|
+
mat[2][0] = D3.coords[1] - mat[2][2] * D3.bbox3d[1][0]; // llft_y
|
|
80837
|
+
|
|
80838
|
+
D3.matrix = Mat.matMatMult(mat, D3.matrix);
|
|
80839
|
+
}
|
|
80840
|
+
|
|
80841
|
+
return this;
|
|
80842
|
+
},
|
|
80843
|
+
|
|
80844
|
+
updateRenderer: function () {
|
|
80845
|
+
this.needsUpdate = false;
|
|
80846
|
+
return this;
|
|
80847
|
+
},
|
|
80848
|
+
|
|
80849
|
+
/**
|
|
80850
|
+
* Project 3D coordinates to 2D board coordinates
|
|
80851
|
+
* The 3D coordinates are provides as three numbers x, y, z or one array of length 3.
|
|
80852
|
+
*
|
|
80853
|
+
* @param {Number|Array} x
|
|
80854
|
+
* @param {[Number]} y
|
|
80855
|
+
* @param {[Number]} z
|
|
80856
|
+
* @returns {Array} Array of length 3 containing the projection on to the board
|
|
80857
|
+
* in homogeneous user coordinates.
|
|
80858
|
+
*/
|
|
80859
|
+
project3DTo2D: function (x, y, z) {
|
|
80860
|
+
var vec;
|
|
80861
|
+
if (arguments.length === 3) {
|
|
80862
|
+
vec = [1, x, y, z];
|
|
80863
|
+
} else {
|
|
80864
|
+
// Argument is an array
|
|
80865
|
+
if (x.length === 3) {
|
|
80866
|
+
vec = [1].concat(x);
|
|
80867
|
+
} else {
|
|
80868
|
+
vec = x;
|
|
80869
|
+
}
|
|
80870
|
+
}
|
|
80871
|
+
return Mat.matVecMult(this.D3.matrix, vec);
|
|
80872
|
+
},
|
|
80873
|
+
|
|
80874
|
+
/**
|
|
80875
|
+
* Project a 2D coordinate to the plane through the origin
|
|
80876
|
+
* defined by its normal vector `normal`.
|
|
80877
|
+
*
|
|
80878
|
+
* @param {JXG.Point} point
|
|
80879
|
+
* @param {Array} normal
|
|
80880
|
+
* @returns Array of length 4 containing the projected
|
|
80881
|
+
* point in homogeneous coordinates.
|
|
80882
|
+
*/
|
|
80883
|
+
project2DTo3DPlane: function (point, normal, foot) {
|
|
80884
|
+
var mat, rhs, d, le,
|
|
80885
|
+
n = normal.slice(1),
|
|
80886
|
+
sol = [1, 0, 0, 0];
|
|
80887
|
+
|
|
80888
|
+
foot = foot || [1, 0, 0, 0];
|
|
80889
|
+
le = Mat.norm(n, 3);
|
|
80890
|
+
d = Mat.innerProduct(foot.slice(1), n, 3) / le;
|
|
80891
|
+
|
|
80892
|
+
mat = this.D3.matrix.slice(0, 3); // True copy
|
|
80893
|
+
mat.push([0].concat(n));
|
|
80894
|
+
|
|
80895
|
+
// 2D coordinates of point:
|
|
80896
|
+
rhs = point.coords.usrCoords.concat([d]);
|
|
80897
|
+
try {
|
|
80898
|
+
// Prevent singularity in case elevation angle is zero
|
|
80899
|
+
if (mat[2][3] === 1.0) {
|
|
80900
|
+
mat[2][1] = mat[2][2] = Mat.eps * 0.001;
|
|
80901
|
+
}
|
|
80902
|
+
sol = Mat.Numerics.Gauss(mat, rhs);
|
|
80903
|
+
} catch (err) {
|
|
80904
|
+
sol = [0, NaN, NaN, NaN];
|
|
80905
|
+
}
|
|
80906
|
+
|
|
80907
|
+
return sol;
|
|
80908
|
+
},
|
|
80909
|
+
|
|
80910
|
+
project3DToCube: function (c3d) {
|
|
80911
|
+
var cube = this.D3.bbox3d;
|
|
80912
|
+
if (c3d[1] < cube[0][0]) { c3d[1] = cube[0][0]; }
|
|
80913
|
+
if (c3d[1] > cube[0][1]) { c3d[1] = cube[0][1]; }
|
|
80914
|
+
if (c3d[2] < cube[1][0]) { c3d[2] = cube[1][0]; }
|
|
80915
|
+
if (c3d[2] > cube[1][1]) { c3d[2] = cube[1][1]; }
|
|
80916
|
+
if (c3d[3] < cube[2][0]) { c3d[3] = cube[2][0]; }
|
|
80917
|
+
if (c3d[3] > cube[2][1]) { c3d[3] = cube[2][1]; }
|
|
80918
|
+
|
|
80919
|
+
return c3d;
|
|
80920
|
+
},
|
|
80921
|
+
|
|
80922
|
+
intersectionLineCube: function (p, d, r) {
|
|
80923
|
+
var rnew, i, r0, r1;
|
|
80924
|
+
|
|
80925
|
+
rnew = r;
|
|
80926
|
+
for (i = 0; i < 3; i++) {
|
|
80927
|
+
if (d[i] !== 0) {
|
|
80928
|
+
r0 = (this.D3.bbox3d[i][0] - p[i]) / d[i];
|
|
80929
|
+
r1 = (this.D3.bbox3d[i][1] - p[i]) / d[i];
|
|
80930
|
+
if (r < 0) {
|
|
80931
|
+
rnew = Math.max(rnew, Math.min(r0, r1));
|
|
80932
|
+
} else {
|
|
80933
|
+
rnew = Math.min(rnew, Math.max(r0, r1));
|
|
80934
|
+
}
|
|
80935
|
+
}
|
|
80936
|
+
}
|
|
80937
|
+
return rnew;
|
|
80938
|
+
},
|
|
80939
|
+
|
|
80940
|
+
isInCube: function (q) {
|
|
80941
|
+
return q[0] > this.D3.bbox3d[0][0] - Mat.eps && q[0] < this.D3.bbox3d[0][1] + Mat.eps &&
|
|
80942
|
+
q[1] > this.D3.bbox3d[1][0] - Mat.eps && q[1] < this.D3.bbox3d[1][1] + Mat.eps &&
|
|
80943
|
+
q[2] > this.D3.bbox3d[2][0] - Mat.eps && q[2] < this.D3.bbox3d[2][1] + Mat.eps;
|
|
80944
|
+
},
|
|
80945
|
+
|
|
80946
|
+
/**
|
|
80947
|
+
*
|
|
80948
|
+
* @param {*} plane1
|
|
80949
|
+
* @param {*} plane2
|
|
80950
|
+
* @param {*} d
|
|
80951
|
+
* @returns Array of length 2 containing the coordinates of the defining points of
|
|
80952
|
+
* of the intersection segment.
|
|
80953
|
+
*/
|
|
80954
|
+
intersectionPlanePlane: function(plane1, plane2, d) {
|
|
80955
|
+
var ret = [[], []],
|
|
80956
|
+
p, dir, r, q;
|
|
80957
|
+
|
|
80958
|
+
d = d || plane2.D3.d;
|
|
80959
|
+
|
|
80960
|
+
p = Mat.Geometry.meet3Planes(plane1.D3.normal, plane1.D3.d, plane2.D3.normal, d,
|
|
80961
|
+
Mat.crossProduct(plane1.D3.normal, plane2.D3.normal), 0);
|
|
80962
|
+
dir = Mat.Geometry.meetPlanePlane(plane1.D3.dir1, plane1.D3.dir2, plane2.D3.dir1, plane2.D3.dir2);
|
|
80963
|
+
r = this.intersectionLineCube(p, dir, Infinity);
|
|
80964
|
+
q = Mat.axpy(r, dir, p);
|
|
80965
|
+
if (this.isInCube(q)) {
|
|
80966
|
+
ret[0] = q;
|
|
80967
|
+
}
|
|
80968
|
+
r = this.intersectionLineCube(p, dir, -Infinity);
|
|
80969
|
+
q = Mat.axpy(r, dir, p);
|
|
80970
|
+
if (this.isInCube(q) ) {
|
|
80971
|
+
ret[1] = q;
|
|
80972
|
+
}
|
|
80973
|
+
return ret;
|
|
80974
|
+
},
|
|
80975
|
+
|
|
80976
|
+
getMesh: function (X, Y, Z, interval_u, interval_v) {
|
|
80977
|
+
var i_u, i_v, u, v, c2d,
|
|
80978
|
+
delta_u, delta_v,
|
|
80979
|
+
p = [0, 0, 0],
|
|
80980
|
+
steps_u = interval_u[2],
|
|
80981
|
+
steps_v = interval_v[2],
|
|
80982
|
+
|
|
80983
|
+
dataX = [],
|
|
80984
|
+
dataY = [];
|
|
80985
|
+
|
|
80986
|
+
delta_u = (Type.evaluate(interval_u[1]) - Type.evaluate(interval_u[0])) / (steps_u);
|
|
80987
|
+
delta_v = (Type.evaluate(interval_v[1]) - Type.evaluate(interval_v[0])) / (steps_v);
|
|
80988
|
+
|
|
80989
|
+
for (i_u = 0; i_u <= steps_u; i_u++) {
|
|
80990
|
+
u = interval_u[0] + delta_u * i_u;
|
|
80991
|
+
for (i_v = 0; i_v <= steps_v; i_v++) {
|
|
80992
|
+
v = interval_v[0] + delta_v * i_v;
|
|
80993
|
+
p[0] = X(u, v);
|
|
80994
|
+
p[1] = Y(u, v);
|
|
80995
|
+
p[2] = Z(u, v);
|
|
80996
|
+
c2d = this.project3DTo2D(p);
|
|
80997
|
+
dataX.push(c2d[1]);
|
|
80998
|
+
dataY.push(c2d[2]);
|
|
80999
|
+
}
|
|
81000
|
+
dataX.push(NaN);
|
|
81001
|
+
dataY.push(NaN);
|
|
81002
|
+
}
|
|
81003
|
+
|
|
81004
|
+
for (i_v = 0; i_v <= steps_v; i_v++) {
|
|
81005
|
+
v = interval_v[0] + delta_v * i_v;
|
|
81006
|
+
for (i_u = 0; i_u <= steps_u; i_u++) {
|
|
81007
|
+
u = interval_u[0] + delta_u * i_u;
|
|
81008
|
+
p[0] = X(u, v);
|
|
81009
|
+
p[1] = Y(u, v);
|
|
81010
|
+
p[2] = Z(u, v);
|
|
81011
|
+
c2d = this.project3DTo2D(p);
|
|
81012
|
+
dataX.push(c2d[1]);
|
|
81013
|
+
dataY.push(c2d[2]);
|
|
81014
|
+
}
|
|
81015
|
+
dataX.push(NaN);
|
|
81016
|
+
dataY.push(NaN);
|
|
81017
|
+
}
|
|
81018
|
+
|
|
81019
|
+
return [dataX, dataY];
|
|
81020
|
+
},
|
|
81021
|
+
|
|
81022
|
+
animateAzimuth: function () {
|
|
81023
|
+
var s = this.D3.az_slide._smin,
|
|
81024
|
+
e = this.D3.az_slide._smax,
|
|
81025
|
+
sdiff = e - s,
|
|
81026
|
+
newVal = this.D3.az_slide.Value() + 0.1;
|
|
81027
|
+
|
|
81028
|
+
this.D3.az_slide.position = ((newVal - s) / sdiff);
|
|
81029
|
+
if (this.D3.az_slide.position > 1) {
|
|
81030
|
+
this.D3.az_slide.position = 0.0;
|
|
81031
|
+
}
|
|
81032
|
+
this.board.update();
|
|
81033
|
+
|
|
81034
|
+
this.timeoutAzimuth = setTimeout(function () { this.animateAzimuth(); }.bind(this), 200);
|
|
81035
|
+
},
|
|
81036
|
+
|
|
81037
|
+
stopAzimuth: function () {
|
|
81038
|
+
clearTimeout(this.timeoutAzimuth);
|
|
81039
|
+
this.timeoutAzimuth = null;
|
|
81040
|
+
}
|
|
81041
|
+
});
|
|
81042
|
+
|
|
81043
|
+
/**
|
|
81044
|
+
* @class This element creates a 3D view.
|
|
81045
|
+
* @pseudo
|
|
81046
|
+
* @description A View3D element provides the container and the methods to create and display 3D elements.
|
|
81047
|
+
* It is contained in a JSXGraph board.
|
|
81048
|
+
* @name View3D
|
|
81049
|
+
* @augments JXG.View3D
|
|
81050
|
+
* @constructor
|
|
81051
|
+
* @type Object
|
|
81052
|
+
* @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
81053
|
+
* @param {Array_Array_Array} lower,dim,cube Here, lower is an array of the form [x, y] and
|
|
81054
|
+
* dim is an array of the form [w, h].
|
|
81055
|
+
* The arrays [x, y] and [w, h] define the 2D frame into which the 3D cube is
|
|
81056
|
+
* (roughly) projected.
|
|
81057
|
+
* cube is an array of the form [[x1, x2], [y1, y2], [z1, z2]]
|
|
81058
|
+
* which determines the coordinate ranges of the 3D cube.
|
|
81059
|
+
*
|
|
81060
|
+
* @example
|
|
81061
|
+
* var bound = [-5, 5];
|
|
81062
|
+
* var view = board.create('view3d',
|
|
81063
|
+
* [[-6, -3],
|
|
81064
|
+
* [8, 8],
|
|
81065
|
+
* [bound, bound, bound]],
|
|
81066
|
+
* {
|
|
81067
|
+
* // Main axes
|
|
81068
|
+
* axesPosition: 'center',
|
|
81069
|
+
* xAxis: { strokeColor: 'blue', strokeWidth: 3},
|
|
81070
|
+
*
|
|
81071
|
+
* // Planes
|
|
81072
|
+
* xPlaneRear: { fillColor: 'yellow', mesh3d: {visible: false}},
|
|
81073
|
+
* yPlaneFront: { visible: true, fillColor: 'blue'},
|
|
81074
|
+
*
|
|
81075
|
+
* // Axes on planes
|
|
81076
|
+
* xPlaneRearYAxis: {strokeColor: 'red'},
|
|
81077
|
+
* xPlaneRearZAxis: {strokeColor: 'red'},
|
|
81078
|
+
*
|
|
81079
|
+
* yPlaneFrontXAxis: {strokeColor: 'blue'},
|
|
81080
|
+
* yPlaneFrontZAxis: {strokeColor: 'blue'},
|
|
81081
|
+
*
|
|
81082
|
+
* zPlaneFrontXAxis: {visible: false},
|
|
81083
|
+
* zPlaneFrontYAxis: {visible: false}
|
|
81084
|
+
* });
|
|
81085
|
+
*
|
|
81086
|
+
* </pre><div id="JXGdd06d90e-be5d-4531-8f0b-65fc30b1a7c7" class="jxgbox" style="width: 500px; height: 500px;"></div>
|
|
81087
|
+
* <script type="text/javascript">
|
|
81088
|
+
* (function() {
|
|
81089
|
+
* var board = JXG.JSXGraph.initBoard('JXGdd06d90e-be5d-4531-8f0b-65fc30b1a7c7',
|
|
81090
|
+
* {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
|
|
81091
|
+
* var bound = [-5, 5];
|
|
81092
|
+
* var view = board.create('view3d',
|
|
81093
|
+
* [[-6, -3], [8, 8],
|
|
81094
|
+
* [bound, bound, bound]],
|
|
81095
|
+
* {
|
|
81096
|
+
* // Main axes
|
|
81097
|
+
* axesPosition: 'center',
|
|
81098
|
+
* xAxis: { strokeColor: 'blue', strokeWidth: 3},
|
|
81099
|
+
*
|
|
81100
|
+
* // Planes
|
|
81101
|
+
* xPlaneRear: { fillColor: 'yellow', mesh3d: {visible: false}},
|
|
81102
|
+
* yPlaneFront: { visible: true, fillColor: 'blue'},
|
|
81103
|
+
*
|
|
81104
|
+
* // Axes on planes
|
|
81105
|
+
* xPlaneRearYAxis: {strokeColor: 'red'},
|
|
81106
|
+
* xPlaneRearZAxis: {strokeColor: 'red'},
|
|
81107
|
+
*
|
|
81108
|
+
* yPlaneFrontXAxis: {strokeColor: 'blue'},
|
|
81109
|
+
* yPlaneFrontZAxis: {strokeColor: 'blue'},
|
|
81110
|
+
*
|
|
81111
|
+
* zPlaneFrontXAxis: {visible: false},
|
|
81112
|
+
* zPlaneFrontYAxis: {visible: false}
|
|
81113
|
+
* });
|
|
81114
|
+
*
|
|
81115
|
+
* })();
|
|
81116
|
+
*
|
|
81117
|
+
* </script><pre>
|
|
81118
|
+
*
|
|
81119
|
+
*/
|
|
81120
|
+
ThreeD.createView3D = function (board, parents, attributes) {
|
|
81121
|
+
var view, frame, attr,
|
|
81122
|
+
x, y, w, h,
|
|
81123
|
+
coords = parents[0], // llft corner
|
|
81124
|
+
size = parents[1]; // [w, h]
|
|
81125
|
+
|
|
81126
|
+
attr = Type.copyAttributes(attributes, board.options, 'view3d');
|
|
81127
|
+
view = new ThreeD.View3D(board, parents, attr);
|
|
81128
|
+
view.defaultAxes = view.create('axes3d', parents, attributes);
|
|
81129
|
+
|
|
81130
|
+
x = coords[0];
|
|
81131
|
+
y = coords[1];
|
|
81132
|
+
w = size[0];
|
|
81133
|
+
h = size[1];
|
|
81134
|
+
|
|
81135
|
+
/*
|
|
81136
|
+
* Frame around the view object
|
|
81137
|
+
*/
|
|
81138
|
+
if (false) {
|
|
81139
|
+
frame = board.create('polygon', [
|
|
81140
|
+
[coords[0], coords[1] + size[1]], // ulft
|
|
81141
|
+
[coords[0], coords[1]], // llft
|
|
81142
|
+
[coords[0] + size[0], coords[1]], // lrt
|
|
81143
|
+
[coords[0] + size[0], coords[1] + size[1]], // urt
|
|
81144
|
+
], {
|
|
81145
|
+
fillColor: 'none',
|
|
81146
|
+
highlightFillColor: 'none',
|
|
81147
|
+
highlight: false,
|
|
81148
|
+
vertices: {
|
|
81149
|
+
fixed: true,
|
|
81150
|
+
visible: false
|
|
81151
|
+
},
|
|
81152
|
+
borders: {
|
|
81153
|
+
strokeColor: 'black',
|
|
81154
|
+
highlight: false,
|
|
81155
|
+
strokeWidth: 0.5,
|
|
81156
|
+
dash: 4
|
|
81157
|
+
}
|
|
81158
|
+
});
|
|
81159
|
+
//view.add(frame);
|
|
81160
|
+
}
|
|
81161
|
+
|
|
81162
|
+
/**
|
|
81163
|
+
* Slider to adapt azimuth angle
|
|
81164
|
+
*/
|
|
81165
|
+
view.D3.az_slide = board.create('slider', [[x - 1, y - 2], [x + w + 1, y - 2], [0, 1.0, 2 * Math.PI]], {
|
|
81166
|
+
style: 6, name: 'az',
|
|
81167
|
+
point1: { frozen: true },
|
|
81168
|
+
point2: { frozen: true }
|
|
81169
|
+
});
|
|
81170
|
+
|
|
81171
|
+
/**
|
|
81172
|
+
* Slider to adapt elevation angle
|
|
81173
|
+
*/
|
|
81174
|
+
view.D3.el_slide = board.create('slider', [[x - 1, y], [x - 1, y + h], [0, 0.30, Math.PI / 2]], {
|
|
81175
|
+
style: 6, name: 'el',
|
|
81176
|
+
point1: { frozen: true },
|
|
81177
|
+
point2: { frozen: true }
|
|
81178
|
+
});
|
|
81179
|
+
|
|
81180
|
+
view.board.highlightInfobox = function (x, y, el) {
|
|
81181
|
+
var d;
|
|
81182
|
+
|
|
81183
|
+
if (Type.exists(el.D3)) {
|
|
81184
|
+
d = Type.evaluate(el.visProp.infoboxdigits);
|
|
81185
|
+
if (d === 'auto') {
|
|
81186
|
+
view.board.highlightCustomInfobox('(' +
|
|
81187
|
+
Type.autoDigits(el.D3.X()) + ' | ' +
|
|
81188
|
+
Type.autoDigits(el.D3.Y()) + ' | ' +
|
|
81189
|
+
Type.autoDigits(el.D3.Z()) + ')', el);
|
|
81190
|
+
} else {
|
|
81191
|
+
view.board.highlightCustomInfobox('(' +
|
|
81192
|
+
Type.toFixed(el.D3.X(), d) + ' | ' +
|
|
81193
|
+
Type.toFixed(el.D3.Y(), d) + ' | ' +
|
|
81194
|
+
Type.toFixed(el.D3.Z(), d) + ')', el);
|
|
81195
|
+
}
|
|
81196
|
+
} else {
|
|
81197
|
+
view.board.highlightCustomInfobox('(' + x + ', ' + y + ')', el);
|
|
81198
|
+
}
|
|
81199
|
+
};
|
|
81200
|
+
|
|
81201
|
+
return view;
|
|
81202
|
+
};
|
|
81203
|
+
JXG.registerElement('view3d', ThreeD.createView3D);
|
|
81204
|
+
|
|
81205
|
+
return ThreeD.View3D;
|
|
81206
|
+
});
|
|
81207
|
+
|
|
81208
|
+
|
|
81209
|
+
/*
|
|
81210
|
+
Copyright 2008-2022
|
|
81211
|
+
Matthias Ehmann,
|
|
81212
|
+
Carsten Miller,
|
|
81213
|
+
Andreas Walter,
|
|
81214
|
+
Alfred Wassermann
|
|
81215
|
+
|
|
81216
|
+
This file is part of JSXGraph.
|
|
81217
|
+
|
|
81218
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
81219
|
+
|
|
81220
|
+
You can redistribute it and/or modify it under the terms of the
|
|
81221
|
+
|
|
81222
|
+
* GNU Lesser General Public License as published by
|
|
81223
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
81224
|
+
(at your option) any later version
|
|
81225
|
+
OR
|
|
81226
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
81227
|
+
|
|
81228
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
81229
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
81230
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
81231
|
+
GNU Lesser General Public License for more details.
|
|
81232
|
+
|
|
81233
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
81234
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
81235
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
81236
|
+
*/
|
|
81237
|
+
/*global JXG:true, define: true*/
|
|
81238
|
+
|
|
81239
|
+
/**
|
|
81240
|
+
* Create axes and rear and front walls of the
|
|
81241
|
+
* view3d bounding box bbox3d.
|
|
81242
|
+
*/
|
|
81243
|
+
define('3d/box3d',['jxg', 'utils/type', 'math/math', 'math/geometry', '3d/view3d'
|
|
81244
|
+
], function (JXG, Type, Mat, Geometry, ThreeD) {
|
|
81245
|
+
"use strict";
|
|
81246
|
+
|
|
81247
|
+
ThreeD.createAxes = function (board, parents, attributes) {
|
|
81248
|
+
var view = parents[0],
|
|
81249
|
+
i, j, k, i1, i2,
|
|
81250
|
+
attr,
|
|
81251
|
+
pos,
|
|
81252
|
+
directions = ['x', 'y', 'z'],
|
|
81253
|
+
suffixAxis = 'Axis',
|
|
81254
|
+
dir, dir1,
|
|
81255
|
+
sides = ['Rear', 'Front'],
|
|
81256
|
+
rear = [0, 0, 0], // x, y, z
|
|
81257
|
+
front = [0, 0, 0], // x, y, z
|
|
81258
|
+
from, to,
|
|
81259
|
+
vec1, vec2, range1, range2,
|
|
81260
|
+
na, na_parent,
|
|
81261
|
+
ticks_attr,
|
|
81262
|
+
axes = {};
|
|
81263
|
+
|
|
81264
|
+
if (Type.exists(view.D3)) {
|
|
81265
|
+
for (i = 0; i < directions.length; i++) {
|
|
81266
|
+
rear[i] = view.D3.bbox3d[i][0];
|
|
81267
|
+
front[i] = view.D3.bbox3d[i][1];
|
|
81268
|
+
}
|
|
81269
|
+
} else {
|
|
81270
|
+
for (i = 0; i < directions.length; i++) {
|
|
81271
|
+
rear[i] = parents[1][i];
|
|
81272
|
+
front[i] = parents[2][1];
|
|
81273
|
+
}
|
|
81274
|
+
}
|
|
81275
|
+
|
|
81276
|
+
// Main 3D axes
|
|
81277
|
+
attr = Type.copyAttributes(attributes, board.options, 'axes3d');
|
|
81278
|
+
pos = attr.axesposition;
|
|
81279
|
+
for (i = 0; i < directions.length; i++) {
|
|
81280
|
+
// Run through ['x', 'y', 'z']
|
|
81281
|
+
dir = directions[i];
|
|
81282
|
+
na = dir + suffixAxis;
|
|
81283
|
+
|
|
81284
|
+
if (pos === 'center') { // Axes centered
|
|
81285
|
+
from = [0, 0, 0];
|
|
81286
|
+
to = [0, 0, 0];
|
|
81287
|
+
to[i] = front[i];
|
|
81288
|
+
axes[na] = view.create('axis3d', [from, to], attr[na.toLowerCase()]);
|
|
81289
|
+
} else {
|
|
81290
|
+
na += 'Border'; // Axes bordered
|
|
81291
|
+
from = rear.slice();
|
|
81292
|
+
to = front.slice();
|
|
81293
|
+
if (i === 2) {
|
|
81294
|
+
from[1] = front[1];
|
|
81295
|
+
to[0] = rear[0];
|
|
81296
|
+
} else {
|
|
81297
|
+
from[i] = front[i];
|
|
81298
|
+
to[2] = rear[2];
|
|
81299
|
+
}
|
|
81300
|
+
to[i] = front[i];
|
|
81301
|
+
attr[na.toLowerCase()].lastArrow = false;
|
|
81302
|
+
axes[na] = view.create('axis3d', [from, to], attr[na.toLowerCase()]);
|
|
81303
|
+
|
|
81304
|
+
// TODO
|
|
81305
|
+
ticks_attr = {
|
|
81306
|
+
visible: true, // Für z-Ticks wird path nicht berechnet
|
|
81307
|
+
minorTicks: 0,
|
|
81308
|
+
tickEndings: [0, 1],
|
|
81309
|
+
drawLabels: false
|
|
81310
|
+
};
|
|
81311
|
+
if (i === 2) {
|
|
81312
|
+
ticks_attr.tickEndings = [1, 0];
|
|
81313
|
+
}
|
|
81314
|
+
axes[na + 'Ticks'] = view.create('ticks', [axes[na], 1], ticks_attr);
|
|
81315
|
+
}
|
|
81316
|
+
}
|
|
81317
|
+
|
|
81318
|
+
// Origin (2D point)
|
|
81319
|
+
axes.O = board.create('intersection', [
|
|
81320
|
+
axes[directions[0] + suffixAxis],
|
|
81321
|
+
axes[directions[1] + suffixAxis]
|
|
81322
|
+
], {
|
|
81323
|
+
name: '', visible: false, withLabel: false
|
|
81324
|
+
});
|
|
81325
|
+
|
|
81326
|
+
// Front and rear planes
|
|
81327
|
+
for (i = 0; i < directions.length; i++) {
|
|
81328
|
+
// Run through ['x', 'y', 'z']
|
|
81329
|
+
i1 = (i + 1) % 3;
|
|
81330
|
+
i2 = (i + 2) % 3;
|
|
81331
|
+
|
|
81332
|
+
dir = directions[i];
|
|
81333
|
+
for (j = 0; j < sides.length; j++) {
|
|
81334
|
+
// Run through ['Rear', 'Front']
|
|
81335
|
+
|
|
81336
|
+
from = [0, 0, 0];
|
|
81337
|
+
from[i] = (j === 0) ? rear[i] : front[i];
|
|
81338
|
+
vec1 = [0, 0, 0];
|
|
81339
|
+
vec2 = [0, 0, 0];
|
|
81340
|
+
vec1[i1] = 1;
|
|
81341
|
+
vec2[i2] = 1;
|
|
81342
|
+
range1 = [rear[i1], front[i1]];
|
|
81343
|
+
range2 = [rear[i2], front[i2]];
|
|
81344
|
+
na = dir + 'Plane' + sides[j];
|
|
81345
|
+
|
|
81346
|
+
attr = Type.copyAttributes(attributes, board.options, 'axes3d', na);
|
|
81347
|
+
axes[na] =
|
|
81348
|
+
view.create('plane3d', [from, vec1, vec2, range1, range2], attr);
|
|
81349
|
+
axes[na].D3.elType = 'axisplane3d';
|
|
81350
|
+
}
|
|
81351
|
+
}
|
|
81352
|
+
|
|
81353
|
+
// Axes on front and rear planes
|
|
81354
|
+
for (i = 0; i < directions.length; i++) {
|
|
81355
|
+
// Run through ['x', 'y', 'z']
|
|
81356
|
+
dir = directions[i];
|
|
81357
|
+
for (j = 0; j < sides.length; j++) {
|
|
81358
|
+
for (k = 1; k <= 2; k++) {
|
|
81359
|
+
i1 = (i + k) % 3;
|
|
81360
|
+
dir1 = directions[i1];
|
|
81361
|
+
na = dir + 'Plane' + sides[j] + dir1.toUpperCase() + 'Axis';
|
|
81362
|
+
na_parent = dir + 'Plane' + sides[j];
|
|
81363
|
+
|
|
81364
|
+
from = [0, 0, 0];
|
|
81365
|
+
to = [0, 0, 0];
|
|
81366
|
+
from[i] = to[i] = (j === 0) ? rear[i] : front[i];
|
|
81367
|
+
|
|
81368
|
+
from[i1] = rear[i1];
|
|
81369
|
+
to[i1] = front[i1];
|
|
81370
|
+
|
|
81371
|
+
attr = Type.copyAttributes(attributes, board.options, 'axes3d', na);
|
|
81372
|
+
axes[na] = view.create('axis3d', [from, to], attr);
|
|
81373
|
+
axes[na_parent].addChild(axes[na]);
|
|
81374
|
+
axes[na_parent].inherits.push(axes[na]);
|
|
81375
|
+
}
|
|
81376
|
+
}
|
|
81377
|
+
}
|
|
81378
|
+
|
|
81379
|
+
return axes;
|
|
81380
|
+
};
|
|
81381
|
+
JXG.registerElement('axes3d', ThreeD.createAxes);
|
|
81382
|
+
|
|
81383
|
+
ThreeD.createAxis = function (board, parents, attributes) {
|
|
81384
|
+
var view = parents[0],
|
|
81385
|
+
attr,
|
|
81386
|
+
start = parents[1],
|
|
81387
|
+
end = parents[2],
|
|
81388
|
+
el_start, el_end, el;
|
|
81389
|
+
|
|
81390
|
+
// Use 2D points to create axis
|
|
81391
|
+
attr = Type.copyAttributes(attributes.point1, board.options, 'axis3d', 'point1');
|
|
81392
|
+
el_start = board.create('point', [
|
|
81393
|
+
(function (xx, yy, zz) {
|
|
81394
|
+
return function () { return view.project3DTo2D(xx, yy, zz)[1]; };
|
|
81395
|
+
})(start[0], start[1], start[2]),
|
|
81396
|
+
(function (xx, yy, zz) {
|
|
81397
|
+
return function () { return view.project3DTo2D(xx, yy, zz)[2]; };
|
|
81398
|
+
})(start[0], start[1], start[2])
|
|
81399
|
+
], attr);
|
|
81400
|
+
|
|
81401
|
+
attr = Type.copyAttributes(attributes.point2, board.options, 'axis3d', 'point2');
|
|
81402
|
+
el_end = board.create('point', [
|
|
81403
|
+
(function (xx, yy, zz) {
|
|
81404
|
+
return function () { return view.project3DTo2D(xx, yy, zz)[1]; };
|
|
81405
|
+
})(end[0], end[1], end[2]),
|
|
81406
|
+
(function (xx, yy, zz) {
|
|
81407
|
+
return function () { return view.project3DTo2D(xx, yy, zz)[2]; };
|
|
81408
|
+
})(end[0], end[1], end[2])
|
|
81409
|
+
], attr);
|
|
81410
|
+
|
|
81411
|
+
attr = Type.copyAttributes(attributes, board.options, 'axis3d');
|
|
81412
|
+
el = board.create('arrow', [el_start, el_end], attr);
|
|
81413
|
+
|
|
81414
|
+
return el;
|
|
81415
|
+
};
|
|
81416
|
+
JXG.registerElement('axis3d', ThreeD.createAxis);
|
|
81417
|
+
|
|
81418
|
+
ThreeD.createMesh = function (board, parents, attr) {
|
|
81419
|
+
var view = parents[0],
|
|
81420
|
+
point = parents[1],
|
|
81421
|
+
vec1 = parents[2],
|
|
81422
|
+
range1 = parents[3],
|
|
81423
|
+
vec2 = parents[4],
|
|
81424
|
+
range2 = parents[5],
|
|
81425
|
+
el;
|
|
81426
|
+
|
|
81427
|
+
el = board.create('curve', [[], []], attr);
|
|
81428
|
+
el.updateDataArray = function () {
|
|
81429
|
+
var s1 = range1[0],
|
|
81430
|
+
e1 = range1[1],
|
|
81431
|
+
s2 = range2[0],
|
|
81432
|
+
e2 = range2[1],
|
|
81433
|
+
l1, l2, res, i, sol,
|
|
81434
|
+
v1 = [0, 0, 0],
|
|
81435
|
+
v2 = [0, 0, 0],
|
|
81436
|
+
step = 1,
|
|
81437
|
+
q = [0, 0, 0];
|
|
81438
|
+
|
|
81439
|
+
this.dataX = [];
|
|
81440
|
+
this.dataY = [];
|
|
81441
|
+
|
|
81442
|
+
for (i = 0; i < 3; i++) {
|
|
81443
|
+
q[i] = Type.evaluate(point[i]);
|
|
81444
|
+
v1[i] = Type.evaluate(vec1[i]);
|
|
81445
|
+
v2[i] = Type.evaluate(vec2[i]);
|
|
81446
|
+
}
|
|
81447
|
+
l1 = JXG.Math.norm(v1, 3);
|
|
81448
|
+
l2 = JXG.Math.norm(v2, 3);
|
|
81449
|
+
for (i = 0; i < 3; i++) {
|
|
81450
|
+
v1[i] /= l1;
|
|
81451
|
+
v2[i] /= l2;
|
|
81452
|
+
}
|
|
81453
|
+
if (false) {
|
|
81454
|
+
sol = Mat.Geometry.getPlaneBounds(v1, v2, q, s1, e1);
|
|
81455
|
+
if (sol !== null) {
|
|
81456
|
+
s1 = sol[0];
|
|
81457
|
+
e1 = sol[1];
|
|
81458
|
+
s2 = sol[2];
|
|
81459
|
+
e2 = sol[3];
|
|
81460
|
+
}
|
|
81461
|
+
}
|
|
81462
|
+
|
|
81463
|
+
res = view.getMesh(
|
|
81464
|
+
function(u, v) { return q[0] + u * v1[0] + v * v2[0]; },
|
|
81465
|
+
function(u, v) { return q[1] + u * v1[1] + v * v2[1]; },
|
|
81466
|
+
function(u, v) { return q[2] + u * v1[2] + v * v2[2]; },
|
|
81467
|
+
[Math.ceil(s1), Math.floor(e1), (Math.ceil(e1) - Math.floor(s1)) / step],
|
|
81468
|
+
[Math.ceil(s2), Math.floor(e2), (Math.ceil(e2) - Math.floor(s2)) / step]);
|
|
81469
|
+
this.dataX = res[0];
|
|
81470
|
+
this.dataY = res[1];
|
|
81471
|
+
};
|
|
81472
|
+
return el;
|
|
81473
|
+
};
|
|
81474
|
+
JXG.registerElement('mesh3d', ThreeD.createMesh);
|
|
81475
|
+
|
|
81476
|
+
});
|
|
81477
|
+
/*
|
|
81478
|
+
Copyright 2008-2022
|
|
81479
|
+
Matthias Ehmann,
|
|
81480
|
+
Carsten Miller,
|
|
81481
|
+
Andreas Walter,
|
|
81482
|
+
Alfred Wassermann
|
|
81483
|
+
|
|
81484
|
+
This file is part of JSXGraph.
|
|
81485
|
+
|
|
81486
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
81487
|
+
|
|
81488
|
+
You can redistribute it and/or modify it under the terms of the
|
|
81489
|
+
|
|
81490
|
+
* GNU Lesser General Public License as published by
|
|
81491
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
81492
|
+
(at your option) any later version
|
|
81493
|
+
OR
|
|
81494
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
81495
|
+
|
|
81496
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
81497
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
81498
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
81499
|
+
GNU Lesser General Public License for more details.
|
|
81500
|
+
|
|
81501
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
81502
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
81503
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
81504
|
+
*/
|
|
81505
|
+
/*global JXG:true, define: true*/
|
|
81506
|
+
|
|
81507
|
+
define('3d/curve3d',['jxg', 'utils/type', '3d/view3d'
|
|
81508
|
+
], function (JXG, Type, ThreeD) {
|
|
81509
|
+
"use strict";
|
|
81510
|
+
|
|
81511
|
+
ThreeD.createCurve = function (board, parents, attr) {
|
|
81512
|
+
var view = parents[0],
|
|
81513
|
+
D3, el;
|
|
81514
|
+
|
|
81515
|
+
D3 = {
|
|
81516
|
+
elType: 'curve3D',
|
|
81517
|
+
X: parents[1],
|
|
81518
|
+
Y: parents[2],
|
|
81519
|
+
Z: parents[3],
|
|
81520
|
+
};
|
|
81521
|
+
D3.F = [D3.X, D3.Y, D3.Z];
|
|
81522
|
+
|
|
81523
|
+
el = board.create('curve', [[], []], attr);
|
|
81524
|
+
el.D3 = D3;
|
|
81525
|
+
|
|
81526
|
+
if (Type.isFunction(el.D3.X)) {
|
|
81527
|
+
// 3D curve given as t -> [X(t), Y(t), Z(t)]
|
|
81528
|
+
|
|
81529
|
+
el.D3.range = parents[4];
|
|
81530
|
+
el.updateDataArray = function () {
|
|
81531
|
+
var steps = Type.evaluate(this.visProp.numberpointshigh),
|
|
81532
|
+
s = Type.evaluate(this.D3.range[0]),
|
|
81533
|
+
e = Type.evaluate(this.D3.range[1]),
|
|
81534
|
+
delta = (e - s) / (steps - 1),
|
|
81535
|
+
c2d, t, i,
|
|
81536
|
+
p = [0, 0, 0];
|
|
81537
|
+
|
|
81538
|
+
this.dataX = [];
|
|
81539
|
+
this.dataY = [];
|
|
81540
|
+
|
|
81541
|
+
for (t = s; t <= e; t += delta) {
|
|
81542
|
+
for (i = 0; i < 3; i++) {
|
|
81543
|
+
p[i] = this.D3.F[i](t);
|
|
81544
|
+
}
|
|
81545
|
+
c2d = view.project3DTo2D(p);
|
|
81546
|
+
this.dataX.push(c2d[1]);
|
|
81547
|
+
this.dataY.push(c2d[2]);
|
|
81548
|
+
}
|
|
81549
|
+
};
|
|
81550
|
+
} else if (Type.isArray(el.D3.X)) {
|
|
81551
|
+
// 3D curve given as array of 3D points
|
|
81552
|
+
|
|
81553
|
+
el.updateDataArray = function () {
|
|
81554
|
+
var i,
|
|
81555
|
+
le = this.D3.X.length,
|
|
81556
|
+
c2d;
|
|
81557
|
+
|
|
81558
|
+
this.dataX = [];
|
|
81559
|
+
this.dataY = [];
|
|
81560
|
+
|
|
81561
|
+
for (i = 0; i < le; i++) {
|
|
81562
|
+
c2d = view.project3DTo2D([this.D3.X[i], this.D3.Y[i], this.D3.Z[i]]);
|
|
81563
|
+
this.dataX.push(c2d[1]);
|
|
81564
|
+
this.dataY.push(c2d[2]);
|
|
81565
|
+
}
|
|
81566
|
+
};
|
|
81567
|
+
}
|
|
81568
|
+
|
|
81569
|
+
return el;
|
|
81570
|
+
};
|
|
81571
|
+
JXG.registerElement('curve3d', ThreeD.createCurve);
|
|
81572
|
+
|
|
81573
|
+
});
|
|
81574
|
+
/*
|
|
81575
|
+
Copyright 2008-2022
|
|
81576
|
+
Matthias Ehmann,
|
|
81577
|
+
Carsten Miller,
|
|
81578
|
+
Andreas Walter,
|
|
81579
|
+
Alfred Wassermann
|
|
81580
|
+
|
|
81581
|
+
This file is part of JSXGraph.
|
|
81582
|
+
|
|
81583
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
81584
|
+
|
|
81585
|
+
You can redistribute it and/or modify it under the terms of the
|
|
81586
|
+
|
|
81587
|
+
* GNU Lesser General Public License as published by
|
|
81588
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
81589
|
+
(at your option) any later version
|
|
81590
|
+
OR
|
|
81591
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
81592
|
+
|
|
81593
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
81594
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
81595
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
81596
|
+
GNU Lesser General Public License for more details.
|
|
81597
|
+
|
|
81598
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
81599
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
81600
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
81601
|
+
*/
|
|
81602
|
+
/*global JXG:true, define: true*/
|
|
81603
|
+
|
|
81604
|
+
/**
|
|
81605
|
+
* Create linear spaces of dimension at least one,
|
|
81606
|
+
* i.e. lines and planes.
|
|
81607
|
+
*/
|
|
81608
|
+
define('3d/linspace3d',['jxg', 'utils/type', 'math/math', 'math/geometry', '3d/view3d'
|
|
81609
|
+
], function (JXG, Type, Mat, Geometry, ThreeD) {
|
|
81610
|
+
"use strict";
|
|
81611
|
+
|
|
81612
|
+
/**
|
|
81613
|
+
* @class This element is used to provide a constructor for a 3D line.
|
|
81614
|
+
* @pseudo
|
|
81615
|
+
* @description There are two possibilities to create a Line3D object.
|
|
81616
|
+
* <p>
|
|
81617
|
+
* First: the line in 3D is defined by two points in 3D (Point3D).
|
|
81618
|
+
* The points can be either existing points or coordinate arrays of
|
|
81619
|
+
* the form [x, y, z].
|
|
81620
|
+
* <p>Second: the line in 3D is defined by a point (or coordinate array [x, y, z])
|
|
81621
|
+
* a direction given as array [x, y, z] and an optional range
|
|
81622
|
+
* given as array [s, e]. The default value for the range is [-Infinity, Infinity].
|
|
81623
|
+
* <p>
|
|
81624
|
+
* All numbers can also be provided as functions returning a number.
|
|
81625
|
+
*
|
|
81626
|
+
* @name Line3D
|
|
81627
|
+
* @augments JXG.Curve
|
|
81628
|
+
* @constructor
|
|
81629
|
+
* @type JXG.Curve
|
|
81630
|
+
* @throws {Exception} If the element cannot be constructed with the given parent
|
|
81631
|
+
* objects an exception is thrown.
|
|
81632
|
+
* @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
|
|
81633
|
+
* 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
|
|
81634
|
+
* line will determine the radius), or another {@link JXG.Circle}.
|
|
81635
|
+
*
|
|
81636
|
+
*/
|
|
81637
|
+
ThreeD.createLine = function (board, parents, attributes) {
|
|
81638
|
+
var view = parents[0],
|
|
81639
|
+
attr, D3, point, point1, point2,
|
|
81640
|
+
el;
|
|
81641
|
+
|
|
81642
|
+
// Range
|
|
81643
|
+
D3 = {
|
|
81644
|
+
elType: 'line3d',
|
|
81645
|
+
range: parents[3] || [-Infinity, Infinity]
|
|
81646
|
+
};
|
|
81647
|
+
|
|
81648
|
+
// Point
|
|
81649
|
+
if (Type.isPoint(parents[1])) {
|
|
81650
|
+
point = parents[1];
|
|
81651
|
+
} else {
|
|
81652
|
+
point = view.create('point3d', parents[1], { visible: false, name: '', withLabel: false });
|
|
81653
|
+
}
|
|
81654
|
+
D3.point = point;
|
|
81655
|
+
|
|
81656
|
+
// Direction
|
|
81657
|
+
if (Type.isPoint(parents[2]) && Type.exists(parents[2].D3)) {
|
|
81658
|
+
// Line defined by two points
|
|
81659
|
+
|
|
81660
|
+
point1 = point;
|
|
81661
|
+
point2 = parents[2];
|
|
81662
|
+
D3.direction = function () {
|
|
81663
|
+
return [
|
|
81664
|
+
point2.D3.X() - point.D3.X(),
|
|
81665
|
+
point2.D3.Y() - point.D3.Y(),
|
|
81666
|
+
point2.D3.Z() - point.D3.Z()
|
|
81667
|
+
];
|
|
81668
|
+
};
|
|
81669
|
+
D3.range = [0, 1];
|
|
81670
|
+
} else {
|
|
81671
|
+
// Line defined by point, direction and range
|
|
81672
|
+
|
|
81673
|
+
// Directions are handled as arrays of length 4,
|
|
81674
|
+
// i.e. with homogeneous coordinates.
|
|
81675
|
+
if (Type.isFunction(parents[2])) {
|
|
81676
|
+
D3.direction = parents[2];
|
|
81677
|
+
} else if (parents[2].length === 3) {
|
|
81678
|
+
D3.direction = [1].concat(parents[2]);
|
|
81679
|
+
} else if (parents[2].length === 4) {
|
|
81680
|
+
D3.direction = parents[2];
|
|
81681
|
+
} else {
|
|
81682
|
+
// Throw error
|
|
81683
|
+
}
|
|
81684
|
+
|
|
81685
|
+
// Direction given as array
|
|
81686
|
+
D3.getPointCoords = function (r) {
|
|
81687
|
+
var p = [],
|
|
81688
|
+
d = [],
|
|
81689
|
+
i;
|
|
81690
|
+
|
|
81691
|
+
p.push(point.D3.X());
|
|
81692
|
+
p.push(point.D3.Y());
|
|
81693
|
+
p.push(point.D3.Z());
|
|
81694
|
+
|
|
81695
|
+
if (Type.isFunction(D3.direction)) {
|
|
81696
|
+
d = D3.direction();
|
|
81697
|
+
} else {
|
|
81698
|
+
for (i = 1; i < 4; i++) {
|
|
81699
|
+
d.push(Type.evaluate(D3.direction[i]));
|
|
81700
|
+
}
|
|
81701
|
+
}
|
|
81702
|
+
if (Math.abs(r) === Infinity) {
|
|
81703
|
+
r = view.intersectionLineCube(p, d, r);
|
|
81704
|
+
}
|
|
81705
|
+
return [
|
|
81706
|
+
p[0] + d[0] * r,
|
|
81707
|
+
p[1] + d[1] * r,
|
|
81708
|
+
p[2] + d[2] * r
|
|
81709
|
+
];
|
|
81710
|
+
|
|
81711
|
+
};
|
|
81712
|
+
|
|
81713
|
+
attr = Type.copyAttributes(attributes, board.options, 'line3d', 'point1');
|
|
81714
|
+
point1 = view.create('point3d', [
|
|
81715
|
+
function () {
|
|
81716
|
+
return D3.getPointCoords(Type.evaluate(D3.range[0]));
|
|
81717
|
+
}
|
|
81718
|
+
], attr);
|
|
81719
|
+
attr = Type.copyAttributes(attributes, board.options, 'line3d', 'point2');
|
|
81720
|
+
point2 = view.create('point3d', [
|
|
81721
|
+
function () {
|
|
81722
|
+
return D3.getPointCoords(Type.evaluate(D3.range[1]));
|
|
81723
|
+
}
|
|
81724
|
+
], attr);
|
|
81725
|
+
}
|
|
81726
|
+
|
|
81727
|
+
attr = Type.copyAttributes(attributes, board.options, 'line3d');
|
|
81728
|
+
el = view.create('segment', [point1, point2], attr);
|
|
81729
|
+
el.point1 = point1;
|
|
81730
|
+
el.point2 = point2;
|
|
81731
|
+
point1.addChild(el);
|
|
81732
|
+
point2.addChild(el);
|
|
81733
|
+
el.D3 = D3;
|
|
81734
|
+
|
|
81735
|
+
return el;
|
|
81736
|
+
};
|
|
81737
|
+
JXG.registerElement('line3d', ThreeD.createLine);
|
|
81738
|
+
|
|
81739
|
+
ThreeD.createPlane = function (board, parents, attributes) {
|
|
81740
|
+
var view = parents[0],
|
|
81741
|
+
attr, D3,
|
|
81742
|
+
point,
|
|
81743
|
+
vec1 = parents[2],
|
|
81744
|
+
vec2 = parents[3],
|
|
81745
|
+
el, grid, update;
|
|
81746
|
+
|
|
81747
|
+
// D3: {
|
|
81748
|
+
// point,
|
|
81749
|
+
// vec1,
|
|
81750
|
+
// vec2,
|
|
81751
|
+
// poin1,
|
|
81752
|
+
// point2,
|
|
81753
|
+
// normal array of len 3
|
|
81754
|
+
// d
|
|
81755
|
+
// }
|
|
81756
|
+
D3 = {
|
|
81757
|
+
elType: 'plane3d',
|
|
81758
|
+
dir1: [],
|
|
81759
|
+
dir2: [],
|
|
81760
|
+
range1: parents[4],
|
|
81761
|
+
range2: parents[5],
|
|
81762
|
+
vec1: vec1,
|
|
81763
|
+
vec2: vec2
|
|
81764
|
+
};
|
|
81765
|
+
|
|
81766
|
+
if (Type.isPoint(parents[1])) {
|
|
81767
|
+
point = parents[1];
|
|
81768
|
+
} else {
|
|
81769
|
+
point = view.create('point3d', parents[1], { visible: false, name: '', withLabel: false });
|
|
81770
|
+
}
|
|
81771
|
+
D3.point = point;
|
|
81772
|
+
|
|
81773
|
+
D3.updateNormal = function () {
|
|
81774
|
+
var i;
|
|
81775
|
+
for (i = 0; i < 3; i++) {
|
|
81776
|
+
D3.dir1[i] = Type.evaluate(D3.vec1[i]);
|
|
81777
|
+
D3.dir2[i] = Type.evaluate(D3.vec2[i]);
|
|
81778
|
+
}
|
|
81779
|
+
D3.normal = Mat.crossProduct(D3.dir1, D3.dir2);
|
|
81780
|
+
D3.d = Mat.innerProduct(D3.point.D3.coords.slice(1), D3.normal, 3);
|
|
81781
|
+
};
|
|
81782
|
+
D3.updateNormal();
|
|
81783
|
+
|
|
81784
|
+
attr = Type.copyAttributes(attributes, board.options, 'plane3d');
|
|
81785
|
+
el = board.create('curve', [[], []], attr);
|
|
81786
|
+
el.D3 = D3;
|
|
81787
|
+
|
|
81788
|
+
el.updateDataArray = function () {
|
|
81789
|
+
var s1, e1, s2, e2,
|
|
81790
|
+
c2d, l1, l2,
|
|
81791
|
+
planes = ['xPlaneRear', 'yPlaneRear', 'zPlaneRear'],
|
|
81792
|
+
points = [],
|
|
81793
|
+
v1 = [0, 0, 0],
|
|
81794
|
+
v2 = [0, 0, 0],
|
|
81795
|
+
q = [0, 0, 0],
|
|
81796
|
+
p = [0, 0, 0], d, i, j, a, b, first, pos, pos_akt;
|
|
81797
|
+
|
|
81798
|
+
this.dataX = [];
|
|
81799
|
+
this.dataY = [];
|
|
81800
|
+
|
|
81801
|
+
this.D3.updateNormal();
|
|
81802
|
+
|
|
81803
|
+
// Infinite plane
|
|
81804
|
+
if (this.D3.elType !== 'axisplane3d' && view.defaultAxes &&
|
|
81805
|
+
(!D3.range1 || !D3.range2)
|
|
81806
|
+
) {
|
|
81807
|
+
|
|
81808
|
+
// Start with the rear plane.
|
|
81809
|
+
// Determine the intersections with the view bbox3d
|
|
81810
|
+
// For each face of the bbox3d we determine two points
|
|
81811
|
+
// which are the ends of the intersection line.
|
|
81812
|
+
// We start with the three rear planes.
|
|
81813
|
+
for (j = 0; j < planes.length; j++) {
|
|
81814
|
+
p = view.intersectionPlanePlane(this, view.defaultAxes[planes[j]]);
|
|
81815
|
+
|
|
81816
|
+
if (p[0].length === 3 && p[1].length === 3) {
|
|
81817
|
+
// This test is necessary to filter out intersection lines which are
|
|
81818
|
+
// identical to intersections of axis planes (they would occur twice).
|
|
81819
|
+
for (i = 0; i < points.length; i++) {
|
|
81820
|
+
if ((Geometry.distance(p[0], points[i][0], 3) < Mat.eps && Geometry.distance(p[1], points[i][1], 3) < Mat.eps) ||
|
|
81821
|
+
(Geometry.distance(p[0], points[i][1], 3) < Mat.eps && Geometry.distance(p[1], points[i][0], 3) < Mat.eps)) {
|
|
81822
|
+
break;
|
|
81823
|
+
}
|
|
81824
|
+
}
|
|
81825
|
+
if (i === points.length) {
|
|
81826
|
+
points.push(p.slice());
|
|
81827
|
+
}
|
|
81828
|
+
}
|
|
81829
|
+
|
|
81830
|
+
// Point on the front plane of the bbox3d
|
|
81831
|
+
p = [0, 0, 0];
|
|
81832
|
+
p[j] = view.D3.bbox3d[j][1];
|
|
81833
|
+
|
|
81834
|
+
// d is the rhs of the Hesse normal form of the front plane.
|
|
81835
|
+
d = Mat.innerProduct(p, view.defaultAxes[planes[j]].D3.normal, 3);
|
|
81836
|
+
p = view.intersectionPlanePlane(this, view.defaultAxes[planes[j]], d);
|
|
81837
|
+
|
|
81838
|
+
if (p[0].length === 3 && p[1].length === 3) {
|
|
81839
|
+
// Do the same test as above
|
|
81840
|
+
for (i = 0; i < points.length; i++) {
|
|
81841
|
+
if ((Geometry.distance(p[0], points[i][0], 3) < Mat.eps && Geometry.distance(p[1], points[i][1], 3) < Mat.eps) ||
|
|
81842
|
+
(Geometry.distance(p[0], points[i][1], 3) < Mat.eps && Geometry.distance(p[1], points[i][0], 3) < Mat.eps)) {
|
|
81843
|
+
break;
|
|
81844
|
+
}
|
|
81845
|
+
}
|
|
81846
|
+
if (i === points.length) {
|
|
81847
|
+
points.push(p.slice());
|
|
81848
|
+
}
|
|
81849
|
+
}
|
|
81850
|
+
}
|
|
81851
|
+
|
|
81852
|
+
// Concatenate the intersection points to a polygon.
|
|
81853
|
+
// If all wents well, each intersection should appear
|
|
81854
|
+
// twice in the list.
|
|
81855
|
+
first = 0;
|
|
81856
|
+
pos = first;
|
|
81857
|
+
i = 0;
|
|
81858
|
+
do {
|
|
81859
|
+
p = points[pos][i];
|
|
81860
|
+
if (p.length === 3) {
|
|
81861
|
+
c2d = view.project3DTo2D(p);
|
|
81862
|
+
this.dataX.push(c2d[1]);
|
|
81863
|
+
this.dataY.push(c2d[2]);
|
|
81864
|
+
}
|
|
81865
|
+
i = (i + 1) % 2;
|
|
81866
|
+
p = points[pos][i];
|
|
81867
|
+
|
|
81868
|
+
pos_akt = pos;
|
|
81869
|
+
for (j = 0; j < points.length; j++) {
|
|
81870
|
+
if (j !== pos && Geometry.distance(p, points[j][0]) < Mat.eps) {
|
|
81871
|
+
pos = j;
|
|
81872
|
+
i = 0;
|
|
81873
|
+
break;
|
|
81874
|
+
}
|
|
81875
|
+
if (j !== pos && Geometry.distance(p, points[j][1]) < Mat.eps) {
|
|
81876
|
+
pos = j;
|
|
81877
|
+
i = 1;
|
|
81878
|
+
break;
|
|
81879
|
+
}
|
|
81880
|
+
}
|
|
81881
|
+
if (pos === pos_akt) {
|
|
81882
|
+
console.log("Error: update plane3d: did not find next", pos);
|
|
81883
|
+
break;
|
|
81884
|
+
}
|
|
81885
|
+
} while (pos !== first);
|
|
81886
|
+
c2d = view.project3DTo2D(points[first][0]);
|
|
81887
|
+
this.dataX.push(c2d[1]);
|
|
81888
|
+
this.dataY.push(c2d[2]);
|
|
81889
|
+
|
|
81890
|
+
} else {
|
|
81891
|
+
// 3D bounded flat
|
|
81892
|
+
s1 = Type.evaluate(this.D3.range1[0]);
|
|
81893
|
+
e1 = Type.evaluate(this.D3.range1[1]);
|
|
81894
|
+
s2 = Type.evaluate(this.D3.range2[0]);
|
|
81895
|
+
e2 = Type.evaluate(this.D3.range2[1]);
|
|
81896
|
+
|
|
81897
|
+
q = this.D3.point.D3.coords.slice(1);
|
|
81898
|
+
|
|
81899
|
+
v1 = this.D3.dir1.slice();
|
|
81900
|
+
v2 = this.D3.dir2.slice();
|
|
81901
|
+
l1 = Mat.norm(v1, 3);
|
|
81902
|
+
l2 = Mat.norm(v2, 3);
|
|
81903
|
+
for (i = 0; i < 3; i++) {
|
|
81904
|
+
v1[i] /= l1;
|
|
81905
|
+
v2[i] /= l2;
|
|
81906
|
+
}
|
|
81907
|
+
|
|
81908
|
+
for (j = 0; j < 4; j++) {
|
|
81909
|
+
switch (j) {
|
|
81910
|
+
case 0: a = s1; b = s2; break;
|
|
81911
|
+
case 1: a = e1; b = s2; break;
|
|
81912
|
+
case 2: a = e1; b = e2; break;
|
|
81913
|
+
case 3: a = s1; b = e2;
|
|
81914
|
+
}
|
|
81915
|
+
for (i = 0; i < 3; i++) {
|
|
81916
|
+
p[i] = q[i] + a * v1[i] + b * v2[i];
|
|
81917
|
+
}
|
|
81918
|
+
c2d = view.project3DTo2D(p);
|
|
81919
|
+
this.dataX.push(c2d[1]);
|
|
81920
|
+
this.dataY.push(c2d[2]);
|
|
81921
|
+
}
|
|
81922
|
+
// Close the curve
|
|
81923
|
+
this.dataX.push(this.dataX[0]);
|
|
81924
|
+
this.dataY.push(this.dataY[0]);
|
|
81925
|
+
}
|
|
81926
|
+
};
|
|
81927
|
+
|
|
81928
|
+
attr = Type.copyAttributes(attributes.mesh3d, board.options, 'mesh3d');
|
|
81929
|
+
|
|
81930
|
+
if (D3.range1 && D3.range2) {
|
|
81931
|
+
grid = view.create('mesh3d', [point.D3.coords.slice(1), vec1, D3.range1, vec2, D3.range2], attr);
|
|
81932
|
+
el.grid = grid;
|
|
81933
|
+
el.inherits.push(grid);
|
|
81934
|
+
}
|
|
81935
|
+
|
|
81936
|
+
// update = el.update;
|
|
81937
|
+
// el.update = function () {
|
|
81938
|
+
// if (el.needsUpdate) {
|
|
81939
|
+
// update.apply(el);
|
|
81940
|
+
// }
|
|
81941
|
+
// return this;
|
|
81942
|
+
// };
|
|
81943
|
+
|
|
81944
|
+
return el;
|
|
81945
|
+
};
|
|
81946
|
+
JXG.registerElement('plane3d', ThreeD.createPlane);
|
|
81947
|
+
|
|
81948
|
+
});
|
|
81949
|
+
/*
|
|
81950
|
+
Copyright 2008-2022
|
|
81951
|
+
Matthias Ehmann,
|
|
81952
|
+
Carsten Miller,
|
|
81953
|
+
Andreas Walter,
|
|
81954
|
+
Alfred Wassermann
|
|
81955
|
+
|
|
81956
|
+
This file is part of JSXGraph.
|
|
81957
|
+
|
|
81958
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
81959
|
+
|
|
81960
|
+
You can redistribute it and/or modify it under the terms of the
|
|
81961
|
+
|
|
81962
|
+
* GNU Lesser General Public License as published by
|
|
81963
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
81964
|
+
(at your option) any later version
|
|
81965
|
+
OR
|
|
81966
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
81967
|
+
|
|
81968
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
81969
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
81970
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
81971
|
+
GNU Lesser General Public License for more details.
|
|
81972
|
+
|
|
81973
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
81974
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
81975
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
81976
|
+
*/
|
|
81977
|
+
/*global JXG:true, define: true*/
|
|
81978
|
+
|
|
81979
|
+
define('3d/point3d',['jxg', 'base/constants', 'math/math', 'math/geometry', 'utils/type', '3d/view3d'
|
|
81980
|
+
], function (JXG, Const, Mat, Geometry, Type, ThreeD) {
|
|
81981
|
+
"use strict";
|
|
81982
|
+
|
|
81983
|
+
/**
|
|
81984
|
+
* @class This element is used to provide a constructor for a 3D Point.
|
|
81985
|
+
* @pseudo
|
|
81986
|
+
* @description There are two possibilities to create a Line3D object.
|
|
81987
|
+
* <p>
|
|
81988
|
+
* First: the line in 3D is defined by two points in 3D (Point3D).
|
|
81989
|
+
* The points can be either existing points or coordinate arrays of
|
|
81990
|
+
* the form [x, y, z].
|
|
81991
|
+
* <p>Second: the line in 3D is defined by a point (or coordinate array [x, y, z])
|
|
81992
|
+
* a direction given as array [x, y, z] and an optional range
|
|
81993
|
+
* given as array [s, e]. The default value for the range is [-Infinity, Infinity].
|
|
81994
|
+
* <p>
|
|
81995
|
+
* All numbers can also be provided as functions returning a number.
|
|
81996
|
+
*
|
|
81997
|
+
* @name Point3D
|
|
81998
|
+
* @augments JXG.Point
|
|
81999
|
+
* @constructor
|
|
82000
|
+
* @type JXG.Point
|
|
82001
|
+
* @throws {Exception} If the element cannot be constructed with the given parent
|
|
82002
|
+
* objects an exception is thrown.
|
|
82003
|
+
* @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
|
|
82004
|
+
* 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
|
|
82005
|
+
* line will determine the radius), or another {@link JXG.Circle}.
|
|
82006
|
+
*
|
|
82007
|
+
*/
|
|
82008
|
+
ThreeD.createPoint = function (board, parents, attributes) {
|
|
82009
|
+
var view = parents[0],
|
|
82010
|
+
attr, update2D, D3,
|
|
82011
|
+
i, c2d,
|
|
82012
|
+
el;
|
|
82013
|
+
|
|
82014
|
+
attr = Type.copyAttributes(attributes, board.options, 'point3d');
|
|
82015
|
+
|
|
82016
|
+
D3 = {
|
|
82017
|
+
elType: 'point3d',
|
|
82018
|
+
coords: [1, 0, 0, 0],
|
|
82019
|
+
X: function () { return this.coords[1]; },
|
|
82020
|
+
Y: function () { return this.coords[2]; },
|
|
82021
|
+
Z: function () { return this.coords[3]; }
|
|
82022
|
+
};
|
|
82023
|
+
|
|
82024
|
+
// If the last element of partents is a 3D object, the point is a glider
|
|
82025
|
+
// on that element.
|
|
82026
|
+
if (parents.length > 2 && Type.exists(parents[parents.length - 1].D3)) {
|
|
82027
|
+
D3.slide = parents.pop();
|
|
82028
|
+
} else {
|
|
82029
|
+
D3.slide = null;
|
|
82030
|
+
}
|
|
82031
|
+
|
|
82032
|
+
if (parents.length === 2) {
|
|
82033
|
+
D3.F = parents[1]; // (Array [x, y, z] | function) returning [x, y, z]
|
|
82034
|
+
D3.coords = [1].concat(Type.evaluate(D3.F));
|
|
82035
|
+
} else if (parents.length === 4) {
|
|
82036
|
+
D3.F = parents.slice(1); // 3 numbers | functions
|
|
82037
|
+
for (i = 0; i < 3; i++) {
|
|
82038
|
+
D3.coords[i + 1] = Type.evaluate(D3.F[i]);
|
|
82039
|
+
}
|
|
82040
|
+
} else {
|
|
82041
|
+
// Throw error
|
|
82042
|
+
}
|
|
82043
|
+
|
|
82044
|
+
/**
|
|
82045
|
+
* Update the 4D coords array
|
|
82046
|
+
* @returns Object
|
|
82047
|
+
*/
|
|
82048
|
+
D3.updateCoords = function () {
|
|
82049
|
+
var res, i;
|
|
82050
|
+
if (Type.isFunction(this.F)) {
|
|
82051
|
+
res = Type.evaluate(this.F);
|
|
82052
|
+
this.coords = [1, res[0], res[1], res[2]];
|
|
82053
|
+
} else {
|
|
82054
|
+
this.coords[0] = 1;
|
|
82055
|
+
for (i = 0; i < 3; i++) {
|
|
82056
|
+
if (Type.isFunction(this.F[i])) {
|
|
82057
|
+
this.coords[i + 1] = Type.evaluate(this.F[i]);
|
|
82058
|
+
}
|
|
82059
|
+
}
|
|
82060
|
+
}
|
|
82061
|
+
return this;
|
|
82062
|
+
};
|
|
82063
|
+
D3.updateCoords();
|
|
82064
|
+
|
|
82065
|
+
c2d = view.project3DTo2D(D3.coords);
|
|
82066
|
+
el = board.create('point', c2d, attr);
|
|
82067
|
+
el.D3 = D3;
|
|
82068
|
+
el.D3.c2d = el.coords.usrCoords.slice(); // Copy of the coordinates to detect dragging
|
|
82069
|
+
update2D = el.update;
|
|
82070
|
+
|
|
82071
|
+
if (el.D3.slide) {
|
|
82072
|
+
el._minFunc = function (n, m, x, con) {
|
|
82073
|
+
var surface = el.D3.slide.D3,
|
|
82074
|
+
c3d = [1, surface.X(x[0], x[1]), surface.Y(x[0], x[1]), surface.Z(x[0], x[1])],
|
|
82075
|
+
c2d = view.project3DTo2D(c3d);
|
|
82076
|
+
|
|
82077
|
+
con[0] = el.X() - c2d[1];
|
|
82078
|
+
con[1] = el.Y() - c2d[2];
|
|
82079
|
+
|
|
82080
|
+
return con[0] * con[0] + con[1] * con[1];
|
|
82081
|
+
};
|
|
82082
|
+
|
|
82083
|
+
el.projectCoords2Surface = function () {
|
|
82084
|
+
var n = 2, // # of variables
|
|
82085
|
+
m = 2, // number of constraints
|
|
82086
|
+
x = [0, 0],
|
|
82087
|
+
// Various Cobyla constants, see Cobyla docs in Cobyja.js
|
|
82088
|
+
rhobeg = 5.0,
|
|
82089
|
+
rhoend = 1.0e-6,
|
|
82090
|
+
iprint = 0,
|
|
82091
|
+
maxfun = 200,
|
|
82092
|
+
surface = this.D3.slide.D3,
|
|
82093
|
+
r, c3d, c2d;
|
|
82094
|
+
|
|
82095
|
+
if (Type.exists(this.D3.params)) {
|
|
82096
|
+
x = this.D3.params.slice();
|
|
82097
|
+
}
|
|
82098
|
+
r = Mat.Nlp.FindMinimum(this._minFunc, n, m, x, rhobeg, rhoend, iprint, maxfun);
|
|
82099
|
+
|
|
82100
|
+
c3d = [1, surface.X(x[0], x[1]), surface.Y(x[0], x[1]), surface.Z(x[0], x[1])];
|
|
82101
|
+
c2d = view.project3DTo2D(c3d);
|
|
82102
|
+
this.D3.params = x;
|
|
82103
|
+
this.D3.coords = c3d;
|
|
82104
|
+
this.coords.setCoordinates(Const.COORDS_BY_USER, c2d);
|
|
82105
|
+
this.D3.c2d = c2d;
|
|
82106
|
+
};
|
|
82107
|
+
}
|
|
82108
|
+
|
|
82109
|
+
el.update = function (drag) {
|
|
82110
|
+
var c3d, foot;
|
|
82111
|
+
if (!this.needsUpdate) {
|
|
82112
|
+
return this;
|
|
82113
|
+
}
|
|
82114
|
+
|
|
82115
|
+
// Update is called in from two methods:
|
|
82116
|
+
// Once in setToPositionDirectly and
|
|
82117
|
+
// once in the subsequent board.update
|
|
82118
|
+
if (this.draggable() &&
|
|
82119
|
+
Geometry.distance(this.D3.c2d, this.coords.usrCoords) !== 0) {
|
|
82120
|
+
|
|
82121
|
+
if (this.D3.slide) {
|
|
82122
|
+
this.projectCoords2Surface();
|
|
82123
|
+
} else {
|
|
82124
|
+
// Drag the point in its xy plane
|
|
82125
|
+
foot = [1, 0, 0, this.D3.coords[3]];
|
|
82126
|
+
c3d = view.project2DTo3DPlane(el, [1, 0, 0, 1], foot);
|
|
82127
|
+
if (c3d[0] !== 0) {
|
|
82128
|
+
this.D3.coords = view.project3DToCube(c3d);
|
|
82129
|
+
}
|
|
82130
|
+
}
|
|
82131
|
+
} else {
|
|
82132
|
+
this.D3.updateCoords();
|
|
82133
|
+
// Update 2D point from its 3D view
|
|
82134
|
+
el.coords.setCoordinates(Const.COORDS_BY_USER,
|
|
82135
|
+
view.project3DTo2D([1, this.D3.X(), this.D3.Y(), this.D3.Z()])
|
|
82136
|
+
);
|
|
82137
|
+
}
|
|
82138
|
+
this.D3.c2d = el.coords.usrCoords.slice();
|
|
82139
|
+
|
|
82140
|
+
update2D.apply(this, [drag]);
|
|
82141
|
+
return this;
|
|
82142
|
+
};
|
|
82143
|
+
|
|
82144
|
+
el.normalizeCoords3D = function () {
|
|
82145
|
+
if (Math.abs(el.D3.coords[0]) > Mat.eps) {
|
|
82146
|
+
el.D3.coords[1] /= el.D3.coords[0];
|
|
82147
|
+
el.D3.coords[2] /= el.D3.coords[0];
|
|
82148
|
+
el.D3.coords[3] /= el.D3.coords[0];
|
|
82149
|
+
el.D3.coords[0] = 1.0;
|
|
82150
|
+
}
|
|
82151
|
+
return this;
|
|
82152
|
+
};
|
|
82153
|
+
|
|
82154
|
+
el.setPosition3D = function (coords, noevent) {
|
|
82155
|
+
var c = el.D3.coords,
|
|
82156
|
+
oc = el.D3.coords.slice(); // Copy of original values
|
|
82157
|
+
|
|
82158
|
+
if (coords.length === 3) { // Euclidean coordinates
|
|
82159
|
+
c[0] = 1.0;
|
|
82160
|
+
c[1] = coords[0];
|
|
82161
|
+
c[2] = coords[1];
|
|
82162
|
+
c[3] = coords[2];
|
|
82163
|
+
} else { // Homogeneous coordinates (normalized)
|
|
82164
|
+
c[0] = coords[0];
|
|
82165
|
+
c[1] = coords[1];
|
|
82166
|
+
c[2] = coords[2];
|
|
82167
|
+
el.normalizeCoords3D();
|
|
82168
|
+
}
|
|
82169
|
+
|
|
82170
|
+
// console.log(el.emitter, !noevent, oc[0] !== c[0] || oc[1] !== c[1] || oc[2] !== c[2] || oc[3] !== c[3]);
|
|
82171
|
+
// Not yet working
|
|
82172
|
+
if (el.emitter && !noevent &&
|
|
82173
|
+
(oc[0] !== c[0] || oc[1] !== c[1] || oc[2] !== c[2] || oc[3] !== c[3])) {
|
|
82174
|
+
this.triggerEventHandlers(['update3D'], [oc]);
|
|
82175
|
+
}
|
|
82176
|
+
return this;
|
|
82177
|
+
};
|
|
82178
|
+
|
|
82179
|
+
// Not yet working
|
|
82180
|
+
el.__evt__update3D = function (oc) { };
|
|
82181
|
+
|
|
82182
|
+
return el;
|
|
82183
|
+
};
|
|
82184
|
+
JXG.registerElement('point3d', ThreeD.createPoint);
|
|
82185
|
+
|
|
82186
|
+
});
|
|
82187
|
+
/*
|
|
82188
|
+
Copyright 2008-2022
|
|
82189
|
+
Matthias Ehmann,
|
|
82190
|
+
Carsten Miller,
|
|
82191
|
+
Andreas Walter,
|
|
82192
|
+
Alfred Wassermann
|
|
82193
|
+
|
|
82194
|
+
This file is part of JSXGraph.
|
|
82195
|
+
|
|
82196
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
82197
|
+
|
|
82198
|
+
You can redistribute it and/or modify it under the terms of the
|
|
82199
|
+
|
|
82200
|
+
* GNU Lesser General Public License as published by
|
|
82201
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
82202
|
+
(at your option) any later version
|
|
82203
|
+
OR
|
|
82204
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
82205
|
+
|
|
82206
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
82207
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
82208
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
82209
|
+
GNU Lesser General Public License for more details.
|
|
82210
|
+
|
|
82211
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
82212
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
82213
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
82214
|
+
*/
|
|
82215
|
+
/*global JXG:true, define: true*/
|
|
82216
|
+
|
|
82217
|
+
define('3d/surface3d',['jxg', 'utils/type', '3d/view3d'
|
|
82218
|
+
], function (JXG, Type, ThreeD) {
|
|
82219
|
+
"use strict";
|
|
82220
|
+
|
|
82221
|
+
|
|
82222
|
+
/**
|
|
82223
|
+
* @class This element creates a 3D parametric surface.
|
|
82224
|
+
* @pseudo
|
|
82225
|
+
* @description A 3D parametric surface is defined by a function
|
|
82226
|
+
* <i>F: R<sup>2</sup> → R<sup>3</sup></i>.
|
|
82227
|
+
*
|
|
82228
|
+
* @name ParametricSurface3D
|
|
82229
|
+
* @augments Curve
|
|
82230
|
+
* @constructor
|
|
82231
|
+
* @type Object
|
|
82232
|
+
* @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
82233
|
+
* @param {Function_Function_Function_Array_Array} F<sub>X</sub>,F<sub>Y</sub>,F<sub>Z</sub>,rangeX,rangeY
|
|
82234
|
+
* 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
|
|
82235
|
+
* lower and upper bound for the range of parameter u, rangeV is the array containing
|
|
82236
|
+
* lower and upper bound for the range of parameter v. rangeU and rangeV may also be functions returning an array of length two.
|
|
82237
|
+
* @example
|
|
82238
|
+
* var view = board.create('view3d',
|
|
82239
|
+
* [[-6, -3], [8, 8],
|
|
82240
|
+
* [[-5, 5], [-5, 5], [-5, 5]]]);
|
|
82241
|
+
*
|
|
82242
|
+
* // Sphere
|
|
82243
|
+
* var c = view.create('parametricsurface3d', [
|
|
82244
|
+
* (u, v) => 2 * Math.sin(u) * Math.cos(v),
|
|
82245
|
+
* (u, v) => 2 * Math.sin(u) * Math.sin(v),
|
|
82246
|
+
* (u, v) => 2 * Math.cos(u),
|
|
82247
|
+
* [0, 2 * Math.PI],
|
|
82248
|
+
* [0, Math.PI]
|
|
82249
|
+
* ], {
|
|
82250
|
+
* strokeColor: '#ff0000',
|
|
82251
|
+
* stepsU: 30,
|
|
82252
|
+
* stepsV: 30
|
|
82253
|
+
* });
|
|
82254
|
+
*
|
|
82255
|
+
* </pre><div id="JXG52da0ecc-1ba9-4d41-850c-36e5120025a5" class="jxgbox" style="width: 500px; height: 500px;"></div>
|
|
82256
|
+
* <script type="text/javascript">
|
|
82257
|
+
* (function() {
|
|
82258
|
+
* var board = JXG.JSXGraph.initBoard('JXG52da0ecc-1ba9-4d41-850c-36e5120025a5',
|
|
82259
|
+
* {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
|
|
82260
|
+
* var view = board.create('view3d',
|
|
82261
|
+
* [[-6, -3], [8, 8],
|
|
82262
|
+
* [[-5, 5], [-5, 5], [-5, 5]]]);
|
|
82263
|
+
*
|
|
82264
|
+
* // Sphere
|
|
82265
|
+
* var c = view.create('parametricsurface3d', [
|
|
82266
|
+
* (u, v) => 2 * Math.sin(u) * Math.cos(v),
|
|
82267
|
+
* (u, v) => 2 * Math.sin(u) * Math.sin(v),
|
|
82268
|
+
* (u, v) => 2 * Math.cos(u),
|
|
82269
|
+
* [0, 2 * Math.PI],
|
|
82270
|
+
* [0, Math.PI]
|
|
82271
|
+
* ], {
|
|
82272
|
+
* strokeColor: '#ff0000',
|
|
82273
|
+
* stepsU: 20,
|
|
82274
|
+
* stepsV: 20
|
|
82275
|
+
* });
|
|
82276
|
+
*
|
|
82277
|
+
* })();
|
|
82278
|
+
*
|
|
82279
|
+
* </script><pre>
|
|
82280
|
+
*
|
|
82281
|
+
*/
|
|
82282
|
+
ThreeD.createParametricSurface = function (board, parents, attributes) {
|
|
82283
|
+
var view = parents[0],
|
|
82284
|
+
attr,
|
|
82285
|
+
X = parents[1],
|
|
82286
|
+
Y = parents[2],
|
|
82287
|
+
Z = parents[3],
|
|
82288
|
+
range_u = parents[4],
|
|
82289
|
+
range_v = parents[5],
|
|
82290
|
+
D3, el;
|
|
82291
|
+
|
|
82292
|
+
D3 = {
|
|
82293
|
+
elType: 'surface3d',
|
|
82294
|
+
X: X,
|
|
82295
|
+
Y: Y,
|
|
82296
|
+
Z: Z,
|
|
82297
|
+
range_u: range_u,
|
|
82298
|
+
range_v: range_v
|
|
82299
|
+
};
|
|
82300
|
+
attr = Type.copyAttributes(attributes, board.options, 'surface3d');
|
|
82301
|
+
el = board.create('curve', [[], []], attr);
|
|
82302
|
+
el.updateDataArray = function () {
|
|
82303
|
+
var steps_u = Type.evaluate(this.visProp.stepsu),
|
|
82304
|
+
steps_v = Type.evaluate(this.visProp.stepsv),
|
|
82305
|
+
r_u = Type.evaluate(this.D3.range_u), // Type.evaluate(range_u),
|
|
82306
|
+
r_v = Type.evaluate(this.D3.range_v), // Type.evaluate(range_v),
|
|
82307
|
+
res = view.getMesh(this.D3.X, this.D3.Y, this.D3.Z,
|
|
82308
|
+
r_u.concat([steps_u]),
|
|
82309
|
+
r_v.concat([steps_v]));
|
|
82310
|
+
this.dataX = res[0];
|
|
82311
|
+
this.dataY = res[1];
|
|
82312
|
+
};
|
|
82313
|
+
el.D3 = D3;
|
|
82314
|
+
|
|
82315
|
+
return el;
|
|
82316
|
+
};
|
|
82317
|
+
JXG.registerElement('parametricsurface3d', ThreeD.createParametricSurface);
|
|
82318
|
+
|
|
82319
|
+
/**
|
|
82320
|
+
* @class This element creates a 3D function graph.
|
|
82321
|
+
* @pseudo
|
|
82322
|
+
* @description A 3D function graph is defined by a function
|
|
82323
|
+
* <i>F: R<sup>2</sup> → R</i>.
|
|
82324
|
+
*
|
|
82325
|
+
* @name Functiongraph3D
|
|
82326
|
+
* @augments ParametricSurface3D
|
|
82327
|
+
* @constructor
|
|
82328
|
+
* @type Object
|
|
82329
|
+
* @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
82330
|
+
* @param {Function_Array_Array} F,rangeX,rangeY F(x,y) is a function returning a number, rangeX is the array containing
|
|
82331
|
+
* lower and upper bound for the range of x, rangeY is the array containing
|
|
82332
|
+
* lower and upper bound for the range of y.
|
|
82333
|
+
* @example
|
|
82334
|
+
* var box = [-5, 5];
|
|
82335
|
+
* var view = board.create('view3d',
|
|
82336
|
+
* [
|
|
82337
|
+
* [-6, -3], [8, 8],
|
|
82338
|
+
* [box, box, box]
|
|
82339
|
+
* ],
|
|
82340
|
+
* {
|
|
82341
|
+
* xPlaneRear: {visible: false},
|
|
82342
|
+
* yPlaneRear: {visible: false},
|
|
82343
|
+
* });
|
|
82344
|
+
*
|
|
82345
|
+
* // Function F to be plotted
|
|
82346
|
+
* var F = (x, y) => Math.sin(x * y / 4);
|
|
82347
|
+
*
|
|
82348
|
+
* // 3D surface
|
|
82349
|
+
* var c = view.create('functiongraph3d', [
|
|
82350
|
+
* F,
|
|
82351
|
+
* box, // () => [-s.Value()*5, s.Value() * 5],
|
|
82352
|
+
* box, // () => [-s.Value()*5, s.Value() * 5],
|
|
82353
|
+
* ], {
|
|
82354
|
+
* strokeWidth: 0.5,
|
|
82355
|
+
* stepsU: 70,
|
|
82356
|
+
* stepsV: 70
|
|
82357
|
+
* });
|
|
82358
|
+
*
|
|
82359
|
+
* </pre><div id="JXG87646dd4-9fe5-4c21-8734-089abc612515" class="jxgbox" style="width: 500px; height: 500px;"></div>
|
|
82360
|
+
* <script type="text/javascript">
|
|
82361
|
+
* (function() {
|
|
82362
|
+
* var board = JXG.JSXGraph.initBoard('JXG87646dd4-9fe5-4c21-8734-089abc612515',
|
|
82363
|
+
* {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
|
|
82364
|
+
* var box = [-5, 5];
|
|
82365
|
+
* var view = board.create('view3d',
|
|
82366
|
+
* [
|
|
82367
|
+
* [-6, -3], [8, 8],
|
|
82368
|
+
* [box, box, box]
|
|
82369
|
+
* ],
|
|
82370
|
+
* {
|
|
82371
|
+
* xPlaneRear: {visible: false},
|
|
82372
|
+
* yPlaneRear: {visible: false},
|
|
82373
|
+
* });
|
|
82374
|
+
*
|
|
82375
|
+
* // Function F to be plotted
|
|
82376
|
+
* var F = (x, y) => Math.sin(x * y / 4);
|
|
82377
|
+
*
|
|
82378
|
+
* // 3D surface
|
|
82379
|
+
* var c = view.create('functiongraph3d', [
|
|
82380
|
+
* F,
|
|
82381
|
+
* box, // () => [-s.Value()*5, s.Value() * 5],
|
|
82382
|
+
* box, // () => [-s.Value()*5, s.Value() * 5],
|
|
82383
|
+
* ], {
|
|
82384
|
+
* strokeWidth: 0.5,
|
|
82385
|
+
* stepsU: 70,
|
|
82386
|
+
* stepsV: 70
|
|
82387
|
+
* });
|
|
82388
|
+
*
|
|
82389
|
+
* })();
|
|
82390
|
+
*
|
|
82391
|
+
* </script><pre>
|
|
82392
|
+
*
|
|
82393
|
+
*/
|
|
82394
|
+
ThreeD.createFunctiongraph = function (board, parents, attributes) {
|
|
82395
|
+
var view = parents[0],
|
|
82396
|
+
X = function(u, v) { return u; },
|
|
82397
|
+
Y = function(u, v) { return v; },
|
|
82398
|
+
Z = parents[1],
|
|
82399
|
+
range_u = parents[2],
|
|
82400
|
+
range_v = parents[3];
|
|
82401
|
+
|
|
82402
|
+
return view.create('parametricsurface3d', [X, Y, Z, range_u, range_v], attributes);
|
|
82403
|
+
};
|
|
82404
|
+
JXG.registerElement('functiongraph3d', ThreeD.createFunctiongraph);
|
|
82405
|
+
|
|
82406
|
+
});
|
|
82407
|
+
|
|
79896
82408
|
/*global define: true*/
|
|
79897
82409
|
define('../build/core.deps.js',[
|
|
79898
82410
|
'jxg',
|
|
@@ -79965,7 +82477,15 @@ define('../build/core.deps.js',[
|
|
|
79965
82477
|
'element/checkbox',
|
|
79966
82478
|
'element/input',
|
|
79967
82479
|
'element/button',
|
|
79968
|
-
'base/foreignobject'
|
|
82480
|
+
'base/foreignobject',
|
|
82481
|
+
'options3d',
|
|
82482
|
+
'3d/box3d',
|
|
82483
|
+
'3d/curve3d',
|
|
82484
|
+
'3d/linspace3d',
|
|
82485
|
+
'3d/point3d',
|
|
82486
|
+
'3d/surface3d',
|
|
82487
|
+
'3d/threed',
|
|
82488
|
+
'3d/view3d'
|
|
79969
82489
|
], function (JXG, Env) {
|
|
79970
82490
|
"use strict";
|
|
79971
82491
|
|