jsxgraph 1.3.0 → 1.4.1
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 +2 -2
- package/distrib/README.md +2 -2
- package/distrib/geogebra.min.js +3 -3
- package/distrib/geonext.min.js +3 -3
- package/distrib/index.d.ts +651 -448
- package/distrib/intergeo.min.js +3 -3
- package/distrib/jsxgraph.css +4 -13
- package/distrib/jsxgraphcore.js +9 -25
- package/distrib/jsxgraphsrc.js +28203 -25234
- package/distrib/sketch.min.js +3 -3
- package/package.json +11 -22
- package/src/base/board.js +674 -469
- package/src/base/chart.js +1 -1
- package/src/base/circle.js +23 -1
- package/src/base/composition.js +1 -1
- package/src/base/constants.js +32 -11
- package/src/base/coords.js +4 -4
- package/src/base/coordselement.js +51 -24
- package/src/base/curve.js +308 -117
- package/src/base/element.js +79 -50
- package/src/base/foreignobject.js +463 -0
- package/src/base/group.js +2 -2
- package/src/base/image.js +12 -15
- package/src/base/line.js +108 -21
- package/src/base/point.js +24 -28
- package/src/base/polygon.js +75 -18
- package/src/base/text.js +116 -63
- package/src/base/ticks.js +29 -11
- package/src/base/transformation.js +1 -1
- package/src/base/turtle.js +1 -1
- package/src/element/arc.js +1 -1
- package/src/element/button.js +29 -2
- package/src/element/checkbox.js +31 -1
- package/src/element/comb.js +5 -2
- package/src/element/composition.js +127 -19
- package/src/element/conic.js +46 -5
- package/src/element/input.js +32 -1
- package/src/element/locus.js +2 -2
- package/src/element/measure.js +9 -4
- package/src/element/sector.js +46 -12
- package/src/element/slider.js +17 -12
- package/src/element/slopetriangle.js +1 -1
- package/src/jsxgraph.js +28 -9
- package/src/jxg.js +4 -3
- package/src/loadjsxgraph.js +3 -2
- package/src/math/bst.js +1 -1
- package/src/math/clip.js +550 -345
- package/src/math/complex.js +1 -1
- package/src/math/extrapolate.js +1 -1
- package/src/math/geometry.js +155 -126
- package/src/math/ia.js +290 -21
- package/src/math/math.js +30 -1
- package/src/math/metapost.js +1 -1
- package/src/math/nlp.js +25 -5
- package/src/math/numerics.js +183 -4
- package/src/math/plot.js +4 -4
- package/src/math/poly.js +1 -1
- package/src/math/probfuncs.js +2 -1
- package/src/math/qdt.js +68 -62
- package/src/math/statistics.js +58 -7
- package/src/math/symbolic.js +1 -1
- package/src/options.js +377 -114
- package/src/parser/ca.js +1297 -1291
- package/src/parser/datasource.js +1 -1
- package/src/parser/geonext.js +6 -6
- package/src/parser/jessiecode.js +275 -79
- package/src/parser/jessiescript.js +1 -1
- package/src/reader/cinderella.js +1 -1
- package/src/reader/file.js +1 -1
- package/src/reader/geogebra.js +1 -1
- package/src/reader/geonext.js +1 -1
- package/src/reader/graph.js +1 -1
- package/src/reader/intergeo.js +1 -1
- package/src/reader/sketch.js +21 -13
- package/src/renderer/abstract.js +21 -6
- package/src/renderer/canvas.js +22 -15
- package/src/renderer/no.js +11 -4
- package/src/renderer/svg.js +76 -53
- package/src/renderer/vml.js +36 -32
- package/src/server/server.js +1 -1
- package/src/utils/base64.js +2 -2
- package/src/utils/color.js +148 -3
- package/src/utils/dump.js +21 -15
- package/src/utils/env.js +63 -104
- package/src/utils/event.js +1 -1
- package/src/utils/expect.js +1 -1
- package/src/utils/type.js +30 -19
- package/src/utils/xml.js +1 -1
- package/src/utils/zip.js +1 -1
- package/CHANGELOG.md +0 -1281
package/src/base/image.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright 2008-
|
|
2
|
+
Copyright 2008-2022
|
|
3
3
|
Matthias Ehmann,
|
|
4
4
|
Michael Gerhaeuser,
|
|
5
5
|
Carsten Miller,
|
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
base/coords
|
|
40
40
|
base/element
|
|
41
41
|
math/math
|
|
42
|
-
math/statistics
|
|
43
42
|
utils/type
|
|
44
43
|
*/
|
|
45
44
|
|
|
@@ -55,8 +54,6 @@ define([
|
|
|
55
54
|
|
|
56
55
|
/**
|
|
57
56
|
* Construct and handle images
|
|
58
|
-
* The coordinates can be relative to the coordinates of an element
|
|
59
|
-
* given in {@link JXG.Options#text.anchor}.
|
|
60
57
|
*
|
|
61
58
|
* The image can be supplied as an URL or an base64 encoded inline image
|
|
62
59
|
* like "data:image/png;base64, /9j/4AAQSkZJRgA..." or a function returning
|
|
@@ -66,8 +63,8 @@ define([
|
|
|
66
63
|
* type {@link Image} instead.
|
|
67
64
|
* @augments JXG.GeometryElement
|
|
68
65
|
* @augments JXG.CoordsElement
|
|
69
|
-
* @param {string|JXG.Board} board The board the new
|
|
70
|
-
* @param {Array} coordinates An array with the user coordinates of the
|
|
66
|
+
* @param {string|JXG.Board} board The board the new image is drawn on.
|
|
67
|
+
* @param {Array} coordinates An array with the user coordinates of the image.
|
|
71
68
|
* @param {Object} attributes An object containing visual and - optionally - a name and an id.
|
|
72
69
|
* @param {string|function} url An URL string or a function returning an URL string.
|
|
73
70
|
* @param {Array} size Array containing width and height of the image in user coordinates.
|
|
@@ -85,13 +82,13 @@ define([
|
|
|
85
82
|
|
|
86
83
|
/**
|
|
87
84
|
* Array of length two containing [width, height] of the image in pixel.
|
|
88
|
-
* @type
|
|
85
|
+
* @type array
|
|
89
86
|
*/
|
|
90
87
|
this.size = [Math.abs(this.usrSize[0] * board.unitX), Math.abs(this.usrSize[1] * board.unitY)];
|
|
91
88
|
|
|
92
89
|
/**
|
|
93
90
|
* 'href' of the image. This might be an URL, but also a data-uri is allowed.
|
|
94
|
-
* @type
|
|
91
|
+
* @type string
|
|
95
92
|
*/
|
|
96
93
|
this.url = url;
|
|
97
94
|
|
|
@@ -269,7 +266,7 @@ define([
|
|
|
269
266
|
return this;
|
|
270
267
|
},
|
|
271
268
|
|
|
272
|
-
//
|
|
269
|
+
// Documented in element.js
|
|
273
270
|
getParents: function () {
|
|
274
271
|
var p = [this.url, [this.Z(), this.X(), this.Y()], this.usrSize];
|
|
275
272
|
|
|
@@ -291,7 +288,7 @@ define([
|
|
|
291
288
|
* @returns {JXG.GeometryElement} A reference to the element
|
|
292
289
|
*
|
|
293
290
|
* @example
|
|
294
|
-
* var im = board.create('image', ['
|
|
291
|
+
* var im = board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg',
|
|
295
292
|
* [-3,-2], [3,3]]);
|
|
296
293
|
* im.setSize(4, 4);
|
|
297
294
|
* board.update();
|
|
@@ -301,7 +298,7 @@ define([
|
|
|
301
298
|
* (function() {
|
|
302
299
|
* var board = JXG.JSXGraph.initBoard('JXG8411e60c-f009-11e5-b1bf-901b0e1b8723',
|
|
303
300
|
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
304
|
-
* var im = board.create('image', ['
|
|
301
|
+
* var im = board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg', [-3,-2], [3,3]]);
|
|
305
302
|
* //im.setSize(4, 4);
|
|
306
303
|
* //board.update();
|
|
307
304
|
*
|
|
@@ -311,7 +308,7 @@ define([
|
|
|
311
308
|
*
|
|
312
309
|
* @example
|
|
313
310
|
* var p0 = board.create('point', [-3, -2]),
|
|
314
|
-
* im = board.create('image', ['
|
|
311
|
+
* im = board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg',
|
|
315
312
|
* [function(){ return p0.X(); }, function(){ return p0.Y(); }],
|
|
316
313
|
* [3,3]]),
|
|
317
314
|
* p1 = board.create('point', [1, 2]);
|
|
@@ -325,7 +322,7 @@ define([
|
|
|
325
322
|
* var board = JXG.JSXGraph.initBoard('JXG4ce706c0-f00a-11e5-b1bf-901b0e1b8723',
|
|
326
323
|
* {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
|
|
327
324
|
* var p0 = board.create('point', [-3, -2]),
|
|
328
|
-
* im = board.create('image', ['
|
|
325
|
+
* im = board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg',
|
|
329
326
|
* [function(){ return p0.X(); }, function(){ return p0.Y(); }],
|
|
330
327
|
* [3,3]]),
|
|
331
328
|
* p1 = board.create('point', [1, 2]);
|
|
@@ -382,12 +379,12 @@ define([
|
|
|
382
379
|
* <p>
|
|
383
380
|
* The array size defines the image's width and height in user coordinates.
|
|
384
381
|
* @example
|
|
385
|
-
* var im = board.create('image', ['
|
|
382
|
+
* var im = board.create('image', ['https://jsxgraph.org/jsxgraph/distrib/images/uccellino.jpg', [-3,-2], [3,3]]);
|
|
386
383
|
*
|
|
387
384
|
* </pre><div class="jxgbox" id="JXG9850cda0-7ea0-4750-981c-68bacf9cca57" style="width: 400px; height: 400px;"></div>
|
|
388
385
|
* <script type="text/javascript">
|
|
389
386
|
* var image_board = JXG.JSXGraph.initBoard('JXG9850cda0-7ea0-4750-981c-68bacf9cca57', {boundingbox: [-4, 4, 4, -4], axis: true, showcopyright: false, shownavigation: false});
|
|
390
|
-
* var image_im = image_board.create('image', ['
|
|
387
|
+
* var image_im = image_board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg', [-3,-2],[3,3]]);
|
|
391
388
|
* </script><pre>
|
|
392
389
|
*/
|
|
393
390
|
JXG.createImage = function (board, parents, attributes) {
|
package/src/base/line.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright 2008-
|
|
2
|
+
Copyright 2008-2022
|
|
3
3
|
Matthias Ehmann,
|
|
4
4
|
Michael Gerhaeuser,
|
|
5
5
|
Carsten Miller,
|
|
@@ -1466,14 +1466,36 @@ define([
|
|
|
1466
1466
|
// this is required for the geogebra reader to display a slope
|
|
1467
1467
|
tangent.glider = p;
|
|
1468
1468
|
} else { // curveType 'plot'
|
|
1469
|
-
//
|
|
1469
|
+
// In case of bezierDegree == 1:
|
|
1470
|
+
// Find two points p1, p2 enclosing the glider.
|
|
1471
|
+
// Then the equation of the line segment is: 0 = y*(x1-x2) + x*(y2-y1) + y1*x2-x1*y2,
|
|
1472
|
+
// which is the cross product of p1 and p2.
|
|
1473
|
+
//
|
|
1474
|
+
// In case of bezieDegree === 3:
|
|
1475
|
+
// The slope dy / dx of the tangent is determined. Then the
|
|
1476
|
+
// tangent is computed as cross product between
|
|
1477
|
+
// the glider p and [1, p.X() + dx, p.Y() + dy]
|
|
1478
|
+
//
|
|
1470
1479
|
tangent = board.create('line', [
|
|
1471
1480
|
function () {
|
|
1472
1481
|
var i = Math.floor(p.position),
|
|
1473
|
-
p1, p2;
|
|
1482
|
+
p1, p2, t, A, B, C, D, dx, dy, d;
|
|
1474
1483
|
|
|
1475
|
-
if (
|
|
1476
|
-
i
|
|
1484
|
+
if (c.bezierDegree === 1) {
|
|
1485
|
+
if (i === c.numberPoints - 1) {
|
|
1486
|
+
i--;
|
|
1487
|
+
}
|
|
1488
|
+
} else if (c.bezierDegree === 3) {
|
|
1489
|
+
// i is start of the Bezier segment
|
|
1490
|
+
// t is the position in the Bezier segment
|
|
1491
|
+
i = Math.floor(p.position * (c.numberPoints - 1) / 3) * 3;
|
|
1492
|
+
t = (p.position * (c.numberPoints - 1) - i) / 3;
|
|
1493
|
+
if (i >= c.numberPoints - 1) {
|
|
1494
|
+
i = c.numberPoints - 4;
|
|
1495
|
+
t = 1;
|
|
1496
|
+
}
|
|
1497
|
+
} else {
|
|
1498
|
+
return 0;
|
|
1477
1499
|
}
|
|
1478
1500
|
|
|
1479
1501
|
if (i < 0) {
|
|
@@ -1482,17 +1504,43 @@ define([
|
|
|
1482
1504
|
|
|
1483
1505
|
// The curve points are transformed (if there is a transformation)
|
|
1484
1506
|
// c.X(i) is not transformed.
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1507
|
+
if (c.bezierDegree === 1) {
|
|
1508
|
+
p1 = c.points[i].usrCoords;
|
|
1509
|
+
p2 = c.points[i + 1].usrCoords;
|
|
1510
|
+
} else {
|
|
1511
|
+
A = c.points[i].usrCoords;
|
|
1512
|
+
B = c.points[i + 1].usrCoords;
|
|
1513
|
+
C = c.points[i + 2].usrCoords;
|
|
1514
|
+
D = c.points[i + 3].usrCoords;
|
|
1515
|
+
dx = (1 - t) * (1 - t) * (B[1] - A[1]) + 2 * (1 - t) * t * (C[1] - B[1]) + t * t * (D[1]- C[1]);
|
|
1516
|
+
dy = (1 - t) * (1 - t) * (B[2] - A[2]) + 2 * (1 - t) * t * (C[2] - B[2]) + t * t * (D[2]- C[2]);
|
|
1517
|
+
d = Math.sqrt(dx * dx + dy * dy);
|
|
1518
|
+
dx /= d;
|
|
1519
|
+
dy /= d;
|
|
1520
|
+
p1 = p.coords.usrCoords;
|
|
1521
|
+
p2 = [1, p1[1] + dx, p1[2] + dy];
|
|
1522
|
+
}
|
|
1523
|
+
return p1[2] * p2[1] - p1[1] * p2[2];
|
|
1489
1524
|
},
|
|
1490
1525
|
function () {
|
|
1491
1526
|
var i = Math.floor(p.position),
|
|
1492
|
-
p1, p2;
|
|
1527
|
+
p1, p2, t, A, B, C, D, dx, dy, d;
|
|
1493
1528
|
|
|
1494
|
-
if (
|
|
1495
|
-
i
|
|
1529
|
+
if (c.bezierDegree === 1) {
|
|
1530
|
+
if (i === c.numberPoints - 1) {
|
|
1531
|
+
i--;
|
|
1532
|
+
}
|
|
1533
|
+
} else if (c.bezierDegree === 3) {
|
|
1534
|
+
// i is start of the Bezier segment
|
|
1535
|
+
// t is the position in the Bezier segment
|
|
1536
|
+
i = Math.floor(p.position * (c.numberPoints - 1) / 3) * 3;
|
|
1537
|
+
t = (p.position * (c.numberPoints - 1) - i) / 3;
|
|
1538
|
+
if (i >= c.numberPoints - 1) {
|
|
1539
|
+
i = c.numberPoints - 4;
|
|
1540
|
+
t = 1;
|
|
1541
|
+
}
|
|
1542
|
+
} else {
|
|
1543
|
+
return 0;
|
|
1496
1544
|
}
|
|
1497
1545
|
|
|
1498
1546
|
if (i < 0) {
|
|
@@ -1501,17 +1549,43 @@ define([
|
|
|
1501
1549
|
|
|
1502
1550
|
// The curve points are transformed (if there is a transformation)
|
|
1503
1551
|
// c.X(i) is not transformed.
|
|
1504
|
-
|
|
1505
|
-
|
|
1552
|
+
if (c.bezierDegree === 1) {
|
|
1553
|
+
p1 = c.points[i].usrCoords;
|
|
1554
|
+
p2 = c.points[i + 1].usrCoords;
|
|
1555
|
+
} else {
|
|
1556
|
+
A = c.points[i].usrCoords;
|
|
1557
|
+
B = c.points[i + 1].usrCoords;
|
|
1558
|
+
C = c.points[i + 2].usrCoords;
|
|
1559
|
+
D = c.points[i + 3].usrCoords;
|
|
1560
|
+
dx = (1 - t) * (1 - t) * (B[1] - A[1]) + 2 * (1 - t) * t * (C[1] - B[1]) + t * t * (D[1]- C[1]);
|
|
1561
|
+
dy = (1 - t) * (1 - t) * (B[2] - A[2]) + 2 * (1 - t) * t * (C[2] - B[2]) + t * t * (D[2]- C[2]);
|
|
1562
|
+
d = Math.sqrt(dx * dx + dy * dy);
|
|
1563
|
+
dx /= d;
|
|
1564
|
+
dy /= d;
|
|
1565
|
+
p1 = p.coords.usrCoords;
|
|
1566
|
+
p2 = [1, p1[1] + dx, p1[2] + dy];
|
|
1567
|
+
}
|
|
1506
1568
|
return p2[2] - p1[2];
|
|
1507
|
-
// return c.Y(i + 1) - c.Y(i);
|
|
1508
1569
|
},
|
|
1509
1570
|
function () {
|
|
1510
1571
|
var i = Math.floor(p.position),
|
|
1511
|
-
p1, p2;
|
|
1572
|
+
p1, p2, t, A, B, C, D, dx, dy, d;
|
|
1512
1573
|
|
|
1513
|
-
if (
|
|
1514
|
-
i
|
|
1574
|
+
if (c.bezierDegree === 1) {
|
|
1575
|
+
if (i === c.numberPoints - 1) {
|
|
1576
|
+
i--;
|
|
1577
|
+
}
|
|
1578
|
+
} else if (c.bezierDegree === 3) {
|
|
1579
|
+
// i is start of the Bezier segment
|
|
1580
|
+
// t is the position in the Bezier segment
|
|
1581
|
+
i = Math.floor(p.position * (c.numberPoints - 1) / 3) * 3;
|
|
1582
|
+
t = (p.position * (c.numberPoints - 1) - i) / 3;
|
|
1583
|
+
if (i >= c.numberPoints - 1) {
|
|
1584
|
+
i = c.numberPoints - 4;
|
|
1585
|
+
t = 1;
|
|
1586
|
+
}
|
|
1587
|
+
} else {
|
|
1588
|
+
return 0;
|
|
1515
1589
|
}
|
|
1516
1590
|
|
|
1517
1591
|
if (i < 0) {
|
|
@@ -1520,10 +1594,23 @@ define([
|
|
|
1520
1594
|
|
|
1521
1595
|
// The curve points are transformed (if there is a transformation)
|
|
1522
1596
|
// c.X(i) is not transformed.
|
|
1523
|
-
|
|
1524
|
-
|
|
1597
|
+
if (c.bezierDegree === 1) {
|
|
1598
|
+
p1 = c.points[i].usrCoords;
|
|
1599
|
+
p2 = c.points[i + 1].usrCoords;
|
|
1600
|
+
} else {
|
|
1601
|
+
A = c.points[i].usrCoords;
|
|
1602
|
+
B = c.points[i + 1].usrCoords;
|
|
1603
|
+
C = c.points[i + 2].usrCoords;
|
|
1604
|
+
D = c.points[i + 3].usrCoords;
|
|
1605
|
+
dx = (1 - t) * (1 - t) * (B[1] - A[1]) + 2 * (1 - t) * t * (C[1] - B[1]) + t * t * (D[1]- C[1]);
|
|
1606
|
+
dy = (1 - t) * (1 - t) * (B[2] - A[2]) + 2 * (1 - t) * t * (C[2] - B[2]) + t * t * (D[2]- C[2]);
|
|
1607
|
+
d = Math.sqrt(dx * dx + dy * dy);
|
|
1608
|
+
dx /= d;
|
|
1609
|
+
dy /= d;
|
|
1610
|
+
p1 = p.coords.usrCoords;
|
|
1611
|
+
p2 = [1, p1[1] + dx, p1[2] + dy];
|
|
1612
|
+
}
|
|
1525
1613
|
return p1[1] - p2[1];
|
|
1526
|
-
// return c.X(i) - c.X(i + 1);
|
|
1527
1614
|
}], attributes);
|
|
1528
1615
|
|
|
1529
1616
|
p.addChild(tangent);
|
package/src/base/point.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright 2008-
|
|
2
|
+
Copyright 2008-2022
|
|
3
3
|
Matthias Ehmann,
|
|
4
4
|
Michael Gerhaeuser,
|
|
5
5
|
Carsten Miller,
|
|
@@ -156,7 +156,7 @@ define([
|
|
|
156
156
|
* @returns {JXG.CoordsElement} Reference to this object.
|
|
157
157
|
*/
|
|
158
158
|
updateTransform: function (fromParent) {
|
|
159
|
-
var c, i
|
|
159
|
+
var c, i;
|
|
160
160
|
|
|
161
161
|
if (this.transformations.length === 0 || this.baseElement === null) {
|
|
162
162
|
return this;
|
|
@@ -167,21 +167,9 @@ define([
|
|
|
167
167
|
c = this.transformations[0].apply(this.baseElement, 'self');
|
|
168
168
|
this.coords.setCoordinates(Const.COORDS_BY_USER, c);
|
|
169
169
|
} else {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (!fromParent) {
|
|
173
|
-
// The element has been dragged, now we transform the baseElement
|
|
174
|
-
if (this.draggable() && this.baseElement.draggable()) {
|
|
175
|
-
this.transformations[0].update();
|
|
176
|
-
invMat = Mat.inverse(this.transformations[0].matrix);
|
|
177
|
-
c = Mat.matVecMult(invMat, this.coords.usrCoords);
|
|
178
|
-
this.baseElement.coords.setCoordinates(Const.COORDS_BY_USER, c);
|
|
179
|
-
}
|
|
180
|
-
} else {
|
|
181
|
-
c = this.transformations[0].apply(this.baseElement);
|
|
182
|
-
this.coords.setCoordinates(Const.COORDS_BY_USER, c);
|
|
183
|
-
}
|
|
170
|
+
c = this.transformations[0].apply(this.baseElement);
|
|
184
171
|
}
|
|
172
|
+
this.coords.setCoordinates(Const.COORDS_BY_USER, c);
|
|
185
173
|
|
|
186
174
|
for (i = 1; i < this.transformations.length; i++) {
|
|
187
175
|
this.coords.setCoordinates(Const.COORDS_BY_USER, this.transformations[i].apply(this));
|
|
@@ -339,7 +327,7 @@ define([
|
|
|
339
327
|
* 'point on curve = ' + point.isOn(curve) + '<br>' +
|
|
340
328
|
* 'point on polygon = ' + point.isOn(pol) + '<br>';
|
|
341
329
|
* }]);
|
|
342
|
-
*
|
|
330
|
+
*
|
|
343
331
|
* </pre><div id="JXG6c7d7404-758a-44eb-802c-e9644b9fab71" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
344
332
|
* <script type="text/javascript">
|
|
345
333
|
* (function() {
|
|
@@ -351,25 +339,25 @@ define([
|
|
|
351
339
|
* var po = board.create('point', [-1, 0], {color: 'blue'});
|
|
352
340
|
* var curve = board.create('functiongraph', ['sin(x)'], {strokeColor: 'blue'});
|
|
353
341
|
* var pol = board.create('polygon', [[2,2], [4,2], [4,3]], {strokeColor: 'blue'});
|
|
354
|
-
*
|
|
342
|
+
*
|
|
355
343
|
* var point = board.create('point', [-1, 1], {
|
|
356
|
-
*
|
|
344
|
+
* attractors: [line, seg, circ, po, curve, pol],
|
|
357
345
|
* attractorDistance: 0.2
|
|
358
346
|
* });
|
|
359
|
-
*
|
|
347
|
+
*
|
|
360
348
|
* var txt = board.create('text', [-4, 3, function() {
|
|
361
|
-
*
|
|
349
|
+
* return 'point on line: ' + point.isOn(line) + '<br>' +
|
|
362
350
|
* 'point on seg: ' + point.isOn(seg) + '<br>' +
|
|
363
351
|
* 'point on circ = ' + point.isOn(circ) + '<br>' +
|
|
364
352
|
* 'point on point = ' + point.isOn(po) + '<br>' +
|
|
365
353
|
* 'point on curve = ' + point.isOn(curve) + '<br>' +
|
|
366
354
|
* 'point on polygon = ' + point.isOn(pol) + '<br>';
|
|
367
355
|
* }]);
|
|
368
|
-
*
|
|
356
|
+
*
|
|
369
357
|
* })();
|
|
370
|
-
*
|
|
358
|
+
*
|
|
371
359
|
* </script><pre>
|
|
372
|
-
*
|
|
360
|
+
*
|
|
373
361
|
*/
|
|
374
362
|
isOn: function(el, tol) {
|
|
375
363
|
var arr, crds;
|
|
@@ -381,24 +369,32 @@ define([
|
|
|
381
369
|
} else if (el.elementClass === Const.OBJECT_CLASS_LINE) {
|
|
382
370
|
if (el.elType === 'segment' && !Type.evaluate(this.visProp.alwaysintersect)) {
|
|
383
371
|
arr = JXG.Math.Geometry.projectCoordsToSegment(
|
|
384
|
-
|
|
372
|
+
this.coords.usrCoords,
|
|
385
373
|
el.point1.coords.usrCoords,
|
|
386
374
|
el.point2.coords.usrCoords);
|
|
387
375
|
if (arr[1] >= 0 && arr[1] <= 1 &&
|
|
388
376
|
Geometry.distPointLine(this.coords.usrCoords, el.stdform) < tol) {
|
|
389
|
-
|
|
377
|
+
return true;
|
|
390
378
|
} else {
|
|
391
|
-
|
|
379
|
+
return false;
|
|
392
380
|
}
|
|
393
381
|
} else {
|
|
394
382
|
return Geometry.distPointLine(this.coords.usrCoords, el.stdform) < tol;
|
|
395
383
|
}
|
|
396
384
|
} else if (el.elementClass === Const.OBJECT_CLASS_CIRCLE) {
|
|
385
|
+
if (Type.evaluate(el.visProp.hasinnerpoints)) {
|
|
386
|
+
return this.Dist(el.center) < el.Radius() + tol;
|
|
387
|
+
}
|
|
397
388
|
return Math.abs(this.Dist(el.center) - el.Radius()) < tol;
|
|
398
389
|
} else if (el.elementClass === Const.OBJECT_CLASS_CURVE) {
|
|
399
390
|
crds = Geometry.projectPointToCurve(this, el, this.board)[0];
|
|
400
391
|
return Geometry.distance(this.coords.usrCoords, crds.usrCoords, 3) < tol;
|
|
401
392
|
} else if (el.type === Const.OBJECT_TYPE_POLYGON) {
|
|
393
|
+
if (Type.evaluate(el.visProp.hasinnerpoints)) {
|
|
394
|
+
if (el.pnpoly(this.coords.usrCoords[1], this.coords.usrCoords[2], JXG.COORDS_BY_USER)) {
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
402
398
|
arr = Geometry.projectCoordsToPolygon(this.coords.usrCoords, el);
|
|
403
399
|
return Geometry.distance(this.coords.usrCoords, arr, 3) < tol;
|
|
404
400
|
} else if (el.type === Const.OBJECT_TYPE_TURTLE) {
|
|
@@ -410,7 +406,7 @@ define([
|
|
|
410
406
|
return false;
|
|
411
407
|
},
|
|
412
408
|
|
|
413
|
-
//
|
|
409
|
+
// Already documented in GeometryElement
|
|
414
410
|
cloneToBackground: function () {
|
|
415
411
|
var copy = {};
|
|
416
412
|
|
package/src/base/polygon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright 2008-
|
|
2
|
+
Copyright 2008-2022
|
|
3
3
|
Matthias Ehmann,
|
|
4
4
|
Michael Gerhaeuser,
|
|
5
5
|
Carsten Miller,
|
|
@@ -163,6 +163,72 @@ define([
|
|
|
163
163
|
JXG.Polygon.prototype = new GeometryElement();
|
|
164
164
|
|
|
165
165
|
JXG.extend(JXG.Polygon.prototype, /** @lends JXG.Polygon.prototype */ {
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Decides if a point (x,y) is inside of the polygon.
|
|
169
|
+
* Implements W. Randolf Franklin's pnpoly method.
|
|
170
|
+
*
|
|
171
|
+
* See <a href="https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html">https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html</a>.
|
|
172
|
+
*
|
|
173
|
+
* @param {Number} x_in x-coordinate (screen or user coordinates)
|
|
174
|
+
* @param {Number} y_in y-coordinate (screen or user coordinates)
|
|
175
|
+
* @param {Number} coord_type (Optional) the type of coordinates used here.
|
|
176
|
+
* Possible values are <b>JXG.COORDS_BY_USER</b> and <b>JXG.COORDS_BY_SCREEN</b>.
|
|
177
|
+
* Default value is JXG.COORDS_BY_SCREEN
|
|
178
|
+
*
|
|
179
|
+
* @returns {Boolean} if (x,y) is inside of the polygon.
|
|
180
|
+
* @example
|
|
181
|
+
* var pol = board.create('polygon', [[-1,2], [2,2], [-1,4]]);
|
|
182
|
+
* var p = board.create('point', [4, 3]);
|
|
183
|
+
* var txt = board.create('text', [-1, 0.5, function() {
|
|
184
|
+
* return 'Point A is inside of the polygon = ' +
|
|
185
|
+
* pol.pnpoly(p.X(), p.Y(), JXG.COORDS_BY_USER);
|
|
186
|
+
* }]);
|
|
187
|
+
*
|
|
188
|
+
* </pre><div id="JXG7f96aec7-4e3d-4ffc-a3f5-d3f967b6691c" class="jxgbox" style="width: 300px; height: 300px;"></div>
|
|
189
|
+
* <script type="text/javascript">
|
|
190
|
+
* (function() {
|
|
191
|
+
* var board = JXG.JSXGraph.initBoard('JXG7f96aec7-4e3d-4ffc-a3f5-d3f967b6691c',
|
|
192
|
+
* {boundingbox: [-2, 5, 5,-2], axis: true, showcopyright: false, shownavigation: false});
|
|
193
|
+
* var pol = board.create('polygon', [[-1,2], [2,2], [-1,4]]);
|
|
194
|
+
* var p = board.create('point', [4, 3]);
|
|
195
|
+
* var txt = board.create('text', [-1, 0.5, function() {
|
|
196
|
+
* return 'Point A is inside of the polygon = ' + pol.pnpoly(p.X(), p.Y(), JXG.COORDS_BY_USER);
|
|
197
|
+
* }]);
|
|
198
|
+
*
|
|
199
|
+
* })();
|
|
200
|
+
*
|
|
201
|
+
* </script><pre>
|
|
202
|
+
*
|
|
203
|
+
*/
|
|
204
|
+
pnpoly: function(x_in, y_in, coord_type) {
|
|
205
|
+
var i, j, len,
|
|
206
|
+
x, y, crds,
|
|
207
|
+
v = this.vertices,
|
|
208
|
+
isIn = false;
|
|
209
|
+
|
|
210
|
+
if (coord_type === Const.COORDS_BY_USER) {
|
|
211
|
+
crds = new Coords(Const.COORDS_BY_USER, [x_in, y_in], this.board);
|
|
212
|
+
x = crds.scrCoords[1];
|
|
213
|
+
y = crds.scrCoords[2];
|
|
214
|
+
} else {
|
|
215
|
+
x = x_in;
|
|
216
|
+
y = y_in;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
len = this.vertices.length;
|
|
220
|
+
for (i = 0, j = len - 2; i < len - 1; j = i++) {
|
|
221
|
+
if (((v[i].coords.scrCoords[2] > y) !== (v[j].coords.scrCoords[2] > y)) &&
|
|
222
|
+
(x < (v[j].coords.scrCoords[1] - v[i].coords.scrCoords[1]) *
|
|
223
|
+
(y - v[i].coords.scrCoords[2]) / (v[j].coords.scrCoords[2] - v[i].coords.scrCoords[2]) + v[i].coords.scrCoords[1])
|
|
224
|
+
) {
|
|
225
|
+
isIn = !isIn;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return isIn;
|
|
230
|
+
},
|
|
231
|
+
|
|
166
232
|
/**
|
|
167
233
|
* Checks whether (x,y) is near the polygon.
|
|
168
234
|
* @param {Number} x Coordinate in x direction, screen coordinates.
|
|
@@ -170,22 +236,11 @@ define([
|
|
|
170
236
|
* @returns {Boolean} Returns true, if (x,y) is inside or at the boundary the polygon, otherwise false.
|
|
171
237
|
*/
|
|
172
238
|
hasPoint: function (x, y) {
|
|
173
|
-
|
|
174
|
-
var i, j, len, c = false;
|
|
239
|
+
var i, len;
|
|
175
240
|
|
|
176
241
|
if (Type.evaluate(this.visProp.hasinnerpoints)) {
|
|
177
242
|
// All points of the polygon trigger hasPoint: inner and boundary points
|
|
178
|
-
|
|
179
|
-
// W. Randolf Franklin's pnpoly method,
|
|
180
|
-
// see https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html
|
|
181
|
-
for (i = 0, j = len - 2; i < len - 1; j = i++) {
|
|
182
|
-
if (((this.vertices[i].coords.scrCoords[2] > y) !== (this.vertices[j].coords.scrCoords[2] > y)) &&
|
|
183
|
-
(x < (this.vertices[j].coords.scrCoords[1] - this.vertices[i].coords.scrCoords[1]) * (y - this.vertices[i].coords.scrCoords[2]) /
|
|
184
|
-
(this.vertices[j].coords.scrCoords[2] - this.vertices[i].coords.scrCoords[2]) + this.vertices[i].coords.scrCoords[1])) {
|
|
185
|
-
c = !c;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (c) {
|
|
243
|
+
if (this.pnpoly(x, y)) {
|
|
189
244
|
return true;
|
|
190
245
|
}
|
|
191
246
|
}
|
|
@@ -197,12 +252,11 @@ define([
|
|
|
197
252
|
len = this.borders.length;
|
|
198
253
|
for (i = 0; i < len; i++) {
|
|
199
254
|
if (this.borders[i].hasPoint(x, y)) {
|
|
200
|
-
|
|
201
|
-
break;
|
|
255
|
+
return true;
|
|
202
256
|
}
|
|
203
257
|
}
|
|
204
258
|
|
|
205
|
-
return
|
|
259
|
+
return false;
|
|
206
260
|
},
|
|
207
261
|
|
|
208
262
|
/**
|
|
@@ -461,7 +515,7 @@ define([
|
|
|
461
515
|
return box;
|
|
462
516
|
},
|
|
463
517
|
|
|
464
|
-
//
|
|
518
|
+
// Already documented in GeometryElement
|
|
465
519
|
bounds: function () {
|
|
466
520
|
return this.boundingBox();
|
|
467
521
|
},
|
|
@@ -469,6 +523,8 @@ define([
|
|
|
469
523
|
/**
|
|
470
524
|
* This method removes the SVG or VML nodes of the lines and the filled area from the renderer, to remove
|
|
471
525
|
* the object completely you should use {@link JXG.Board#removeObject}.
|
|
526
|
+
*
|
|
527
|
+
* @private
|
|
472
528
|
*/
|
|
473
529
|
remove: function () {
|
|
474
530
|
var i;
|
|
@@ -483,6 +539,7 @@ define([
|
|
|
483
539
|
/**
|
|
484
540
|
* Finds the index to a given point reference.
|
|
485
541
|
* @param {JXG.Point} p Reference to an element of type {@link JXG.Point}
|
|
542
|
+
* @returns {Number} Index of the point or -1.
|
|
486
543
|
*/
|
|
487
544
|
findPoint: function (p) {
|
|
488
545
|
var i;
|