jsxgraph 1.4.4 → 1.4.6
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/build/Readme.md +17 -0
- package/build/bin/jsxcompressor.js +1 -0
- package/build/bin/jsxgraphcore-min.js +7 -0
- package/build/bin/jsxgraphcore.js +83017 -0
- package/build/bin/jsxgraphcore.min.js +67 -0
- package/build/compressor.build.json +14 -0
- package/build/compressor.deps.js +8 -0
- package/build/core-amd.build.json +14 -0
- package/build/core-amd.deps.js +81 -0
- package/build/core.build.json +14 -0
- package/build/core.deps.js +102 -0
- package/build/plot.build.json +15 -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 +28 -7
- package/distrib/intergeo.min.js +1 -1
- package/distrib/jsxgraph.css +6 -0
- package/distrib/jsxgraphcore.js +3 -3
- package/distrib/jsxgraphsrc.js +3558 -1857
- package/distrib/sketch.min.js +1 -1
- package/package.json +1 -1
- package/src/3d/box3d.js +43 -38
- package/src/3d/curve3d.js +157 -53
- package/src/3d/element3d.js +84 -0
- package/src/3d/linspace3d.js +427 -146
- package/src/3d/point3d.js +360 -123
- package/src/3d/surface3d.js +140 -42
- package/src/3d/view3d.js +319 -164
- package/src/base/board.js +163 -78
- package/src/base/constants.js +8 -1
- package/src/base/curve.js +51 -9
- package/src/base/polygon.js +111 -69
- package/src/base/text.js +122 -19
- package/src/base/ticks.js +12 -3
- package/src/element/button.js +7 -3
- package/src/element/checkbox.js +8 -4
- package/src/element/composition.js +7 -1
- package/src/element/conic.js +2 -2
- package/src/element/input.js +9 -5
- package/src/jsxgraph.js +4 -1
- package/src/loadjsxgraph.js +13 -8
- package/src/math/clip.js +34 -134
- package/src/math/geometry.js +204 -3
- package/src/math/math.js +1 -2
- package/src/math/nlp.js +865 -774
- package/src/options.js +185 -12
- package/src/options3d.js +24 -7
- package/src/parser/jessiecode.js +9 -3
- package/src/renderer/abstract.js +26 -15
- package/src/renderer/canvas.js +2 -2
- package/src/renderer/svg.js +15 -2
- package/src/utils/env.js +36 -53
- package/src/utils/type.js +75 -2
- package/src/3d/threed.js +0 -38
package/src/3d/view3d.js
CHANGED
|
@@ -28,74 +28,117 @@
|
|
|
28
28
|
*/
|
|
29
29
|
/*global JXG:true, define: true*/
|
|
30
30
|
|
|
31
|
-
define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/element',
|
|
32
|
-
|
|
31
|
+
define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/element','base/composition'],
|
|
32
|
+
function (JXG, Options, Const, Type, Mat, GeometryElement, Composition) {
|
|
33
33
|
"use strict";
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
/**
|
|
36
|
+
* 3D view inside of a JXGraph board.
|
|
37
|
+
*
|
|
38
|
+
* @class Creates a new 3D view. Do not use this constructor to create a 3D view. Use {@link JXG.Board#create} with
|
|
39
|
+
* type {@link View3D} instead.
|
|
40
|
+
*
|
|
41
|
+
* @augments JXG.GeometryElement
|
|
42
|
+
* @param {Array} parents Array consisting of lower left corner [x, y] of the view inside the board, [width, height] of the view
|
|
43
|
+
* and box size [[x1, x2], [y1,y2], [z1,z2]]. If the view's azimuth=0 and elevation=0, the 3D view will cover a rectangle with lower left corner
|
|
44
|
+
* [x,y] and side lengths [w, h] of the board.
|
|
45
|
+
*/
|
|
46
|
+
JXG.View3D = function (board, parents, attributes) {
|
|
47
|
+
this.constructor(board, attributes, Const.OBJECT_TYPE_VIEW3D, Const.OBJECT_CLASS_3D);
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* An associative array containing all geometric objects belonging to the view.
|
|
50
51
|
* Key is the id of the object and value is a reference to the object.
|
|
51
52
|
* @type Object
|
|
53
|
+
* @private
|
|
52
54
|
*/
|
|
53
|
-
this.
|
|
55
|
+
this.objects = {};
|
|
54
56
|
|
|
55
57
|
/**
|
|
56
58
|
* An array containing all geometric objects in this view in the order of construction.
|
|
57
59
|
* @type Array
|
|
60
|
+
* @private
|
|
58
61
|
*/
|
|
59
|
-
this.
|
|
62
|
+
this.objectsList = [];
|
|
60
63
|
|
|
61
64
|
/**
|
|
62
|
-
*
|
|
65
|
+
* An associative array / dictionary to store the objects of the board by name. The name of the object is the key and value is a reference to the object.
|
|
66
|
+
* @type Object
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
this.elementsByName = {};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Default axes of the 3D view, contains the axes of the view or null.
|
|
73
|
+
*
|
|
74
|
+
* @type {Object}
|
|
63
75
|
* @default null
|
|
64
76
|
*/
|
|
65
|
-
this.
|
|
77
|
+
this.defaultAxes = null;
|
|
66
78
|
|
|
67
79
|
/**
|
|
68
80
|
* 3D-to-2D transformation matrix
|
|
69
|
-
* @type {Array} 3 x 4
|
|
81
|
+
* @type {Array} 3 x 4 matrix
|
|
82
|
+
* @private
|
|
70
83
|
*/
|
|
71
|
-
this.
|
|
84
|
+
this.matrix3D = [
|
|
72
85
|
[1, 0, 0, 0],
|
|
73
86
|
[0, 1, 0, 0],
|
|
74
87
|
[0, 0, 1, 0]
|
|
75
88
|
];
|
|
76
89
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Lower left corner [x, y] of the 3D view if elevation and azimuth are set to 0.
|
|
92
|
+
* @type array
|
|
93
|
+
* @private
|
|
94
|
+
*/
|
|
95
|
+
this.llftCorner = parents[0];
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Width and height [w, h] of the 3D view if elevation and azimuth are set to 0.
|
|
99
|
+
* @type array
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
this.size = parents[1];
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Bounding box (cube) [[x1, x2], [y1,y2], [z1,z2]] of the 3D view
|
|
106
|
+
* @type array
|
|
107
|
+
*/
|
|
108
|
+
this.bbox3D = parents[2];
|
|
81
109
|
|
|
82
110
|
/**
|
|
83
111
|
* Distance of the view to the origin. In other words, its
|
|
84
|
-
* the radius of the sphere where the camera sits.
|
|
112
|
+
* the radius of the sphere where the camera sits.view.board.update
|
|
113
|
+
* @type Number
|
|
85
114
|
*/
|
|
86
|
-
this.
|
|
115
|
+
this.r = -1;
|
|
87
116
|
|
|
88
117
|
this.timeoutAzimuth = null;
|
|
89
118
|
|
|
90
119
|
this.id = this.board.setId(this, 'V');
|
|
91
120
|
this.board.finalizeAdding(this);
|
|
92
121
|
this.elType = 'view3d';
|
|
122
|
+
|
|
93
123
|
this.methodMap = Type.deepCopy(this.methodMap, {
|
|
124
|
+
// TODO
|
|
94
125
|
});
|
|
95
126
|
};
|
|
96
|
-
|
|
127
|
+
JXG.View3D.prototype = new GeometryElement();
|
|
128
|
+
|
|
129
|
+
JXG.extend(JXG.View3D.prototype, /** @lends JXG.View3D.prototype */ {
|
|
97
130
|
|
|
98
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Creates a new 3D element of type elementType.
|
|
133
|
+
* @param {String} elementType Type of the element to be constructed given as a string e.g. 'point3d' or 'surface3d'.
|
|
134
|
+
* @param {Array} parents Array of parent elements needed to construct the element e.g. coordinates for a 3D point or two
|
|
135
|
+
* 3D points to construct a line. This highly depends on the elementType that is constructed. See the corresponding JXG.create*
|
|
136
|
+
* methods for a list of possible parameters.
|
|
137
|
+
* @param {Object} [attributes] An object containing the attributes to be set. This also depends on the elementType.
|
|
138
|
+
* Common attributes are name, visible, strokeColor.
|
|
139
|
+
* @returns {Object} Reference to the created element. This is usually a GeometryElement3D, but can be an array containing
|
|
140
|
+
* two or more elements.
|
|
141
|
+
*/
|
|
99
142
|
create: function (elementType, parents, attributes) {
|
|
100
143
|
var prefix = [],
|
|
101
144
|
is3D = false,
|
|
@@ -106,59 +149,117 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
106
149
|
prefix.push(this);
|
|
107
150
|
}
|
|
108
151
|
el = this.board.create(elementType, prefix.concat(parents), attributes);
|
|
109
|
-
if (true || is3D) {
|
|
110
|
-
this.add(el);
|
|
111
|
-
}
|
|
112
|
-
return el;
|
|
113
|
-
},
|
|
114
152
|
|
|
115
|
-
|
|
116
|
-
this.D3.objects[el.id] = el;
|
|
117
|
-
this.D3.objectsList.push(el);
|
|
153
|
+
return el;
|
|
118
154
|
},
|
|
119
155
|
|
|
120
156
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
157
|
+
* Select a single or multiple elements at once.
|
|
158
|
+
* @param {String|Object|function} str The name, id or a reference to a JSXGraph 3D element in the 3D view. An object will
|
|
159
|
+
* be used as a filter to return multiple elements at once filtered by the properties of the object.
|
|
160
|
+
* @param {Boolean} onlyByIdOrName If true (default:false) elements are only filtered by their id, name or groupId.
|
|
161
|
+
* The advanced filters consisting of objects or functions are ignored.
|
|
162
|
+
* @returns {JXG.GeometryElement3D|JXG.Composition}
|
|
163
|
+
* @example
|
|
164
|
+
* // select the element with name A
|
|
165
|
+
* view.select('A');
|
|
123
166
|
*
|
|
124
|
-
*
|
|
167
|
+
* // select all elements with strokecolor set to 'red' (but not '#ff0000')
|
|
168
|
+
* view.select({
|
|
169
|
+
* strokeColor: 'red'
|
|
170
|
+
* });
|
|
171
|
+
*
|
|
172
|
+
* // select all points on or below the x/y plane and make them black.
|
|
173
|
+
* view.select({
|
|
174
|
+
* elType: 'point3d',
|
|
175
|
+
* Z: function (v) {
|
|
176
|
+
* return v <= 0;
|
|
177
|
+
* }
|
|
178
|
+
* }).setAttribute({color: 'black'});
|
|
179
|
+
*
|
|
180
|
+
* // select all elements
|
|
181
|
+
* view.select(function (el) {
|
|
182
|
+
* return true;
|
|
183
|
+
* });
|
|
125
184
|
*/
|
|
185
|
+
select: function (str, onlyByIdOrName) {
|
|
186
|
+
var flist, olist, i, l,
|
|
187
|
+
s = str;
|
|
188
|
+
|
|
189
|
+
if (s === null) {
|
|
190
|
+
return s;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// It's a string, most likely an id or a name.
|
|
194
|
+
if (Type.isString(s) && s !== '') {
|
|
195
|
+
// Search by ID
|
|
196
|
+
if (Type.exists(this.objects[s])) {
|
|
197
|
+
s = this.objects[s];
|
|
198
|
+
// Search by name
|
|
199
|
+
} else if (Type.exists(this.elementsByName[s])) {
|
|
200
|
+
s = this.elementsByName[s];
|
|
201
|
+
// // Search by group ID
|
|
202
|
+
// } else if (Type.exists(this.groups[s])) {
|
|
203
|
+
// s = this.groups[s];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// It's a function or an object, but not an element
|
|
207
|
+
} else if (!onlyByIdOrName &&
|
|
208
|
+
(Type.isFunction(s) ||
|
|
209
|
+
(Type.isObject(s) && !Type.isFunction(s.setAttribute))
|
|
210
|
+
)) {
|
|
211
|
+
flist = Type.filterElements(this.objectsList, s);
|
|
212
|
+
|
|
213
|
+
olist = {};
|
|
214
|
+
l = flist.length;
|
|
215
|
+
for (i = 0; i < l; i++) {
|
|
216
|
+
olist[flist[i].id] = flist[i];
|
|
217
|
+
}
|
|
218
|
+
s = new Composition(olist);
|
|
219
|
+
|
|
220
|
+
// It's an element which has been deleted (and still hangs around, e.g. in an attractor list
|
|
221
|
+
} else if (Type.isObject(s) && Type.exists(s.id) && !Type.exists(this.objects[s.id])) {
|
|
222
|
+
s = null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return s;
|
|
226
|
+
},
|
|
227
|
+
|
|
126
228
|
update: function () {
|
|
127
|
-
|
|
128
|
-
|
|
229
|
+
// Update 3D-to-2D transformation matrix with the actual
|
|
230
|
+
// elevation and azimuth angles.
|
|
129
231
|
|
|
130
|
-
|
|
131
|
-
|
|
232
|
+
var e, r, a, f, mat;
|
|
233
|
+
|
|
234
|
+
if (!Type.exists(this.el_slide) ||
|
|
235
|
+
!Type.exists(this.az_slide) ||
|
|
132
236
|
!this.needsUpdate) {
|
|
133
237
|
return this;
|
|
134
238
|
}
|
|
135
239
|
|
|
136
|
-
e =
|
|
137
|
-
r =
|
|
138
|
-
a =
|
|
240
|
+
e = this.el_slide.Value();
|
|
241
|
+
r = this.r;
|
|
242
|
+
a = this.az_slide.Value();
|
|
139
243
|
f = r * Math.sin(e);
|
|
140
244
|
mat = [[1, 0, 0,], [0, 1, 0], [0, 0, 1]];
|
|
141
245
|
|
|
142
|
-
|
|
246
|
+
this.matrix3D = [
|
|
143
247
|
[1, 0, 0, 0],
|
|
144
248
|
[0, 1, 0, 0],
|
|
145
249
|
[0, 0, 1, 0]
|
|
146
250
|
];
|
|
147
251
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (true) {
|
|
155
|
-
mat[1][1] = D3.size[0] / (D3.bbox3d[0][1] - D3.bbox3d[0][0]); // w / d_x
|
|
156
|
-
mat[2][2] = D3.size[1] / (D3.bbox3d[1][1] - D3.bbox3d[1][0]); // h / d_y
|
|
157
|
-
mat[1][0] = D3.coords[0] - mat[1][1] * D3.bbox3d[0][0]; // llft_x
|
|
158
|
-
mat[2][0] = D3.coords[1] - mat[2][2] * D3.bbox3d[1][0]; // llft_y
|
|
252
|
+
this.matrix3D[1][1] = r * Math.cos(a);
|
|
253
|
+
this.matrix3D[1][2] = -r * Math.sin(a);
|
|
254
|
+
this.matrix3D[2][1] = f * Math.sin(a);
|
|
255
|
+
this.matrix3D[2][2] = f * Math.cos(a);
|
|
256
|
+
this.matrix3D[2][3] = Math.cos(e);
|
|
159
257
|
|
|
160
|
-
|
|
161
|
-
|
|
258
|
+
mat[1][1] = this.size[0] / (this.bbox3D[0][1] - this.bbox3D[0][0]); // w / d_x
|
|
259
|
+
mat[2][2] = this.size[1] / (this.bbox3D[1][1] - this.bbox3D[1][0]); // h / d_y
|
|
260
|
+
mat[1][0] = this.llftCorner[0] - mat[1][1] * this.bbox3D[0][0]; // llft_x
|
|
261
|
+
mat[2][0] = this.llftCorner[1] - mat[2][2] * this.bbox3D[1][0]; // llft_y
|
|
262
|
+
this.matrix3D = Mat.matMatMult(mat, this.matrix3D);
|
|
162
263
|
|
|
163
264
|
return this;
|
|
164
265
|
},
|
|
@@ -190,19 +291,20 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
190
291
|
vec = x;
|
|
191
292
|
}
|
|
192
293
|
}
|
|
193
|
-
return Mat.matVecMult(this.
|
|
294
|
+
return Mat.matVecMult(this.matrix3D, vec);
|
|
194
295
|
},
|
|
195
296
|
|
|
196
297
|
/**
|
|
197
|
-
* Project a 2D coordinate to the plane
|
|
198
|
-
*
|
|
298
|
+
* Project a 2D coordinate to the plane defined by the point foot
|
|
299
|
+
* and the normal vector `normal`.
|
|
199
300
|
*
|
|
200
301
|
* @param {JXG.Point} point
|
|
201
302
|
* @param {Array} normal
|
|
202
|
-
* @
|
|
303
|
+
* @param {Array} foot
|
|
304
|
+
* @returns {Array} of length 4 containing the projected
|
|
203
305
|
* point in homogeneous coordinates.
|
|
204
306
|
*/
|
|
205
|
-
project2DTo3DPlane: function (
|
|
307
|
+
project2DTo3DPlane: function (point2d, normal, foot) {
|
|
206
308
|
var mat, rhs, d, le,
|
|
207
309
|
n = normal.slice(1),
|
|
208
310
|
sol = [1, 0, 0, 0];
|
|
@@ -211,11 +313,11 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
211
313
|
le = Mat.norm(n, 3);
|
|
212
314
|
d = Mat.innerProduct(foot.slice(1), n, 3) / le;
|
|
213
315
|
|
|
214
|
-
mat = this.
|
|
316
|
+
mat = this.matrix3D.slice(0, 3); // True copy
|
|
215
317
|
mat.push([0].concat(n));
|
|
216
318
|
|
|
217
319
|
// 2D coordinates of point:
|
|
218
|
-
rhs =
|
|
320
|
+
rhs = point2d.coords.usrCoords.concat([d]);
|
|
219
321
|
try {
|
|
220
322
|
// Prevent singularity in case elevation angle is zero
|
|
221
323
|
if (mat[2][3] === 1.0) {
|
|
@@ -229,8 +331,14 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
229
331
|
return sol;
|
|
230
332
|
},
|
|
231
333
|
|
|
334
|
+
/**
|
|
335
|
+
* Limit 3D coordinates to the bounding cube.
|
|
336
|
+
*
|
|
337
|
+
* @param {Array} c3d 3D coordinates [x,y,z]
|
|
338
|
+
* @returns Array with updated 3D coordinates.
|
|
339
|
+
*/
|
|
232
340
|
project3DToCube: function (c3d) {
|
|
233
|
-
var cube = this.
|
|
341
|
+
var cube = this.bbox3D;
|
|
234
342
|
if (c3d[1] < cube[0][0]) { c3d[1] = cube[0][0]; }
|
|
235
343
|
if (c3d[1] > cube[0][1]) { c3d[1] = cube[0][1]; }
|
|
236
344
|
if (c3d[2] < cube[1][0]) { c3d[2] = cube[1][0]; }
|
|
@@ -241,14 +349,21 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
241
349
|
return c3d;
|
|
242
350
|
},
|
|
243
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Intersect a ray with the bounding cube of the 3D view.
|
|
354
|
+
* @param {Array} p 3D coordinates [x,y,z]
|
|
355
|
+
* @param {Array} d 3D direction vector of the line (array of length 3)
|
|
356
|
+
* @param {Number} r direction of the ray (positive if r > 0, negative if r < 0).
|
|
357
|
+
* @returns Affine ratio of the intersection of the line with the cube.
|
|
358
|
+
*/
|
|
244
359
|
intersectionLineCube: function (p, d, r) {
|
|
245
360
|
var rnew, i, r0, r1;
|
|
246
361
|
|
|
247
362
|
rnew = r;
|
|
248
363
|
for (i = 0; i < 3; i++) {
|
|
249
364
|
if (d[i] !== 0) {
|
|
250
|
-
r0 = (this.
|
|
251
|
-
r1 = (this.
|
|
365
|
+
r0 = (this.bbox3D[i][0] - p[i]) / d[i];
|
|
366
|
+
r1 = (this.bbox3D[i][1] - p[i]) / d[i];
|
|
252
367
|
if (r < 0) {
|
|
253
368
|
rnew = Math.max(rnew, Math.min(r0, r1));
|
|
254
369
|
} else {
|
|
@@ -259,29 +374,35 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
259
374
|
return rnew;
|
|
260
375
|
},
|
|
261
376
|
|
|
377
|
+
/**
|
|
378
|
+
* Test if coordinates are inside of the bounding cube.
|
|
379
|
+
* @param {array} q 3D coordinates [x,y,z] of a point.
|
|
380
|
+
* @returns Boolean
|
|
381
|
+
*/
|
|
262
382
|
isInCube: function (q) {
|
|
263
|
-
return q[0] > this.
|
|
264
|
-
q[1] > this.
|
|
265
|
-
q[2] > this.
|
|
383
|
+
return q[0] > this.bbox3D[0][0] - Mat.eps && q[0] < this.bbox3D[0][1] + Mat.eps &&
|
|
384
|
+
q[1] > this.bbox3D[1][0] - Mat.eps && q[1] < this.bbox3D[1][1] + Mat.eps &&
|
|
385
|
+
q[2] > this.bbox3D[2][0] - Mat.eps && q[2] < this.bbox3D[2][1] + Mat.eps;
|
|
266
386
|
},
|
|
267
387
|
|
|
268
388
|
/**
|
|
269
389
|
*
|
|
270
|
-
* @param {
|
|
271
|
-
* @param {
|
|
272
|
-
* @param {
|
|
273
|
-
* @returns Array of length 2 containing the coordinates of the defining points of
|
|
390
|
+
* @param {JXG.Plane3D} plane1
|
|
391
|
+
* @param {JXG.Plane3D} plane2
|
|
392
|
+
* @param {JXG.Plane3D} d
|
|
393
|
+
* @returns {Array} of length 2 containing the coordinates of the defining points of
|
|
274
394
|
* of the intersection segment.
|
|
275
395
|
*/
|
|
276
396
|
intersectionPlanePlane: function(plane1, plane2, d) {
|
|
277
397
|
var ret = [[], []],
|
|
278
398
|
p, dir, r, q;
|
|
279
399
|
|
|
280
|
-
d = d || plane2.
|
|
400
|
+
d = d || plane2.d;
|
|
281
401
|
|
|
282
|
-
p = Mat.Geometry.meet3Planes(
|
|
283
|
-
|
|
284
|
-
|
|
402
|
+
p = Mat.Geometry.meet3Planes(
|
|
403
|
+
plane1.normal, plane1.d, plane2.normal, d, Mat.crossProduct(plane1.normal, plane2.normal
|
|
404
|
+
), 0);
|
|
405
|
+
dir = Mat.Geometry.meetPlanePlane(plane1.vec1, plane1.vec2, plane2.vec1, plane2.vec2);
|
|
285
406
|
r = this.intersectionLineCube(p, dir, Infinity);
|
|
286
407
|
q = Mat.axpy(r, dir, p);
|
|
287
408
|
if (this.isInCube(q)) {
|
|
@@ -295,7 +416,39 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
295
416
|
return ret;
|
|
296
417
|
},
|
|
297
418
|
|
|
298
|
-
|
|
419
|
+
/**
|
|
420
|
+
* Generate mesh for a surface / plane.
|
|
421
|
+
* Returns array [dataX, dataY] for a JSXGraph curve's updateDataArray function.
|
|
422
|
+
* @param {Array,Function} func
|
|
423
|
+
* @param {Array} interval_u
|
|
424
|
+
* @param {Array} interval_v
|
|
425
|
+
* @returns Array
|
|
426
|
+
* @private
|
|
427
|
+
*
|
|
428
|
+
* @example
|
|
429
|
+
* var el = view.create('curve', [[], []]);
|
|
430
|
+
* el.updateDataArray = function () {
|
|
431
|
+
* var steps_u = Type.evaluate(this.visProp.stepsu),
|
|
432
|
+
* steps_v = Type.evaluate(this.visProp.stepsv),
|
|
433
|
+
* r_u = Type.evaluate(this.range_u),
|
|
434
|
+
* r_v = Type.evaluate(this.range_v),
|
|
435
|
+
* func, ret;
|
|
436
|
+
*
|
|
437
|
+
* if (this.F !== null) {
|
|
438
|
+
* func = this.F;
|
|
439
|
+
* } else {
|
|
440
|
+
* func = [this.X, this.Y, this.Z];
|
|
441
|
+
* }
|
|
442
|
+
* ret = this.view.getMesh(func,
|
|
443
|
+
* r_u.concat([steps_u]),
|
|
444
|
+
* r_v.concat([steps_v]));
|
|
445
|
+
*
|
|
446
|
+
* this.dataX = ret[0];
|
|
447
|
+
* this.dataY = ret[1];
|
|
448
|
+
* };
|
|
449
|
+
*
|
|
450
|
+
*/
|
|
451
|
+
getMesh: function (func, interval_u, interval_v) {
|
|
299
452
|
var i_u, i_v, u, v, c2d,
|
|
300
453
|
delta_u, delta_v,
|
|
301
454
|
p = [0, 0, 0],
|
|
@@ -312,9 +465,11 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
312
465
|
u = interval_u[0] + delta_u * i_u;
|
|
313
466
|
for (i_v = 0; i_v <= steps_v; i_v++) {
|
|
314
467
|
v = interval_v[0] + delta_v * i_v;
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
468
|
+
if (Type.isFunction(func)) {
|
|
469
|
+
p = func(u, v);
|
|
470
|
+
} else {
|
|
471
|
+
p = [func[0](u, v), func[1](u, v), func[2](u, v)];
|
|
472
|
+
}
|
|
318
473
|
c2d = this.project3DTo2D(p);
|
|
319
474
|
dataX.push(c2d[1]);
|
|
320
475
|
dataY.push(c2d[2]);
|
|
@@ -327,9 +482,11 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
327
482
|
v = interval_v[0] + delta_v * i_v;
|
|
328
483
|
for (i_u = 0; i_u <= steps_u; i_u++) {
|
|
329
484
|
u = interval_u[0] + delta_u * i_u;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
485
|
+
if (Type.isFunction(func)) {
|
|
486
|
+
p = func(u, v);
|
|
487
|
+
} else {
|
|
488
|
+
p = [func[0](u, v), func[1](u, v), func[2](u, v)];
|
|
489
|
+
}
|
|
333
490
|
c2d = this.project3DTo2D(p);
|
|
334
491
|
dataX.push(c2d[1]);
|
|
335
492
|
dataY.push(c2d[2]);
|
|
@@ -341,21 +498,27 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
341
498
|
return [dataX, dataY];
|
|
342
499
|
},
|
|
343
500
|
|
|
501
|
+
/**
|
|
502
|
+
*
|
|
503
|
+
*/
|
|
344
504
|
animateAzimuth: function () {
|
|
345
|
-
var s = this.
|
|
346
|
-
e = this.
|
|
505
|
+
var s = this.az_slide._smin,
|
|
506
|
+
e = this.az_slide._smax,
|
|
347
507
|
sdiff = e - s,
|
|
348
|
-
newVal = this.
|
|
508
|
+
newVal = this.az_slide.Value() + 0.1;
|
|
349
509
|
|
|
350
|
-
this.
|
|
351
|
-
if (this.
|
|
352
|
-
this.
|
|
510
|
+
this.az_slide.position = ((newVal - s) / sdiff);
|
|
511
|
+
if (this.az_slide.position > 1) {
|
|
512
|
+
this.az_slide.position = 0.0;
|
|
353
513
|
}
|
|
354
514
|
this.board.update();
|
|
355
515
|
|
|
356
516
|
this.timeoutAzimuth = setTimeout(function () { this.animateAzimuth(); }.bind(this), 200);
|
|
357
517
|
},
|
|
358
518
|
|
|
519
|
+
/**
|
|
520
|
+
*
|
|
521
|
+
*/
|
|
359
522
|
stopAzimuth: function () {
|
|
360
523
|
clearTimeout(this.timeoutAzimuth);
|
|
361
524
|
this.timeoutAzimuth = null;
|
|
@@ -375,8 +538,9 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
375
538
|
* @param {Array_Array_Array} lower,dim,cube Here, lower is an array of the form [x, y] and
|
|
376
539
|
* dim is an array of the form [w, h].
|
|
377
540
|
* The arrays [x, y] and [w, h] define the 2D frame into which the 3D cube is
|
|
378
|
-
* (roughly) projected.
|
|
379
|
-
*
|
|
541
|
+
* (roughly) projected. If the view's azimuth=0 and elevation=0, the 3D view will cover a rectangle with lower left corner
|
|
542
|
+
* [x,y] and side lengths [w, h] of the board.
|
|
543
|
+
* The array 'cube' is of the form [[x1, x2], [y1, y2], [z1, z2]]
|
|
380
544
|
* which determines the coordinate ranges of the 3D cube.
|
|
381
545
|
*
|
|
382
546
|
* @example
|
|
@@ -410,43 +574,38 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
410
574
|
* (function() {
|
|
411
575
|
* var board = JXG.JSXGraph.initBoard('JXGdd06d90e-be5d-4531-8f0b-65fc30b1a7c7',
|
|
412
576
|
* {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
* zPlaneFrontXAxis: {visible: false},
|
|
434
|
-
* zPlaneFrontYAxis: {visible: false}
|
|
435
|
-
* });
|
|
436
|
-
*
|
|
577
|
+
* var bound = [-5, 5];
|
|
578
|
+
* var view = board.create('view3d',
|
|
579
|
+
* [[-6, -3], [8, 8],
|
|
580
|
+
* [bound, bound, bound]],
|
|
581
|
+
* {
|
|
582
|
+
* // Main axes
|
|
583
|
+
* axesPosition: 'center',
|
|
584
|
+
* xAxis: { strokeColor: 'blue', strokeWidth: 3},
|
|
585
|
+
* // Planes
|
|
586
|
+
* xPlaneRear: { fillColor: 'yellow', mesh3d: {visible: false}},
|
|
587
|
+
* yPlaneFront: { visible: true, fillColor: 'blue'},
|
|
588
|
+
* // Axes on planes
|
|
589
|
+
* xPlaneRearYAxis: {strokeColor: 'red'},
|
|
590
|
+
* xPlaneRearZAxis: {strokeColor: 'red'},
|
|
591
|
+
* yPlaneFrontXAxis: {strokeColor: 'blue'},
|
|
592
|
+
* yPlaneFrontZAxis: {strokeColor: 'blue'},
|
|
593
|
+
* zPlaneFrontXAxis: {visible: false},
|
|
594
|
+
* zPlaneFrontYAxis: {visible: false}
|
|
595
|
+
* });
|
|
437
596
|
* })();
|
|
438
597
|
*
|
|
439
598
|
* </script><pre>
|
|
440
599
|
*
|
|
441
600
|
*/
|
|
442
|
-
|
|
443
|
-
var view,
|
|
601
|
+
JXG.createView3D = function (board, parents, attributes) {
|
|
602
|
+
var view, attr,
|
|
444
603
|
x, y, w, h,
|
|
445
604
|
coords = parents[0], // llft corner
|
|
446
605
|
size = parents[1]; // [w, h]
|
|
447
606
|
|
|
448
607
|
attr = Type.copyAttributes(attributes, board.options, 'view3d');
|
|
449
|
-
view = new
|
|
608
|
+
view = new JXG.View3D(board, parents, attr);
|
|
450
609
|
view.defaultAxes = view.create('axes3d', parents, attributes);
|
|
451
610
|
|
|
452
611
|
x = coords[0];
|
|
@@ -454,37 +613,12 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
454
613
|
w = size[0];
|
|
455
614
|
h = size[1];
|
|
456
615
|
|
|
457
|
-
/**
|
|
458
|
-
* Frame around the view object
|
|
459
|
-
*/
|
|
460
|
-
if (false) {
|
|
461
|
-
frame = board.create('polygon', [
|
|
462
|
-
[coords[0], coords[1] + size[1]], // ulft
|
|
463
|
-
[coords[0], coords[1]], // llft
|
|
464
|
-
[coords[0] + size[0], coords[1]], // lrt
|
|
465
|
-
[coords[0] + size[0], coords[1] + size[1]], // urt
|
|
466
|
-
], {
|
|
467
|
-
fillColor: 'none',
|
|
468
|
-
highlightFillColor: 'none',
|
|
469
|
-
highlight: false,
|
|
470
|
-
vertices: {
|
|
471
|
-
fixed: true,
|
|
472
|
-
visible: false
|
|
473
|
-
},
|
|
474
|
-
borders: {
|
|
475
|
-
strokeColor: 'black',
|
|
476
|
-
highlight: false,
|
|
477
|
-
strokeWidth: 0.5,
|
|
478
|
-
dash: 4
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
//view.add(frame);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
616
|
/**
|
|
485
617
|
* Slider to adapt azimuth angle
|
|
618
|
+
* @name JXG.View3D#az_slide
|
|
619
|
+
* @type {Slider}
|
|
486
620
|
*/
|
|
487
|
-
view.
|
|
621
|
+
view.az_slide = board.create('slider', [[x - 1, y - 2], [x + w + 1, y - 2], [0, 1.0, 2 * Math.PI]], {
|
|
488
622
|
style: 6, name: 'az',
|
|
489
623
|
point1: { frozen: true },
|
|
490
624
|
point2: { frozen: true }
|
|
@@ -492,38 +626,59 @@ define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/ele
|
|
|
492
626
|
|
|
493
627
|
/**
|
|
494
628
|
* Slider to adapt elevation angle
|
|
629
|
+
*
|
|
630
|
+
* @name JXG.View3D#el_slide
|
|
631
|
+
* @type {Slider}
|
|
495
632
|
*/
|
|
496
|
-
view.
|
|
633
|
+
view.el_slide = board.create('slider', [[x - 1, y], [x - 1, y + h], [0, 0.30, Math.PI / 2]], {
|
|
497
634
|
style: 6, name: 'el',
|
|
498
635
|
point1: { frozen: true },
|
|
499
636
|
point2: { frozen: true }
|
|
500
637
|
});
|
|
501
638
|
|
|
502
639
|
view.board.highlightInfobox = function (x, y, el) {
|
|
503
|
-
var d
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
640
|
+
var d, i,
|
|
641
|
+
c3d, foot,
|
|
642
|
+
brd = el.board,
|
|
643
|
+
p = null;
|
|
644
|
+
|
|
645
|
+
// Search 3D parent
|
|
646
|
+
for (i = 0; i < el.parents.length; i++) {
|
|
647
|
+
p = brd.objects[el.parents[i]];
|
|
648
|
+
if (p.is3D) {
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
if (p) {
|
|
653
|
+
foot = [1, 0, 0, p.coords[3]];
|
|
654
|
+
c3d = view.project2DTo3DPlane(p.element2D, [1, 0, 0, 1], foot);
|
|
655
|
+
if (!view.isInCube(c3d)) {
|
|
656
|
+
view.board.highlightCustomInfobox('', p);
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
d = Type.evaluate(p.visProp.infoboxdigits);
|
|
507
660
|
if (d === 'auto') {
|
|
508
661
|
view.board.highlightCustomInfobox('(' +
|
|
509
|
-
Type.autoDigits(
|
|
510
|
-
Type.autoDigits(
|
|
511
|
-
Type.autoDigits(
|
|
662
|
+
Type.autoDigits(p.X()) + ' | ' +
|
|
663
|
+
Type.autoDigits(p.Y()) + ' | ' +
|
|
664
|
+
Type.autoDigits(p.Z()) + ')', p);
|
|
512
665
|
} else {
|
|
513
666
|
view.board.highlightCustomInfobox('(' +
|
|
514
|
-
Type.toFixed(
|
|
515
|
-
Type.toFixed(
|
|
516
|
-
Type.toFixed(
|
|
667
|
+
Type.toFixed(p.X(), d) + ' | ' +
|
|
668
|
+
Type.toFixed(p.Y(), d) + ' | ' +
|
|
669
|
+
Type.toFixed(p.Z(), d) + ')', p);
|
|
517
670
|
}
|
|
518
671
|
} else {
|
|
519
672
|
view.board.highlightCustomInfobox('(' + x + ', ' + y + ')', el);
|
|
520
673
|
}
|
|
521
674
|
};
|
|
522
675
|
|
|
676
|
+
view.board.update();
|
|
677
|
+
|
|
523
678
|
return view;
|
|
524
679
|
};
|
|
525
|
-
JXG.registerElement('view3d',
|
|
680
|
+
JXG.registerElement('view3d', JXG.createView3D);
|
|
526
681
|
|
|
527
|
-
return
|
|
682
|
+
return JXG.View3D;
|
|
528
683
|
});
|
|
529
684
|
|