plotboilerplate 1.23.3 → 1.24.0
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 +6 -0
- package/dist/index.esm.js +1390 -265
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/plotboilerplate.browser.min.js +1 -1
- package/dist/plotboilerplate.browser.min.js.map +1 -1
- package/dist/plotboilerplate.js +1264 -99
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +1 -1
- package/src/cjs/BezierPath.d.ts +41 -5
- package/src/cjs/BezierPath.js +52 -2
- package/src/cjs/BezierPath.js.map +1 -1
- package/src/cjs/Bounds.d.ts +67 -3
- package/src/cjs/Bounds.js +101 -3
- package/src/cjs/Bounds.js.map +1 -1
- package/src/cjs/Circle.d.ts +46 -4
- package/src/cjs/Circle.js +82 -3
- package/src/cjs/Circle.js.map +1 -1
- package/src/cjs/CircleSector.d.ts +51 -2
- package/src/cjs/CircleSector.js +112 -3
- package/src/cjs/CircleSector.js.map +1 -1
- package/src/cjs/CubicBezierCurve.d.ts +113 -7
- package/src/cjs/CubicBezierCurve.js +281 -33
- package/src/cjs/CubicBezierCurve.js.map +1 -1
- package/src/cjs/Line.d.ts +38 -3
- package/src/cjs/Line.js +64 -1
- package/src/cjs/Line.js.map +1 -1
- package/src/cjs/PlotBoilerplate.js +2 -9
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +48 -4
- package/src/cjs/Polygon.js +91 -16
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Triangle.d.ts +52 -3
- package/src/cjs/Triangle.js +80 -1
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/VEllipse.d.ts +62 -3
- package/src/cjs/VEllipse.js +181 -17
- package/src/cjs/VEllipse.js.map +1 -1
- package/src/cjs/VEllipseSector.d.ts +86 -2
- package/src/cjs/VEllipseSector.js +148 -4
- package/src/cjs/VEllipseSector.js.map +1 -1
- package/src/cjs/Vector.d.ts +12 -2
- package/src/cjs/Vector.js +15 -2
- package/src/cjs/Vector.js.map +1 -1
- package/src/cjs/VertTuple.d.ts +28 -4
- package/src/cjs/VertTuple.js +36 -3
- package/src/cjs/VertTuple.js.map +1 -1
- package/src/cjs/Vertex.d.ts +17 -2
- package/src/cjs/Vertex.js +18 -1
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/interfaces/core.d.ts +39 -0
- package/src/cjs/interfaces/core.js +2 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- package/src/cjs/utils/algorithms/convexPolygonIncircle.d.ts +2 -1
- package/src/cjs/utils/algorithms/convexPolygonIncircle.js +14 -6
- package/src/cjs/utils/algorithms/convexPolygonIncircle.js.map +1 -1
- package/src/cjs/utils/createRandomizedPolygon.d.ts +14 -0
- package/src/cjs/utils/createRandomizedPolygon.js +32 -0
- package/src/cjs/utils/createRandomizedPolygon.js.map +1 -0
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +9 -7
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +37 -23
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/cjs/utils/helpers/CircleSectorHelper.d.ts +10 -1
- package/src/cjs/utils/helpers/CircleSectorHelper.js +19 -20
- package/src/cjs/utils/helpers/CircleSectorHelper.js.map +1 -1
- package/src/cjs/utils/helpers/VEllipseHelper.d.ts +30 -0
- package/src/cjs/utils/helpers/VEllipseHelper.js +86 -0
- package/src/cjs/utils/helpers/VEllipseHelper.js.map +1 -0
- package/src/cjs/utils/helpers/VEllipseSectorHelper.d.ts +42 -3
- package/src/cjs/utils/helpers/VEllipseSectorHelper.js +107 -25
- package/src/cjs/utils/helpers/VEllipseSectorHelper.js.map +1 -1
- package/src/createDemoDrawables.js +3 -1
- package/src/esm/BezierPath.d.ts +41 -5
- package/src/esm/BezierPath.js +50 -2
- package/src/esm/BezierPath.js.map +1 -1
- package/src/esm/Bounds.d.ts +67 -3
- package/src/esm/Bounds.js +101 -3
- package/src/esm/Bounds.js.map +1 -1
- package/src/esm/Circle.d.ts +46 -4
- package/src/esm/Circle.js +79 -3
- package/src/esm/Circle.js.map +1 -1
- package/src/esm/CircleSector.d.ts +51 -2
- package/src/esm/CircleSector.js +108 -3
- package/src/esm/CircleSector.js.map +1 -1
- package/src/esm/CubicBezierCurve.d.ts +113 -7
- package/src/esm/CubicBezierCurve.js +277 -33
- package/src/esm/CubicBezierCurve.js.map +1 -1
- package/src/esm/Line.d.ts +38 -3
- package/src/esm/Line.js +62 -1
- package/src/esm/Line.js.map +1 -1
- package/src/esm/PlotBoilerplate.js +2 -9
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +48 -4
- package/src/esm/Polygon.js +89 -16
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Triangle.d.ts +52 -3
- package/src/esm/Triangle.js +77 -1
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/VEllipse.d.ts +62 -3
- package/src/esm/VEllipse.js +178 -17
- package/src/esm/VEllipse.js.map +1 -1
- package/src/esm/VEllipseSector.d.ts +86 -2
- package/src/esm/VEllipseSector.js +146 -7
- package/src/esm/VEllipseSector.js.map +1 -1
- package/src/esm/Vector.d.ts +12 -2
- package/src/esm/Vector.js +15 -2
- package/src/esm/Vector.js.map +1 -1
- package/src/esm/VertTuple.d.ts +28 -4
- package/src/esm/VertTuple.js +36 -3
- package/src/esm/VertTuple.js.map +1 -1
- package/src/esm/Vertex.d.ts +17 -2
- package/src/esm/Vertex.js +18 -1
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/interfaces/core.d.ts +39 -0
- package/src/esm/interfaces/core.js +2 -0
- package/src/esm/interfaces/core.js.map +1 -1
- package/src/esm/utils/algorithms/convexPolygonIncircle.d.ts +2 -1
- package/src/esm/utils/algorithms/convexPolygonIncircle.js +15 -7
- package/src/esm/utils/algorithms/convexPolygonIncircle.js.map +1 -1
- package/src/esm/utils/algorithms/createRandomizedPolygon.d.ts +14 -0
- package/src/esm/utils/algorithms/createRandomizedPolygon.js +28 -0
- package/src/esm/utils/algorithms/createRandomizedPolygon.js.map +1 -0
- package/src/esm/utils/createRandomizedPolygon.d.ts +14 -0
- package/src/esm/utils/createRandomizedPolygon.js +28 -0
- package/src/esm/utils/createRandomizedPolygon.js.map +1 -0
- package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +9 -7
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js +35 -22
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/esm/utils/helpers/CircleSectorHelper.d.ts +10 -1
- package/src/esm/utils/helpers/CircleSectorHelper.js +19 -20
- package/src/esm/utils/helpers/CircleSectorHelper.js.map +1 -1
- package/src/esm/utils/helpers/VEllipseHelper.d.ts +30 -0
- package/src/esm/utils/helpers/VEllipseHelper.js +81 -0
- package/src/esm/utils/helpers/VEllipseHelper.js.map +1 -0
- package/src/esm/utils/helpers/VEllipseSectorHelper.d.ts +42 -3
- package/src/esm/utils/helpers/VEllipseSectorHelper.js +106 -24
- package/src/esm/utils/helpers/VEllipseSectorHelper.js.map +1 -1
- package/src/ts/BezierPath.ts +58 -5
- package/src/ts/Bounds.ts +110 -6
- package/src/ts/Circle.ts +87 -5
- package/src/ts/CircleSector.ts +115 -5
- package/src/ts/CubicBezierCurve.ts +332 -42
- package/src/ts/Line.ts +66 -3
- package/src/ts/PlotBoilerplate.ts +3 -9
- package/src/ts/Polygon.ts +103 -22
- package/src/ts/Triangle.ts +85 -3
- package/src/ts/VEllipse.ts +214 -19
- package/src/ts/VEllipseSector.ts +154 -8
- package/src/ts/Vector.ts +16 -2
- package/src/ts/VertTuple.ts +39 -4
- package/src/ts/Vertex.ts +20 -2
- package/src/ts/interfaces/core.ts +42 -0
- package/src/ts/utils/algorithms/convexPolygonIncircle.ts +82 -78
- package/src/ts/utils/createRandomizedPolygon.ts +31 -0
- package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +45 -29
- package/src/ts/utils/helpers/CircleSectorHelper.ts +115 -125
- package/src/ts/utils/helpers/VEllipseHelper.ts +113 -0
- package/src/ts/utils/helpers/VEllipseSectorHelper.ts +142 -25
package/dist/plotboilerplate.js
CHANGED
|
@@ -450,7 +450,10 @@ class AlloyFinger {
|
|
|
450
450
|
* @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
451
451
|
* @modified 2023-10-06 Adding the `BezierPath.toPathPoints()` method.
|
|
452
452
|
* @modified 2023-10-07 Adding the `BezierPath.fromCurve(CubicBezierCurve)` static function.
|
|
453
|
-
* @
|
|
453
|
+
* @modified 2025-04-09 Added the `BezierPath.move` method to match the convention – which just calls `translate`.
|
|
454
|
+
* @modified 2025-04-09 Modified the `BezierPath.translate` method: chaning parameter `Vertex` to more generalized `XYCoords`.
|
|
455
|
+
* @modified 2025-04-14 Class `BezierPath` is now implementing interface `Intersectable`.
|
|
456
|
+
* @version 2.7.0
|
|
454
457
|
*
|
|
455
458
|
* @file BezierPath
|
|
456
459
|
* @public
|
|
@@ -661,7 +664,7 @@ var BezierPath = /** @class */ (function () {
|
|
|
661
664
|
* Move the whole bezier path by the given (x,y)-amount.
|
|
662
665
|
*
|
|
663
666
|
* @method translate
|
|
664
|
-
* @param {
|
|
667
|
+
* @param {XYCoords} amount - The amount to be added (amount.x and amount.y)
|
|
665
668
|
* to each vertex of the curve.
|
|
666
669
|
* @instance
|
|
667
670
|
* @memberof BezierPath
|
|
@@ -680,6 +683,19 @@ var BezierPath = /** @class */ (function () {
|
|
|
680
683
|
this.updateArcLengths();
|
|
681
684
|
return this;
|
|
682
685
|
};
|
|
686
|
+
/**
|
|
687
|
+
* Move the whole bezier path by the given (x,y)-amount.
|
|
688
|
+
*
|
|
689
|
+
* @method move
|
|
690
|
+
* @param {XYCoords} amount - The amount to be added (amount.x and amount.y)
|
|
691
|
+
* to each vertex of the curve.
|
|
692
|
+
* @instance
|
|
693
|
+
* @memberof BezierPath
|
|
694
|
+
* @return {BezierPath} this for chaining
|
|
695
|
+
**/
|
|
696
|
+
BezierPath.prototype.move = function (amount) {
|
|
697
|
+
return this.translate(amount);
|
|
698
|
+
};
|
|
683
699
|
/**
|
|
684
700
|
* Scale the whole bezier path by the given uniform factor.
|
|
685
701
|
*
|
|
@@ -890,6 +906,38 @@ var BezierPath = /** @class */ (function () {
|
|
|
890
906
|
var relativeU = u - uResult.uPart;
|
|
891
907
|
return bCurve.getPerpendicular(relativeU);
|
|
892
908
|
};
|
|
909
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
910
|
+
/**
|
|
911
|
+
* Get all line intersections with this shape.
|
|
912
|
+
*
|
|
913
|
+
* This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
|
|
914
|
+
*
|
|
915
|
+
* @param {VertTuple} line - The line to find intersections with.
|
|
916
|
+
* @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
|
|
917
|
+
* @returns {Array<Vertex>} - An array of all intersections with the shape's outline.
|
|
918
|
+
*/
|
|
919
|
+
BezierPath.prototype.lineIntersections = function (line, inVectorBoundsOnly) {
|
|
920
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
921
|
+
return this.bezierCurves.reduce(function (accu, curCurve) {
|
|
922
|
+
return accu.concat(curCurve.lineIntersections(line, inVectorBoundsOnly));
|
|
923
|
+
}, []);
|
|
924
|
+
};
|
|
925
|
+
/**
|
|
926
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
927
|
+
*
|
|
928
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
929
|
+
*
|
|
930
|
+
* @param line
|
|
931
|
+
* @param lineIntersectionTangents
|
|
932
|
+
* @returns
|
|
933
|
+
*/
|
|
934
|
+
BezierPath.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
935
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
936
|
+
return this.bezierCurves.reduce(function (accu, curCurve) {
|
|
937
|
+
return accu.concat(curCurve.lineIntersectionTangents(line, inVectorBoundsOnly));
|
|
938
|
+
}, []);
|
|
939
|
+
};
|
|
940
|
+
//--- END --- Implement interface `Intersectable`
|
|
893
941
|
/**
|
|
894
942
|
* This is a helper function to locate the curve index for a given
|
|
895
943
|
* absolute path position u.
|
|
@@ -1103,6 +1151,7 @@ var BezierPath = /** @class */ (function () {
|
|
|
1103
1151
|
}
|
|
1104
1152
|
neighbourCurve.updateArcLengths();
|
|
1105
1153
|
};
|
|
1154
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
1106
1155
|
/**
|
|
1107
1156
|
* Get the bounds of this Bézier path.
|
|
1108
1157
|
*
|
|
@@ -1124,6 +1173,7 @@ var BezierPath = /** @class */ (function () {
|
|
|
1124
1173
|
}
|
|
1125
1174
|
return new Bounds_1.Bounds(min, max);
|
|
1126
1175
|
};
|
|
1176
|
+
//--- END --- Implement interface `IBounded`
|
|
1127
1177
|
/**
|
|
1128
1178
|
* Get n 'equally' distributed vertices along this Bézier path.
|
|
1129
1179
|
*
|
|
@@ -1517,7 +1567,11 @@ exports.BezierPath = BezierPath;
|
|
|
1517
1567
|
* @modified 2022-10-09 Added the `fromDimension` function.
|
|
1518
1568
|
* @modified 2022-11-28 Added the `clone` method.
|
|
1519
1569
|
* @modified 2023-09-29 Added the `randomPoint` method.
|
|
1520
|
-
* @
|
|
1570
|
+
* @modified 2025-03-23 Added the `getMinDimension` and `getMaxDimension` methods.
|
|
1571
|
+
* @modified 2025-04-18 Change parameter type in `Bounds.computeFromVertices` from `Vertex` to more general `XYCoords`.
|
|
1572
|
+
* @modified 2025-04-19 Added methods to `Bounds` class: `getNorthPoint`, `getSouthPoint`, `getEastPoint` and `getWestPoint`.
|
|
1573
|
+
* @modified 2025-04-26 Added static method `Bounds.computeFromBoundsSet` to calculate containing bounds for a set of bounding boxes.
|
|
1574
|
+
* @version 1.8.0
|
|
1521
1575
|
**/
|
|
1522
1576
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1523
1577
|
exports.Bounds = void 0;
|
|
@@ -1545,6 +1599,54 @@ var Bounds = /** @class */ (function () {
|
|
|
1545
1599
|
this.width = max.x - min.x;
|
|
1546
1600
|
this.height = max.y - min.y;
|
|
1547
1601
|
}
|
|
1602
|
+
/**
|
|
1603
|
+
* Get the center point of the north bound.
|
|
1604
|
+
*
|
|
1605
|
+
* @method getNorthPoint
|
|
1606
|
+
* @instance
|
|
1607
|
+
* @memberof Bounds
|
|
1608
|
+
* @return {Vertex} The "northmost" centered point of this bounding box.
|
|
1609
|
+
*/
|
|
1610
|
+
Bounds.prototype.getNorthPoint = function () {
|
|
1611
|
+
return new Vertex_1.Vertex(this.min.x + this.width / 2.0, this.min.y);
|
|
1612
|
+
};
|
|
1613
|
+
;
|
|
1614
|
+
/**
|
|
1615
|
+
* Get the center point of the south bound.
|
|
1616
|
+
*
|
|
1617
|
+
* @method getNorthPoint
|
|
1618
|
+
* @instance
|
|
1619
|
+
* @memberof Bounds
|
|
1620
|
+
* @return {Vertex} The "southhmost" centered point of this bounding box.
|
|
1621
|
+
*/
|
|
1622
|
+
Bounds.prototype.getSouthPoint = function () {
|
|
1623
|
+
return new Vertex_1.Vertex(this.min.x + this.width / 2.0, this.max.y);
|
|
1624
|
+
};
|
|
1625
|
+
;
|
|
1626
|
+
/**
|
|
1627
|
+
* Get the center point of the west bound.
|
|
1628
|
+
*
|
|
1629
|
+
* @method getWestPoint
|
|
1630
|
+
* @instance
|
|
1631
|
+
* @memberof Bounds
|
|
1632
|
+
* @return {Vertex} The "westhmost" centered point of this bounding box.
|
|
1633
|
+
*/
|
|
1634
|
+
Bounds.prototype.getWestPoint = function () {
|
|
1635
|
+
return new Vertex_1.Vertex(this.min.x, this.min.y + this.height / 2.0);
|
|
1636
|
+
};
|
|
1637
|
+
;
|
|
1638
|
+
/**
|
|
1639
|
+
* Get the center point of the east bound.
|
|
1640
|
+
*
|
|
1641
|
+
* @method getEastPoint
|
|
1642
|
+
* @instance
|
|
1643
|
+
* @memberof Bounds
|
|
1644
|
+
* @return {Vertex} The "easthmost" centered point of this bounding box.
|
|
1645
|
+
*/
|
|
1646
|
+
Bounds.prototype.getEastPoint = function () {
|
|
1647
|
+
return new Vertex_1.Vertex(this.max.x, this.min.y + this.height / 2.0);
|
|
1648
|
+
};
|
|
1649
|
+
;
|
|
1548
1650
|
/**
|
|
1549
1651
|
* Convert this rectangular bounding box to a polygon with four vertices.
|
|
1550
1652
|
*
|
|
@@ -1567,6 +1669,22 @@ var Bounds = /** @class */ (function () {
|
|
|
1567
1669
|
Bounds.prototype.getCenter = function () {
|
|
1568
1670
|
return new Vertex_1.Vertex(this.min.x + (this.max.x - this.min.x) / 2.0, this.min.y + (this.max.y - this.min.y) / 2);
|
|
1569
1671
|
};
|
|
1672
|
+
/**
|
|
1673
|
+
* Get the minimum of `width` and `height`.
|
|
1674
|
+
*
|
|
1675
|
+
* @returns {number} The value of Math.min( this.width, this.height )
|
|
1676
|
+
*/
|
|
1677
|
+
Bounds.prototype.getMinDimension = function () {
|
|
1678
|
+
return Math.min(this.width, this.height);
|
|
1679
|
+
};
|
|
1680
|
+
/**
|
|
1681
|
+
* Get the minimum of `width` and `height`.
|
|
1682
|
+
*
|
|
1683
|
+
* @returns {number} The value of Math.min( this.width, this.height )
|
|
1684
|
+
*/
|
|
1685
|
+
Bounds.prototype.getMaxDimension = function () {
|
|
1686
|
+
return Math.max(this.width, this.height);
|
|
1687
|
+
};
|
|
1570
1688
|
/**
|
|
1571
1689
|
* Generate a random point inside this bounds object. Safe areas at the border to avoid
|
|
1572
1690
|
* included.
|
|
@@ -1619,12 +1737,13 @@ var Bounds = /** @class */ (function () {
|
|
|
1619
1737
|
* @static
|
|
1620
1738
|
* @method computeFromVertices
|
|
1621
1739
|
* @memberof Bounds
|
|
1622
|
-
* @param {Array<
|
|
1740
|
+
* @param {Array<XYCoords>} vertices - The set of vertices you want to get the bounding box for.
|
|
1623
1741
|
* @return The minimal Bounds for the given vertices.
|
|
1624
1742
|
**/
|
|
1625
1743
|
Bounds.computeFromVertices = function (vertices) {
|
|
1626
|
-
if (vertices.length == 0)
|
|
1744
|
+
if (vertices.length == 0) {
|
|
1627
1745
|
return new Bounds(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(0, 0));
|
|
1746
|
+
}
|
|
1628
1747
|
var xMin = vertices[0].x;
|
|
1629
1748
|
var xMax = vertices[0].x;
|
|
1630
1749
|
var yMin = vertices[0].y;
|
|
@@ -1639,6 +1758,35 @@ var Bounds = /** @class */ (function () {
|
|
|
1639
1758
|
}
|
|
1640
1759
|
return new Bounds(new Vertex_1.Vertex(xMin, yMin), new Vertex_1.Vertex(xMax, yMax));
|
|
1641
1760
|
};
|
|
1761
|
+
/**
|
|
1762
|
+
* Compute the minimal bounding box for a given set of existing bounding boxes.
|
|
1763
|
+
*
|
|
1764
|
+
* An empty vertex array will return an empty bounding box located at (0,0).
|
|
1765
|
+
*
|
|
1766
|
+
* @static
|
|
1767
|
+
* @method computeFromBoundsSet
|
|
1768
|
+
* @memberof Bounds
|
|
1769
|
+
* @param {Array<IBounds>} boundingBoxes - The set of existing bounding boxes to get the containing bounding box for.
|
|
1770
|
+
* @return The minimal Bounds for the given bounds instances.
|
|
1771
|
+
**/
|
|
1772
|
+
Bounds.computeFromBoundsSet = function (boundingBoxes) {
|
|
1773
|
+
if (boundingBoxes.length == 0) {
|
|
1774
|
+
return new Bounds(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(0, 0));
|
|
1775
|
+
}
|
|
1776
|
+
var xMin = boundingBoxes[0].min.x;
|
|
1777
|
+
var xMax = boundingBoxes[0].max.x;
|
|
1778
|
+
var yMin = boundingBoxes[0].min.y;
|
|
1779
|
+
var yMax = boundingBoxes[0].min.y;
|
|
1780
|
+
var bounds;
|
|
1781
|
+
for (var i in boundingBoxes) {
|
|
1782
|
+
bounds = boundingBoxes[i];
|
|
1783
|
+
xMin = Math.min(xMin, bounds.min.x);
|
|
1784
|
+
xMax = Math.max(xMax, bounds.max.x);
|
|
1785
|
+
yMin = Math.min(yMin, bounds.min.y);
|
|
1786
|
+
yMax = Math.max(yMax, bounds.min.y);
|
|
1787
|
+
}
|
|
1788
|
+
return new Bounds(new Vertex_1.Vertex(xMin, yMin), new Vertex_1.Vertex(xMax, yMax));
|
|
1789
|
+
};
|
|
1642
1790
|
/**
|
|
1643
1791
|
* Create a new `Bounds` instance just from `width` and `height`, located at (0,0) or the optionally given origin.
|
|
1644
1792
|
*
|
|
@@ -1675,10 +1823,13 @@ exports.Bounds = Bounds;
|
|
|
1675
1823
|
* @modified 2022-08-15 Added the `containsPoint` function.
|
|
1676
1824
|
* @modified 2022-08-23 Added the `lineIntersection` function.
|
|
1677
1825
|
* @modified 2022-08-23 Added the `closestPoint` function.
|
|
1678
|
-
* @
|
|
1826
|
+
* @modified 2025-04-09 Added the `Circle.move(amount: XYCoords)` method.
|
|
1827
|
+
* @modified 2025-04-16 Class `Circle` now implements interface `Intersectable`.
|
|
1828
|
+
* @version 1.5.0
|
|
1679
1829
|
**/
|
|
1680
1830
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1681
1831
|
exports.Circle = void 0;
|
|
1832
|
+
var Bounds_1 = __webpack_require__(76);
|
|
1682
1833
|
var Line_1 = __webpack_require__(939);
|
|
1683
1834
|
var UIDGenerator_1 = __webpack_require__(938);
|
|
1684
1835
|
var Vector_1 = __webpack_require__(30);
|
|
@@ -1712,6 +1863,19 @@ var Circle = /** @class */ (function () {
|
|
|
1712
1863
|
this.center = center;
|
|
1713
1864
|
this.radius = radius;
|
|
1714
1865
|
}
|
|
1866
|
+
/**
|
|
1867
|
+
* Move the circle by the given amount.
|
|
1868
|
+
*
|
|
1869
|
+
* @method move
|
|
1870
|
+
* @param {XYCoords} amount - The amount to move.
|
|
1871
|
+
* @instance
|
|
1872
|
+
* @memberof Circle
|
|
1873
|
+
* @return {Circle} this for chaining
|
|
1874
|
+
**/
|
|
1875
|
+
Circle.prototype.move = function (amount) {
|
|
1876
|
+
this.center.add(amount);
|
|
1877
|
+
return this;
|
|
1878
|
+
};
|
|
1715
1879
|
/**
|
|
1716
1880
|
* Check if the given circle is fully contained inside this circle.
|
|
1717
1881
|
*
|
|
@@ -1782,7 +1946,21 @@ var Circle = /** @class */ (function () {
|
|
|
1782
1946
|
var pointA = Circle.circleUtils.vertAt(angle, this.radius);
|
|
1783
1947
|
// Construct the perpendicular of the line in point a. Then move relative to center.
|
|
1784
1948
|
return new Vector_1.Vector(pointA, new Vertex_1.Vertex(0, 0)).add(this.center).perp();
|
|
1949
|
+
// return (new Vector(this.center.clone(), pointA).add(pointA) as Vector).perp() as Vector;
|
|
1950
|
+
};
|
|
1951
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
1952
|
+
/**
|
|
1953
|
+
* Get the bounding box (bounds) of this Circle.
|
|
1954
|
+
*
|
|
1955
|
+
* @method getBounds
|
|
1956
|
+
* @instance
|
|
1957
|
+
* @memberof Circle
|
|
1958
|
+
* @return {Bounds} The rectangular bounds of this Circle.
|
|
1959
|
+
**/
|
|
1960
|
+
Circle.prototype.getBounds = function () {
|
|
1961
|
+
return new Bounds_1.Bounds(this.center.clone().subXY(Math.abs(this.radius), Math.abs(this.radius)), this.center.clone().addXY(Math.abs(this.radius), Math.abs(this.radius)));
|
|
1785
1962
|
};
|
|
1963
|
+
//--- END --- Implement interface `Intersectable`
|
|
1786
1964
|
/**
|
|
1787
1965
|
* Calculate the intersection points (if exists) with the given circle.
|
|
1788
1966
|
*
|
|
@@ -1842,7 +2020,7 @@ var Circle = /** @class */ (function () {
|
|
|
1842
2020
|
* @instance
|
|
1843
2021
|
* @memberof Circle
|
|
1844
2022
|
* @param {Vertex} a- The first of the two points defining the line.
|
|
1845
|
-
* @param {
|
|
2023
|
+
* @param {XYCoords} b - The second of the two points defining the line.
|
|
1846
2024
|
* @return {Line|null} The intersection points (as a line) or null if this circle does not intersect the line given.
|
|
1847
2025
|
**/
|
|
1848
2026
|
Circle.prototype.lineIntersection = function (a, b) {
|
|
@@ -1875,8 +2053,57 @@ var Circle = /** @class */ (function () {
|
|
|
1875
2053
|
interA.y = (-det * diff.x + Math.abs(diff.y) * sqrt) / distSquared;
|
|
1876
2054
|
interB.y = (-det * diff.x - Math.abs(diff.y) * sqrt) / distSquared;
|
|
1877
2055
|
return new Line_1.Line(interA.add(this.center), interB.add(this.center));
|
|
1878
|
-
|
|
2056
|
+
};
|
|
2057
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
2058
|
+
/**
|
|
2059
|
+
* Get all line intersections with this circle.
|
|
2060
|
+
*
|
|
2061
|
+
* This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
|
|
2062
|
+
*
|
|
2063
|
+
* @param {VertTuple} line - The line to find intersections with.
|
|
2064
|
+
* @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
|
|
2065
|
+
* @returns {Array<Vertex>} - An array of all intersections with the circle outline.
|
|
2066
|
+
*/
|
|
2067
|
+
Circle.prototype.lineIntersections = function (line, inVectorBoundsOnly) {
|
|
2068
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
2069
|
+
// Find the intersections of all lines inside the edge bounds
|
|
2070
|
+
var intersectioLine = this.lineIntersection(line.a, line.b);
|
|
2071
|
+
if (!intersectioLine) {
|
|
2072
|
+
return [];
|
|
2073
|
+
}
|
|
2074
|
+
if (inVectorBoundsOnly) {
|
|
2075
|
+
// const maxDist = line.length();
|
|
2076
|
+
return [intersectioLine.a, intersectioLine.b].filter(function (vert) { return line.hasPoint(vert, true); });
|
|
2077
|
+
}
|
|
2078
|
+
else {
|
|
2079
|
+
return [intersectioLine.a, intersectioLine.b];
|
|
2080
|
+
}
|
|
1879
2081
|
};
|
|
2082
|
+
/**
|
|
2083
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
2084
|
+
*
|
|
2085
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
2086
|
+
*
|
|
2087
|
+
* @param line
|
|
2088
|
+
* @param lineIntersectionTangents
|
|
2089
|
+
* @returns
|
|
2090
|
+
*/
|
|
2091
|
+
Circle.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
2092
|
+
var _this = this;
|
|
2093
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
2094
|
+
// Find the intersections of all lines plus their tangents inside the circle bounds
|
|
2095
|
+
var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);
|
|
2096
|
+
return interSectionPoints.map(function (vert) {
|
|
2097
|
+
// Calculate angle
|
|
2098
|
+
var lineFromCenter = new Line_1.Line(_this.center, vert);
|
|
2099
|
+
var angle = lineFromCenter.angle();
|
|
2100
|
+
// console.log("angle", (angle / Math.PI) * 180.0);
|
|
2101
|
+
// const angle = Math.random() * Math.PI * 2; // TODO
|
|
2102
|
+
// Calculate tangent at angle
|
|
2103
|
+
return _this.tangentAt(angle);
|
|
2104
|
+
});
|
|
2105
|
+
};
|
|
2106
|
+
//--- END --- Implement interface `Intersectable`
|
|
1880
2107
|
/**
|
|
1881
2108
|
* Calculate the closest point on the outline of this circle to the given point.
|
|
1882
2109
|
*
|
|
@@ -1937,12 +2164,20 @@ exports.Circle = Circle;
|
|
|
1937
2164
|
* @modified 2024-03-08 Added the `containsAngle` method.
|
|
1938
2165
|
* @modified 2024-03-09 Added the `circleSectorIntersection` method to find coherent sector intersections..
|
|
1939
2166
|
* @modified 2024-03-09 Added the `angleAt` method to determine any angle at some ratio.
|
|
2167
|
+
* @modified 2025-04-02 Adding the `CircleSector.lineIntersections` and `CircleSector.lineIntersectionTangents` and implementing `Intersectable`.
|
|
2168
|
+
* @modified 2025-04-09 Adding the `CircleSector.move()` method.
|
|
2169
|
+
* @modified 2025-04-19 Tweaking the `CircleSector.containsAngle` method: all values (input angle, start- and end- angle) are wrapped into [0,2*PI) now.
|
|
2170
|
+
* @modified 2025-04-19 Class `CircleSector` implements interface `Bounded` now (method `getBounds` added).
|
|
1940
2171
|
* @version 1.2.0
|
|
1941
2172
|
**/
|
|
1942
2173
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1943
2174
|
exports.CircleSector = void 0;
|
|
2175
|
+
var Bounds_1 = __webpack_require__(76);
|
|
1944
2176
|
var Circle_1 = __webpack_require__(118);
|
|
2177
|
+
var Line_1 = __webpack_require__(939);
|
|
1945
2178
|
var UIDGenerator_1 = __webpack_require__(938);
|
|
2179
|
+
var Vertex_1 = __webpack_require__(787);
|
|
2180
|
+
var geomutils_1 = __webpack_require__(328);
|
|
1946
2181
|
/**
|
|
1947
2182
|
* @classdesc A simple circle sector: circle, start- and end-angle.
|
|
1948
2183
|
*
|
|
@@ -1972,6 +2207,49 @@ var CircleSector = /** @class */ (function () {
|
|
|
1972
2207
|
this.startAngle = startAngle;
|
|
1973
2208
|
this.endAngle = endAngle;
|
|
1974
2209
|
}
|
|
2210
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
2211
|
+
/**
|
|
2212
|
+
* Get the bounds of this ellipse.
|
|
2213
|
+
*
|
|
2214
|
+
* The bounds are approximated by the underlying segment buffer; the more segment there are,
|
|
2215
|
+
* the more accurate will be the returned bounds.
|
|
2216
|
+
*
|
|
2217
|
+
* @method getBounds
|
|
2218
|
+
* @instance
|
|
2219
|
+
* @memberof VEllipse
|
|
2220
|
+
* @return {Bounds} The bounds of this curve.
|
|
2221
|
+
**/
|
|
2222
|
+
CircleSector.prototype.getBounds = function () {
|
|
2223
|
+
var _self = this;
|
|
2224
|
+
var circleBounds = this.circle.getBounds();
|
|
2225
|
+
// Calculage angles from east, west, north and south box points and check if they are inside
|
|
2226
|
+
var candidates = [
|
|
2227
|
+
circleBounds.getNorthPoint(),
|
|
2228
|
+
circleBounds.getSouthPoint(),
|
|
2229
|
+
circleBounds.getWestPoint(),
|
|
2230
|
+
circleBounds.getEastPoint()
|
|
2231
|
+
].filter(function (point) {
|
|
2232
|
+
// Check for each candidate points if they are contained in this sector. Drop if not.
|
|
2233
|
+
var angle = new Line_1.Line(_self.circle.center, point).angle();
|
|
2234
|
+
return _self.containsAngle(angle);
|
|
2235
|
+
});
|
|
2236
|
+
// Compute bounds and inlcude start end end point (they are definitely part of the bounds)
|
|
2237
|
+
return Bounds_1.Bounds.computeFromVertices(candidates.concat([this.getStartPoint(), this.getEndPoint()]));
|
|
2238
|
+
};
|
|
2239
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
2240
|
+
/**
|
|
2241
|
+
* Move the circle sector by the given amount.
|
|
2242
|
+
*
|
|
2243
|
+
* @method move
|
|
2244
|
+
* @param {XYCoords} amount - The amount to move.
|
|
2245
|
+
* @instance
|
|
2246
|
+
* @memberof CircleSector
|
|
2247
|
+
* @return {CircleSector} this for chaining
|
|
2248
|
+
**/
|
|
2249
|
+
CircleSector.prototype.move = function (amount) {
|
|
2250
|
+
this.circle.move(amount);
|
|
2251
|
+
return this;
|
|
2252
|
+
};
|
|
1975
2253
|
/**
|
|
1976
2254
|
* Checks wether the given angle (must be inside 0 and PI*2) is contained inside this sector.
|
|
1977
2255
|
*
|
|
@@ -1982,12 +2260,22 @@ var CircleSector = /** @class */ (function () {
|
|
|
1982
2260
|
* @return {boolean} True if (and only if) this sector contains the given angle.
|
|
1983
2261
|
*/
|
|
1984
2262
|
CircleSector.prototype.containsAngle = function (angle) {
|
|
1985
|
-
|
|
1986
|
-
|
|
2263
|
+
var wrappedAngle = geomutils_1.geomutils.mapAngleTo2PI(angle);
|
|
2264
|
+
var wrappedStart = geomutils_1.geomutils.mapAngleTo2PI(this.startAngle);
|
|
2265
|
+
var wrappedEnd = geomutils_1.geomutils.mapAngleTo2PI(this.endAngle);
|
|
2266
|
+
// TODO: cleanup
|
|
2267
|
+
// if (this.startAngle <= this.endAngle) {
|
|
2268
|
+
// return angle >= this.startAngle && angle < this.endAngle;
|
|
2269
|
+
// } else {
|
|
2270
|
+
// // startAngle > endAngle
|
|
2271
|
+
// return angle >= this.startAngle || angle < this.endAngle;
|
|
2272
|
+
// }
|
|
2273
|
+
if (wrappedStart <= wrappedEnd) {
|
|
2274
|
+
return wrappedAngle >= wrappedStart && wrappedAngle < wrappedEnd;
|
|
1987
2275
|
}
|
|
1988
2276
|
else {
|
|
1989
2277
|
// startAngle > endAngle
|
|
1990
|
-
return
|
|
2278
|
+
return wrappedAngle >= wrappedStart || wrappedAngle < wrappedEnd;
|
|
1991
2279
|
}
|
|
1992
2280
|
};
|
|
1993
2281
|
/**
|
|
@@ -2081,6 +2369,54 @@ var CircleSector = /** @class */ (function () {
|
|
|
2081
2369
|
}
|
|
2082
2370
|
return resultSector;
|
|
2083
2371
|
};
|
|
2372
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
2373
|
+
/**
|
|
2374
|
+
* Get the line intersections as vectors with this ellipse.
|
|
2375
|
+
*
|
|
2376
|
+
* @method lineIntersections
|
|
2377
|
+
* @instance
|
|
2378
|
+
* @param {VertTuple<Vector> ray - The line/ray to intersect this ellipse with.
|
|
2379
|
+
* @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.
|
|
2380
|
+
* @returns
|
|
2381
|
+
*/
|
|
2382
|
+
CircleSector.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {
|
|
2383
|
+
var _this = this;
|
|
2384
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
2385
|
+
// First get all line intersections from underlying ellipse.
|
|
2386
|
+
var ellipseIntersections = this.circle.lineIntersections(ray, inVectorBoundsOnly);
|
|
2387
|
+
// Drop all intersection points that are not contained in the circle sectors bounds.
|
|
2388
|
+
var tmpLine = new Line_1.Line(this.circle.center, new Vertex_1.Vertex());
|
|
2389
|
+
return ellipseIntersections.filter(function (intersectionPoint) {
|
|
2390
|
+
tmpLine.b.set(intersectionPoint);
|
|
2391
|
+
var lineAngle = tmpLine.angle();
|
|
2392
|
+
return _this.containsAngle(geomutils_1.geomutils.wrapMinMax(lineAngle, 0, Math.PI * 2));
|
|
2393
|
+
});
|
|
2394
|
+
};
|
|
2395
|
+
/**
|
|
2396
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
2397
|
+
*
|
|
2398
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
2399
|
+
*
|
|
2400
|
+
* @param line
|
|
2401
|
+
* @param lineIntersectionTangents
|
|
2402
|
+
* @returns
|
|
2403
|
+
*/
|
|
2404
|
+
CircleSector.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
2405
|
+
var _this = this;
|
|
2406
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
2407
|
+
// Find the intersections of all lines plus their tangents inside the circle bounds
|
|
2408
|
+
var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);
|
|
2409
|
+
return interSectionPoints.map(function (vert) {
|
|
2410
|
+
// Calculate angle
|
|
2411
|
+
var lineFromCenter = new Line_1.Line(_this.circle.center, vert);
|
|
2412
|
+
var angle = lineFromCenter.angle();
|
|
2413
|
+
// console.log("angle", (angle / Math.PI) * 180.0);
|
|
2414
|
+
// const angle = Math.random() * Math.PI * 2; // TODO
|
|
2415
|
+
// Calculate tangent at angle
|
|
2416
|
+
return _this.circle.tangentAt(angle);
|
|
2417
|
+
});
|
|
2418
|
+
};
|
|
2419
|
+
//--- END --- Implement interface `Intersectable`
|
|
2084
2420
|
/**
|
|
2085
2421
|
* This function should invalidate any installed listeners and invalidate this object.
|
|
2086
2422
|
* After calling this function the object might not hold valid data any more and
|
|
@@ -2186,7 +2522,17 @@ exports.CircleSector = CircleSector;
|
|
|
2186
2522
|
* @modified 2022-10-17 The `CubicBezierCurve` class now implements the new `PathSegment` interface.
|
|
2187
2523
|
* @modified 2023-09-30 Added the function `CubicbezierCurve.getSubCurve(number,number)` – similar to `getSubCurveAt(...)` but with absolute position parameters.
|
|
2188
2524
|
* @modified 2023-10-07 Added the `trimEnd`, `trimEndAt`, `trimStart`, `trimStartAt` methods.
|
|
2189
|
-
* @
|
|
2525
|
+
* @modified 2025-04-09 Added the `CubicBezierCurve.move` method to match the convention – which just calls `translate`.
|
|
2526
|
+
* @modified 2025-04-09 Modified the `CubicBezierCurve.translate` method: chaning parameter `Vertex` to more generalized `XYCoords`.
|
|
2527
|
+
* @modified 2025-04-13 Changed visibility of `CubicBezierCurve.utils` from 'private' to 'public'.
|
|
2528
|
+
* @modified 2025-04-13 Added helper function `CubicBezierCurve.utils.bezierCoeffs`.
|
|
2529
|
+
* @modified 2025-04-13 Added helper functopn `CubicBezierCurve.utils.sgn(number)` for division safe sign calculation.
|
|
2530
|
+
* @modified 2025-03-13 Class `CubicBezierCurve` is now implementing interface `Intersectable`.
|
|
2531
|
+
* @modified 2025-04-18 Added evaluation method for cubic Bézier curves `CubicBezierCurve.utils.evaluateT`.
|
|
2532
|
+
* @modified 2025-04-18 Refactored method `CubicBezierCurve.getPointAt` to use `evaluateT`.
|
|
2533
|
+
* @modified 2025-04-18 Fixed the `CubicBezierCurve.getBounds` method: now returning the real bounding box. Before it was an approximated one.
|
|
2534
|
+
* @modified 2025-ß4-18 Added helper methods for bounding box calculation `CubucBezierCurve.util.cubicPolyMinMax` and `cubicPoly`.
|
|
2535
|
+
* @version 2.9.0
|
|
2190
2536
|
*
|
|
2191
2537
|
* @file CubicBezierCurve
|
|
2192
2538
|
* @public
|
|
@@ -2281,7 +2627,7 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2281
2627
|
* Translate the whole curve by the given {x,y} amount: moves all four points.
|
|
2282
2628
|
*
|
|
2283
2629
|
* @method translate
|
|
2284
|
-
* @param {
|
|
2630
|
+
* @param {XYCoords} amount - The amount to translate this curve by.
|
|
2285
2631
|
* @instance
|
|
2286
2632
|
* @memberof CubicBezierCurve
|
|
2287
2633
|
* @return {CubicBezierCurve} this (for chaining).
|
|
@@ -2293,6 +2639,18 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2293
2639
|
this.endPoint.add(amount);
|
|
2294
2640
|
return this;
|
|
2295
2641
|
};
|
|
2642
|
+
/**
|
|
2643
|
+
* Translate the whole curve by the given {x,y} amount: moves all four points.
|
|
2644
|
+
*
|
|
2645
|
+
* @method translate
|
|
2646
|
+
* @param {XYCoords} amount - The amount to translate this curve by.
|
|
2647
|
+
* @instance
|
|
2648
|
+
* @memberof CubicBezierCurve
|
|
2649
|
+
* @return {CubicBezierCurve} this (for chaining).
|
|
2650
|
+
**/
|
|
2651
|
+
CubicBezierCurve.prototype.move = function (amount) {
|
|
2652
|
+
return this.translate(amount);
|
|
2653
|
+
};
|
|
2296
2654
|
/**
|
|
2297
2655
|
* Reverse this curve, means swapping start- and end-point and swapping
|
|
2298
2656
|
* start-control- and end-control-point.
|
|
@@ -2373,6 +2731,9 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2373
2731
|
*
|
|
2374
2732
|
* This function uses a recursive approach by cutting the curve into several linear segments.
|
|
2375
2733
|
*
|
|
2734
|
+
* @method getClosestT
|
|
2735
|
+
* @instance
|
|
2736
|
+
* @memberof CubicBezierCurve
|
|
2376
2737
|
* @param {Vertex} p - The point to find the closest position ('t' on the curve).
|
|
2377
2738
|
* @return {number}
|
|
2378
2739
|
**/
|
|
@@ -2422,27 +2783,35 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2422
2783
|
tNext: tStart + tDiff * (Math.min(stepCount, minIndex + 1) / stepCount)
|
|
2423
2784
|
};
|
|
2424
2785
|
};
|
|
2786
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
2425
2787
|
/**
|
|
2426
2788
|
* Get the bounds of this bezier curve.
|
|
2427
2789
|
*
|
|
2428
2790
|
* The bounds are approximated by the underlying segment buffer; the more segment there are,
|
|
2429
2791
|
* the more accurate will be the returned bounds.
|
|
2430
2792
|
*
|
|
2431
|
-
* @
|
|
2793
|
+
* @method getClosestT
|
|
2794
|
+
* @instance
|
|
2795
|
+
* @memberof CubicBezierCurve
|
|
2796
|
+
* @return {Bounds} The bounds of this ellipse.
|
|
2432
2797
|
**/
|
|
2433
2798
|
CubicBezierCurve.prototype.getBounds = function () {
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
var
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2799
|
+
// Thanks to Richard "RM" for the Bézier bounds calculatin
|
|
2800
|
+
// https://jsfiddle.net/SalixAlba/QQnvm/4/
|
|
2801
|
+
var xMinMax = CubicBezierCurve.utils.cubicPolyMinMax(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x);
|
|
2802
|
+
var xl = xMinMax.min;
|
|
2803
|
+
var xh = xMinMax.max;
|
|
2804
|
+
var yMinMax = CubicBezierCurve.utils.cubicPolyMinMax(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y);
|
|
2805
|
+
var yl = yMinMax.min;
|
|
2806
|
+
var yh = yMinMax.max;
|
|
2807
|
+
return Bounds_1.Bounds.computeFromVertices([
|
|
2808
|
+
{ x: xl, y: yl },
|
|
2809
|
+
{ x: xl, y: yh },
|
|
2810
|
+
{ x: xh, y: yh },
|
|
2811
|
+
{ x: xh, y: yl }
|
|
2812
|
+
]);
|
|
2813
|
+
};
|
|
2814
|
+
//--- END --- Implement interface `IBounded`
|
|
2446
2815
|
/**
|
|
2447
2816
|
* Get the start point of the curve.<br>
|
|
2448
2817
|
* <br>
|
|
@@ -2529,14 +2898,19 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2529
2898
|
**/
|
|
2530
2899
|
CubicBezierCurve.prototype.getPointAt = function (t) {
|
|
2531
2900
|
// Perform some powerful math magic
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2901
|
+
// TODO: cleanup
|
|
2902
|
+
// const x: number =
|
|
2903
|
+
// this.startPoint.x * Math.pow(1.0 - t, 3) +
|
|
2904
|
+
// this.startControlPoint.x * 3 * t * Math.pow(1.0 - t, 2) +
|
|
2905
|
+
// this.endControlPoint.x * 3 * Math.pow(t, 2) * (1.0 - t) +
|
|
2906
|
+
// this.endPoint.x * Math.pow(t, 3);
|
|
2907
|
+
// const y: number =
|
|
2908
|
+
// this.startPoint.y * Math.pow(1.0 - t, 3) +
|
|
2909
|
+
// this.startControlPoint.y * 3 * t * Math.pow(1.0 - t, 2) +
|
|
2910
|
+
// this.endControlPoint.y * 3 * Math.pow(t, 2) * (1.0 - t) +
|
|
2911
|
+
// this.endPoint.y * Math.pow(t, 3);
|
|
2912
|
+
var x = CubicBezierCurve.utils.evaluateT(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x, t);
|
|
2913
|
+
var y = CubicBezierCurve.utils.evaluateT(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y, t);
|
|
2540
2914
|
return new Vertex_1.Vertex(x, y);
|
|
2541
2915
|
};
|
|
2542
2916
|
/**
|
|
@@ -2677,17 +3051,7 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2677
3051
|
* @return {CubicBezierCurve} The sub curve as a new curve.
|
|
2678
3052
|
**/
|
|
2679
3053
|
CubicBezierCurve.prototype.getSubCurveAt = function (tStart, tEnd) {
|
|
2680
|
-
//
|
|
2681
|
-
// const endVec: Vector = new Vector(this.getPointAt(tEnd), this.getTangentAt(tEnd).inv());
|
|
2682
|
-
// // Tangents are relative. Make absolute.
|
|
2683
|
-
// startVec.b.add(startVec.a);
|
|
2684
|
-
// endVec.b.add(endVec.a);
|
|
2685
|
-
// // This 'splits' the curve at the given point at t.
|
|
2686
|
-
// startVec.scale(0.33333333 * (tEnd - tStart));
|
|
2687
|
-
// endVec.scale(0.33333333 * (tEnd - tStart));
|
|
2688
|
-
// // Draw the bezier curve
|
|
2689
|
-
// // pb.draw.cubicBezier( startVec.a, endVec.a, startVec.b, endVec.b, '#8800ff', 2 );
|
|
2690
|
-
// return new CubicBezierCurve(startVec.a, endVec.a, startVec.b, endVec.b);
|
|
3054
|
+
// This 'splits' the curve at the given point at t.
|
|
2691
3055
|
var subCurbePoints = CubicBezierCurve.utils.getSubCurvePointsAt(this, tStart, tEnd);
|
|
2692
3056
|
return new CubicBezierCurve(subCurbePoints[0], subCurbePoints[1], subCurbePoints[2], subCurbePoints[3]);
|
|
2693
3057
|
};
|
|
@@ -2779,6 +3143,73 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2779
3143
|
return this.endControlPoint;
|
|
2780
3144
|
};
|
|
2781
3145
|
//---END PathSegment-------------------------
|
|
3146
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
3147
|
+
/**
|
|
3148
|
+
* Get all line intersections with this shape.
|
|
3149
|
+
*
|
|
3150
|
+
* This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
|
|
3151
|
+
*
|
|
3152
|
+
* @param {VertTuple} line - The line to find intersections with.
|
|
3153
|
+
* @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
|
|
3154
|
+
* @returns {Array<Vertex>} - An array of all intersections with the shape outline.
|
|
3155
|
+
*/
|
|
3156
|
+
CubicBezierCurve.prototype.lineIntersections = function (line, inVectorBoundsOnly) {
|
|
3157
|
+
var _this = this;
|
|
3158
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
3159
|
+
var intersectionTs = this.lineIntersectionTs(line);
|
|
3160
|
+
var intersectionPoints = intersectionTs.map(function (t) {
|
|
3161
|
+
return _this.getPointAt(t);
|
|
3162
|
+
});
|
|
3163
|
+
if (inVectorBoundsOnly) {
|
|
3164
|
+
// const maxDist = line.length();
|
|
3165
|
+
return intersectionPoints.filter(function (vert) { return line.hasPoint(vert, true); });
|
|
3166
|
+
}
|
|
3167
|
+
else {
|
|
3168
|
+
return intersectionPoints;
|
|
3169
|
+
}
|
|
3170
|
+
};
|
|
3171
|
+
/**
|
|
3172
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
3173
|
+
*
|
|
3174
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
3175
|
+
*
|
|
3176
|
+
* @param line
|
|
3177
|
+
* @param lineIntersectionTangents
|
|
3178
|
+
* @returns
|
|
3179
|
+
*/
|
|
3180
|
+
CubicBezierCurve.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
3181
|
+
var _this = this;
|
|
3182
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
3183
|
+
var intersectionTs = this.lineIntersectionTs(line);
|
|
3184
|
+
var intersectionTangents = intersectionTs.map(function (t) {
|
|
3185
|
+
var startPoint = _this.getPointAt(t);
|
|
3186
|
+
var endPoint = _this.getTangentAt(t);
|
|
3187
|
+
return new Vector_1.Vector(startPoint, endPoint.add(startPoint));
|
|
3188
|
+
});
|
|
3189
|
+
if (inVectorBoundsOnly) {
|
|
3190
|
+
return intersectionTangents.filter(function (vec) { return line.hasPoint(vec.a, true); });
|
|
3191
|
+
}
|
|
3192
|
+
else {
|
|
3193
|
+
return intersectionTangents;
|
|
3194
|
+
}
|
|
3195
|
+
};
|
|
3196
|
+
//--- END --- Implement interface `Intersectable`
|
|
3197
|
+
CubicBezierCurve.prototype.lineIntersectionTs = function (line) {
|
|
3198
|
+
var A = line.b.y - line.a.y; // A=y2-y1
|
|
3199
|
+
var B = line.a.x - line.b.x; // B=x1-x2
|
|
3200
|
+
var C = line.a.x * (line.a.y - line.b.y) + line.a.y * (line.b.x - line.a.x); //C=x1*(y1-y2)+y1*(x2-x1)
|
|
3201
|
+
// var bx = bezierCoeffs(px[0], px[1], px[2], px[3]);
|
|
3202
|
+
// var by = bezierCoeffs(py[0], py[1], py[2], py[3]);
|
|
3203
|
+
var bx = CubicBezierCurve.utils.bezierCoeffs(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x);
|
|
3204
|
+
var by = CubicBezierCurve.utils.bezierCoeffs(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y);
|
|
3205
|
+
var poly = Array(4);
|
|
3206
|
+
poly[0] = A * bx[0] + B * by[0]; /*t^3*/
|
|
3207
|
+
poly[1] = A * bx[1] + B * by[1]; /*t^2*/
|
|
3208
|
+
poly[2] = A * bx[2] + B * by[2]; /*t*/
|
|
3209
|
+
poly[3] = A * bx[3] + B * by[3] + C; /*1*/
|
|
3210
|
+
var roots = CubicBezierCurve.utils.cubicRoots(poly);
|
|
3211
|
+
return roots.filter(function (root) { return root != -1; });
|
|
3212
|
+
};
|
|
2782
3213
|
/**
|
|
2783
3214
|
* Check if this and the specified curve are equal.<br>
|
|
2784
3215
|
* <br>
|
|
@@ -2945,6 +3376,71 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2945
3376
|
* Helper utils.
|
|
2946
3377
|
*/
|
|
2947
3378
|
CubicBezierCurve.utils = {
|
|
3379
|
+
evaluateT: function (p0, p1, p2, p3, t) {
|
|
3380
|
+
return p0 * Math.pow(1.0 - t, 3) +
|
|
3381
|
+
p1 * 3 * t * Math.pow(1.0 - t, 2) +
|
|
3382
|
+
p2 * 3 * Math.pow(t, 2) * (1.0 - t) +
|
|
3383
|
+
p3 * Math.pow(t, 3);
|
|
3384
|
+
},
|
|
3385
|
+
cubicPolyMinMax: function (p0, p1, p2, p3) {
|
|
3386
|
+
// var polyX = CubicBezierCurve.utils.cubicPoly2(
|
|
3387
|
+
// p0, // P[0].X, // bezierCurve.startPoint.x,
|
|
3388
|
+
// p1, // P[1].X, // bezierCurve.startControlPoint.x,
|
|
3389
|
+
// p2, // P[2].X, // bezierCurve.endControlPoint.x,
|
|
3390
|
+
// p3 // P[3].X // bezierCurve.endPoint.x
|
|
3391
|
+
// );
|
|
3392
|
+
// var a = polyX.a;
|
|
3393
|
+
// var b = polyX.b;
|
|
3394
|
+
// var c = polyX.c;
|
|
3395
|
+
// var disc = polyX.b * polyX.b - 4 * polyX.a * polyX.c;
|
|
3396
|
+
var polyX = CubicBezierCurve.utils.cubicPoly(p0, // P[0].X, // bezierCurve.startPoint.x,
|
|
3397
|
+
p1, // P[1].X, // bezierCurve.startControlPoint.x,
|
|
3398
|
+
p2, // P[2].X, // bezierCurve.endControlPoint.x,
|
|
3399
|
+
p3 // P[3].X // bezierCurve.endPoint.x
|
|
3400
|
+
);
|
|
3401
|
+
var a = polyX[0]; // .a;
|
|
3402
|
+
var b = polyX[1]; // .b;
|
|
3403
|
+
var c = polyX[2]; // .c;
|
|
3404
|
+
//alert("a "+a+" "+b+" "+c);
|
|
3405
|
+
// var disc = b * b - 4 * a * c;
|
|
3406
|
+
var disc = polyX[1] * polyX[1] - 4 * polyX[0] * polyX[2];
|
|
3407
|
+
// var polyX = CubicBezierCurve.utils.bezierCoeffs(p3,p2,p1,p0);
|
|
3408
|
+
// var a = polyX[0]; //polyX.a;
|
|
3409
|
+
// var b = polyX[1]; // .b;
|
|
3410
|
+
// var c = polyX[2]; //.c;
|
|
3411
|
+
// var disc = polyX[1] * polyX[1] - 4 * polyX[0] * polyX[2];
|
|
3412
|
+
// var xl = Math.min(bCurve.endPoint.x, bCurve.startPoint.x); // P[0].X;
|
|
3413
|
+
// var xh = Math.max(bCurve.endPoint.x, bCurve.startPoint.x); // P[0].X;
|
|
3414
|
+
var xl = Math.min(p3, p0); // P[0].X;
|
|
3415
|
+
var xh = Math.max(p3, p0); // P[0].X;
|
|
3416
|
+
// if (P[3].X < xl) xl = P[3].X;
|
|
3417
|
+
// if (P[3].X > xh) xh = P[3].X;
|
|
3418
|
+
if (disc >= 0) {
|
|
3419
|
+
var t1 = (-b + Math.sqrt(disc)) / (2 * a);
|
|
3420
|
+
// alert("t1 " + t1);
|
|
3421
|
+
if (t1 > 0 && t1 < 1) {
|
|
3422
|
+
// var x1 = evalBez(PX, t1);
|
|
3423
|
+
// var x1 = bCurve.getPointAt(t1).x;
|
|
3424
|
+
var x1 = CubicBezierCurve.utils.evaluateT(p0, p1, p2, p3, t1); // bCurve.getPointAt(t1).x;
|
|
3425
|
+
if (x1 < xl)
|
|
3426
|
+
xl = x1;
|
|
3427
|
+
if (x1 > xh)
|
|
3428
|
+
xh = x1;
|
|
3429
|
+
}
|
|
3430
|
+
var t2 = (-b - Math.sqrt(disc)) / (2 * a);
|
|
3431
|
+
// alert("t2 " + t2);
|
|
3432
|
+
if (t2 > 0 && t2 < 1) {
|
|
3433
|
+
// var x2 = evalBez(PX, t2);
|
|
3434
|
+
// var x2 = bCurve.getPointAt(t2).x;
|
|
3435
|
+
var x2 = CubicBezierCurve.utils.evaluateT(p0, p1, p2, p3, t2); //
|
|
3436
|
+
if (x2 < xl)
|
|
3437
|
+
xl = x2;
|
|
3438
|
+
if (x2 > xh)
|
|
3439
|
+
xh = x2;
|
|
3440
|
+
}
|
|
3441
|
+
}
|
|
3442
|
+
return { min: xl, max: xh };
|
|
3443
|
+
},
|
|
2948
3444
|
/**
|
|
2949
3445
|
* Get the points of a sub curve at the given start end end offsets (values between 0.0 and 1.0).
|
|
2950
3446
|
*
|
|
@@ -2968,6 +3464,94 @@ var CubicBezierCurve = /** @class */ (function () {
|
|
|
2968
3464
|
startVec.scale(0.33333333 * (tEnd - tStart));
|
|
2969
3465
|
endVec.scale(0.33333333 * (tEnd - tStart));
|
|
2970
3466
|
return [startVec.a, endVec.a, startVec.b, endVec.b];
|
|
3467
|
+
},
|
|
3468
|
+
/**
|
|
3469
|
+
* Compute the cubic roots for the given cubic polynomial coefficients.
|
|
3470
|
+
*
|
|
3471
|
+
* Based on
|
|
3472
|
+
* http://mysite.verizon.net/res148h4j/javascript/script_exact_cubic.html#the%20source%20code
|
|
3473
|
+
* Inspired by
|
|
3474
|
+
* https://www.particleincell.com/2013/cubic-line-intersection/
|
|
3475
|
+
* Thanks to Stephan Schmitt and Particle-In-Cell!
|
|
3476
|
+
*
|
|
3477
|
+
* @param poly
|
|
3478
|
+
* @returns
|
|
3479
|
+
*/
|
|
3480
|
+
cubicRoots: function (poly) {
|
|
3481
|
+
var a = poly[0];
|
|
3482
|
+
var b = poly[1];
|
|
3483
|
+
var c = poly[2];
|
|
3484
|
+
var d = poly[3];
|
|
3485
|
+
var A = b / a;
|
|
3486
|
+
var B = c / a;
|
|
3487
|
+
var C = d / a;
|
|
3488
|
+
var S, T, Im;
|
|
3489
|
+
var Q = (3 * B - Math.pow(A, 2)) / 9;
|
|
3490
|
+
var R = (9 * A * B - 27 * C - 2 * Math.pow(A, 3)) / 54;
|
|
3491
|
+
var D = Math.pow(Q, 3) + Math.pow(R, 2); // polynomial discriminant
|
|
3492
|
+
var ts = []; // Array();
|
|
3493
|
+
if (D >= 0) {
|
|
3494
|
+
// complex or duplicate roots
|
|
3495
|
+
S = CubicBezierCurve.utils.sgn(R + Math.sqrt(D)) * Math.pow(Math.abs(R + Math.sqrt(D)), 1 / 3);
|
|
3496
|
+
T = CubicBezierCurve.utils.sgn(R - Math.sqrt(D)) * Math.pow(Math.abs(R - Math.sqrt(D)), 1 / 3);
|
|
3497
|
+
ts[0] = -A / 3 + (S + T); // real root
|
|
3498
|
+
ts[1] = -A / 3 - (S + T) / 2; // real part of complex root
|
|
3499
|
+
ts[2] = -A / 3 - (S + T) / 2; // real part of complex root
|
|
3500
|
+
Im = Math.abs((Math.sqrt(3) * (S - T)) / 2); // complex part of root pair
|
|
3501
|
+
// Mark complex roots to be discarded
|
|
3502
|
+
if (Im != 0) {
|
|
3503
|
+
ts[1] = -1;
|
|
3504
|
+
ts[2] = -1;
|
|
3505
|
+
}
|
|
3506
|
+
} // distinct real roots
|
|
3507
|
+
else {
|
|
3508
|
+
var th = Math.acos(R / Math.sqrt(-Math.pow(Q, 3)));
|
|
3509
|
+
ts[0] = 2 * Math.sqrt(-Q) * Math.cos(th / 3) - A / 3;
|
|
3510
|
+
ts[1] = 2 * Math.sqrt(-Q) * Math.cos((th + 2 * Math.PI) / 3) - A / 3;
|
|
3511
|
+
ts[2] = 2 * Math.sqrt(-Q) * Math.cos((th + 4 * Math.PI) / 3) - A / 3;
|
|
3512
|
+
Im = 0.0;
|
|
3513
|
+
}
|
|
3514
|
+
// Discard all t's out of spec and sort the rest
|
|
3515
|
+
return ts.filter(function (t) { return t >= 0 && t <= 1.0; }).sort();
|
|
3516
|
+
},
|
|
3517
|
+
/**
|
|
3518
|
+
* Compute the Bézier coefficients from the given Bézier point coordinates.
|
|
3519
|
+
*
|
|
3520
|
+
* @param {number} p0 - The start point coordinate.
|
|
3521
|
+
* @param {number} p1 - The start control point coordinate.
|
|
3522
|
+
* @param {number} p2 - The end control point coordinate.
|
|
3523
|
+
* @param {number} p3 - The end point coordinate.
|
|
3524
|
+
* @returns {[number,number,number,number]}
|
|
3525
|
+
*/
|
|
3526
|
+
bezierCoeffs: function (p0, p1, p2, p3) {
|
|
3527
|
+
var coeffs = [NaN, NaN, NaN, NaN]; //Array(4);
|
|
3528
|
+
coeffs[0] = -p0 + 3 * p1 + -3 * p2 + p3;
|
|
3529
|
+
coeffs[1] = 3 * p0 - 6 * p1 + 3 * p2;
|
|
3530
|
+
coeffs[2] = -3 * p0 + 3 * p1;
|
|
3531
|
+
coeffs[3] = p0;
|
|
3532
|
+
return coeffs;
|
|
3533
|
+
},
|
|
3534
|
+
/**
|
|
3535
|
+
* Calculate the cubic polynomial coefficients used to find the bounding box.
|
|
3536
|
+
*
|
|
3537
|
+
* @param {number} p0 - The start point coordinate.
|
|
3538
|
+
* @param {number} p1 - The start control point coordinate.
|
|
3539
|
+
* @param {number} p2 - The end control point coordinate.
|
|
3540
|
+
* @param {number} p3 - The end point coordinate.
|
|
3541
|
+
* @returns {[number,number,number]}
|
|
3542
|
+
*/
|
|
3543
|
+
cubicPoly: function (p0, p1, p2, p3) {
|
|
3544
|
+
return [
|
|
3545
|
+
3 * p3 - 9 * p2 + 9 * p1 - 3 * p0,
|
|
3546
|
+
6 * p0 - 12 * p1 + 6 * p2,
|
|
3547
|
+
3 * p1 - 3 * p0
|
|
3548
|
+
];
|
|
3549
|
+
},
|
|
3550
|
+
/**
|
|
3551
|
+
* sign of number, but is division safe: no zero returned :)
|
|
3552
|
+
*/
|
|
3553
|
+
sgn: function (x) {
|
|
3554
|
+
return x < 0.0 ? -1 : 1;
|
|
2971
3555
|
}
|
|
2972
3556
|
};
|
|
2973
3557
|
return CubicBezierCurve;
|
|
@@ -3536,7 +4120,9 @@ exports.KeyHandler = KeyHandler;
|
|
|
3536
4120
|
* @modified 2022-10-09 Changed the actual return value of the `intersection` function to null (was undefined before).
|
|
3537
4121
|
* @modified 2022-10-17 Adding these methods from the `PathSegment` interface: getStartPoint, getEndPoint, revert.
|
|
3538
4122
|
* @modified 2023-09-25 Changed param type of `intersection()` from Line to VertTuple.
|
|
3539
|
-
* @
|
|
4123
|
+
* @modified 2025-04-15 Class `Line` now implements interface `Intersectable`.
|
|
4124
|
+
* @modified 2025-04-16 Class `Line` now implements interface `IBounded`.
|
|
4125
|
+
* @version 2.4.0
|
|
3540
4126
|
*
|
|
3541
4127
|
* @file Line
|
|
3542
4128
|
* @public
|
|
@@ -3558,6 +4144,8 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
3558
4144
|
})();
|
|
3559
4145
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3560
4146
|
exports.Line = void 0;
|
|
4147
|
+
var Bounds_1 = __webpack_require__(76);
|
|
4148
|
+
var Vector_1 = __webpack_require__(30);
|
|
3561
4149
|
var VertTuple_1 = __webpack_require__(590);
|
|
3562
4150
|
var Vertex_1 = __webpack_require__(787);
|
|
3563
4151
|
/**
|
|
@@ -3616,6 +4204,19 @@ var Line = /** @class */ (function (_super) {
|
|
|
3616
4204
|
// if we cast these lines infinitely in both directions, they intersect here:
|
|
3617
4205
|
return new Vertex_1.Vertex(x, y);
|
|
3618
4206
|
};
|
|
4207
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
4208
|
+
/**
|
|
4209
|
+
* Get the bounding box (bounds) of this Line.
|
|
4210
|
+
*
|
|
4211
|
+
* @method getBounds
|
|
4212
|
+
* @instance
|
|
4213
|
+
* @memberof Line
|
|
4214
|
+
* @return {Bounds} The rectangular bounds of this Line.
|
|
4215
|
+
**/
|
|
4216
|
+
Line.prototype.getBounds = function () {
|
|
4217
|
+
return Bounds_1.Bounds.computeFromVertices([this.a, this.b]);
|
|
4218
|
+
};
|
|
4219
|
+
//--- END --- Implement interface `IBounded`
|
|
3619
4220
|
//--- Implement PathSegment ---
|
|
3620
4221
|
/**
|
|
3621
4222
|
* Get the start point of this path segment.
|
|
@@ -3670,6 +4271,52 @@ var Line = /** @class */ (function (_super) {
|
|
|
3670
4271
|
this.b = tmp;
|
|
3671
4272
|
return this;
|
|
3672
4273
|
};
|
|
4274
|
+
//--- END Implement PathSegment ---
|
|
4275
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
4276
|
+
/**
|
|
4277
|
+
* Get all line intersections with this polygon.
|
|
4278
|
+
*
|
|
4279
|
+
* This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
|
|
4280
|
+
*
|
|
4281
|
+
* See demo `47-closest-vector-projection-on-polygon` for how it works.
|
|
4282
|
+
*
|
|
4283
|
+
* @param {VertTuple} line - The line to find intersections with.
|
|
4284
|
+
* @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
|
|
4285
|
+
* @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.
|
|
4286
|
+
*/
|
|
4287
|
+
Line.prototype.lineIntersections = function (line, inVectorBoundsOnly) {
|
|
4288
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
4289
|
+
// Find the intersections of all lines inside the edge bounds
|
|
4290
|
+
var intersection = this.intersection(line);
|
|
4291
|
+
if (!intersection) {
|
|
4292
|
+
return []; // Both lines parallel
|
|
4293
|
+
}
|
|
4294
|
+
if (this.hasPoint(intersection, true) && (!inVectorBoundsOnly || line.hasPoint(intersection, inVectorBoundsOnly))) {
|
|
4295
|
+
return [intersection];
|
|
4296
|
+
}
|
|
4297
|
+
else {
|
|
4298
|
+
return [];
|
|
4299
|
+
}
|
|
4300
|
+
};
|
|
4301
|
+
/**
|
|
4302
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
4303
|
+
*
|
|
4304
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
4305
|
+
*
|
|
4306
|
+
* @param line
|
|
4307
|
+
* @param inVectorBoundsOnly
|
|
4308
|
+
* @returns
|
|
4309
|
+
*/
|
|
4310
|
+
Line.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
4311
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
4312
|
+
// Find the intersection tangents of all lines inside the edge bounds
|
|
4313
|
+
var intersections = this.lineIntersections(line, inVectorBoundsOnly);
|
|
4314
|
+
if (intersections.length === 0) {
|
|
4315
|
+
return [];
|
|
4316
|
+
}
|
|
4317
|
+
var intrsctn = intersections[0];
|
|
4318
|
+
return [new Vector_1.Vector(this.a.clone(), this.b.clone()).moveTo(intrsctn)];
|
|
4319
|
+
};
|
|
3673
4320
|
return Line;
|
|
3674
4321
|
}(VertTuple_1.VertTuple));
|
|
3675
4322
|
exports.Line = Line;
|
|
@@ -5312,18 +5959,17 @@ var PlotBoilerplate = /** @class */ (function () {
|
|
|
5312
5959
|
}
|
|
5313
5960
|
else if (d instanceof Triangle_1.Triangle) {
|
|
5314
5961
|
draw.polyline([d.a, d.b, d.c], false, this.drawConfig.triangle.color, this.drawConfig.triangle.lineWidth);
|
|
5315
|
-
if (!this.drawConfig.drawHandlePoints)
|
|
5962
|
+
if (!this.drawConfig.drawHandlePoints) {
|
|
5316
5963
|
d.a.attr.renderTime = d.b.attr.renderTime = d.c.attr.renderTime = renderTime;
|
|
5964
|
+
}
|
|
5317
5965
|
}
|
|
5318
5966
|
else if (d instanceof VEllipse_1.VEllipse) {
|
|
5319
5967
|
if (this.drawConfig.drawHandleLines) {
|
|
5320
5968
|
draw.setCurrentId("".concat(d.uid, "_e0"));
|
|
5321
5969
|
draw.setCurrentClassName("".concat(d.className, "-v-line"));
|
|
5322
|
-
// draw.line( d.center.clone().add(0,d.axis.y-d.center.y), d.axis, '#c8c8c8' );
|
|
5323
5970
|
draw.handleLine(d.center.clone().add(0, d.signedRadiusV()).rotate(d.rotation, d.center), d.axis); // , "#c8c8c8");
|
|
5324
5971
|
draw.setCurrentId("".concat(d.uid, "_e1"));
|
|
5325
5972
|
draw.setCurrentClassName("".concat(d.className, "-h-line"));
|
|
5326
|
-
// draw.line( d.center.clone().add(d.axis.x-d.center.x,0), d.axis, '#c8c8c8' );
|
|
5327
5973
|
draw.handleLine(d.center.clone().add(d.signedRadiusH(), 0).rotate(d.rotation, d.center), d.axis); // , "#c8c8c8");
|
|
5328
5974
|
}
|
|
5329
5975
|
draw.setCurrentId(d.uid);
|
|
@@ -5339,12 +5985,6 @@ var PlotBoilerplate = /** @class */ (function () {
|
|
|
5339
5985
|
else if (d instanceof VEllipseSector_1.VEllipseSector) {
|
|
5340
5986
|
draw.setCurrentId(d.uid);
|
|
5341
5987
|
draw.setCurrentClassName("".concat(d.className));
|
|
5342
|
-
/* draw.ellipse( d.center,
|
|
5343
|
-
// Math.abs(d.axis.x-d.center.x), Math.abs(d.axis.y-d.center.y),
|
|
5344
|
-
d.radiusH(), d.radiusV(),
|
|
5345
|
-
this.drawConfig.ellipse.color,
|
|
5346
|
-
this.drawConfig.ellipse.lineWidth,
|
|
5347
|
-
d.rotation ); */
|
|
5348
5988
|
var data = VEllipseSector_1.VEllipseSector.ellipseSectorUtils.describeSVGArc(d.ellipse.center.x, d.ellipse.center.y, d.ellipse.radiusH(), d.ellipse.radiusV(), d.startAngle, d.endAngle, d.ellipse.rotation, { moveToStart: true });
|
|
5349
5989
|
draw.path(data, this.drawConfig.ellipseSector.color, this.drawConfig.ellipseSector.lineWidth);
|
|
5350
5990
|
}
|
|
@@ -6534,7 +7174,11 @@ exports["default"] = PlotBoilerplate;
|
|
|
6534
7174
|
* @modified 2024-10-30 Added the `getEdges` method.
|
|
6535
7175
|
* @modified 2024-12-02 Added the `elimitateColinearEdges` method.
|
|
6536
7176
|
* @modified 2025-02-12 Added the `containsVerts` method to test multiple vertices for containment.
|
|
6537
|
-
* @
|
|
7177
|
+
* @modified 2025-03-28 Added the `Polygon.utils.locateLineIntersecion` static helper method.
|
|
7178
|
+
* @modified 2025-03-28 Added the `Polygon.lineIntersectionTangents` method.
|
|
7179
|
+
* @modified 2025-04-09 Added the `Polygon.getCentroid` method.
|
|
7180
|
+
* @modified 2025-05-16 Class `Polygon` now implements `IBounded`.
|
|
7181
|
+
* @version 1.15.0
|
|
6538
7182
|
*
|
|
6539
7183
|
* @file Polygon
|
|
6540
7184
|
* @public
|
|
@@ -6546,6 +7190,7 @@ var Bounds_1 = __webpack_require__(76);
|
|
|
6546
7190
|
var Line_1 = __webpack_require__(939);
|
|
6547
7191
|
var Triangle_1 = __webpack_require__(737);
|
|
6548
7192
|
var UIDGenerator_1 = __webpack_require__(938);
|
|
7193
|
+
var Vector_1 = __webpack_require__(30);
|
|
6549
7194
|
var Vertex_1 = __webpack_require__(787);
|
|
6550
7195
|
var geomutils_1 = __webpack_require__(328);
|
|
6551
7196
|
/**
|
|
@@ -6916,9 +7561,44 @@ var Polygon = /** @class */ (function () {
|
|
|
6916
7561
|
center.y /= this.vertices.length;
|
|
6917
7562
|
return center;
|
|
6918
7563
|
};
|
|
7564
|
+
/**
|
|
7565
|
+
* Get centroid.
|
|
7566
|
+
* Centroids define the barycenter of any non self-intersecting convex polygon.
|
|
7567
|
+
*
|
|
7568
|
+
* If the polygon is self intersecting or non konvex then the barycenter is not well defined.
|
|
7569
|
+
*
|
|
7570
|
+
* https://mathworld.wolfram.com/PolygonCentroid.html
|
|
7571
|
+
*
|
|
7572
|
+
* @method getCentroid
|
|
7573
|
+
* @instance
|
|
7574
|
+
* @memberof Polygon
|
|
7575
|
+
* @returns {Vertex|null}
|
|
7576
|
+
*/
|
|
7577
|
+
Polygon.prototype.getCentroid = function () {
|
|
7578
|
+
if (this.vertices.length === 0) {
|
|
7579
|
+
return null;
|
|
7580
|
+
}
|
|
7581
|
+
var center = new Vertex_1.Vertex(0.0, 0.0);
|
|
7582
|
+
var n = this.vertices.length;
|
|
7583
|
+
for (var i = 0; i < n; i++) {
|
|
7584
|
+
// center.add(this.vertices[i]);
|
|
7585
|
+
var cur = this.vertices[i];
|
|
7586
|
+
var next = this.vertices[(i + 1) % n];
|
|
7587
|
+
var factor = cur.x * next.y - next.x * cur.y;
|
|
7588
|
+
center.x += (cur.x + next.x) * factor;
|
|
7589
|
+
center.y += (cur.y + next.y) * factor;
|
|
7590
|
+
}
|
|
7591
|
+
var area = this.area();
|
|
7592
|
+
center.x *= 1 / (6 * area);
|
|
7593
|
+
center.y *= 1 / (6 * area);
|
|
7594
|
+
return center;
|
|
7595
|
+
};
|
|
7596
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
6919
7597
|
/**
|
|
6920
7598
|
* Get all line intersections with this polygon.
|
|
6921
7599
|
*
|
|
7600
|
+
* This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
|
|
7601
|
+
*
|
|
6922
7602
|
* See demo `47-closest-vector-projection-on-polygon` for how it works.
|
|
6923
7603
|
*
|
|
6924
7604
|
* @param {VertTuple} line - The line to find intersections with.
|
|
@@ -6928,21 +7608,29 @@ var Polygon = /** @class */ (function () {
|
|
|
6928
7608
|
Polygon.prototype.lineIntersections = function (line, inVectorBoundsOnly) {
|
|
6929
7609
|
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
6930
7610
|
// Find the intersections of all lines inside the edge bounds
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
7611
|
+
return Polygon.utils
|
|
7612
|
+
.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly)
|
|
7613
|
+
.map(function (intersectionTuple) { return intersectionTuple.intersectionPoint; });
|
|
7614
|
+
};
|
|
7615
|
+
/**
|
|
7616
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
7617
|
+
*
|
|
7618
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
7619
|
+
*
|
|
7620
|
+
* @param line
|
|
7621
|
+
* @param inVectorBoundsOnly
|
|
7622
|
+
* @returns
|
|
7623
|
+
*/
|
|
7624
|
+
Polygon.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
7625
|
+
var _this = this;
|
|
7626
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
7627
|
+
// Find the intersection tangents of all lines inside the edge bounds
|
|
7628
|
+
return Polygon.utils.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly).map(function (intersectionTuple) {
|
|
7629
|
+
var polyLine = _this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
7630
|
+
return new Vector_1.Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersectionPoint);
|
|
7631
|
+
});
|
|
6945
7632
|
};
|
|
7633
|
+
//--- END --- Implement interface `Intersectable`
|
|
6946
7634
|
/**
|
|
6947
7635
|
* Get the closest line-polygon-intersection point (closest the line point A).
|
|
6948
7636
|
*
|
|
@@ -7044,6 +7732,7 @@ var Polygon = /** @class */ (function () {
|
|
|
7044
7732
|
}
|
|
7045
7733
|
return result;
|
|
7046
7734
|
};
|
|
7735
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
7047
7736
|
/**
|
|
7048
7737
|
* Get the bounding box (bounds) of this polygon.
|
|
7049
7738
|
*
|
|
@@ -7055,6 +7744,7 @@ var Polygon = /** @class */ (function () {
|
|
|
7055
7744
|
Polygon.prototype.getBounds = function () {
|
|
7056
7745
|
return Bounds_1.Bounds.computeFromVertices(this.vertices);
|
|
7057
7746
|
};
|
|
7747
|
+
//--- END --- Implement interface `IBounded`
|
|
7058
7748
|
/**
|
|
7059
7749
|
* Create a deep copy of this polygon.
|
|
7060
7750
|
*
|
|
@@ -7109,7 +7799,6 @@ var Polygon = /** @class */ (function () {
|
|
|
7109
7799
|
// -> delete all vertices in between
|
|
7110
7800
|
if (j - i > 2) {
|
|
7111
7801
|
// Means: there have been 'colinear vertices' in between
|
|
7112
|
-
// console.log("Splice", "i", i, "j", j, i + 1, j - i - 1);
|
|
7113
7802
|
verts.splice(i + 1, j - i - 2);
|
|
7114
7803
|
}
|
|
7115
7804
|
i++;
|
|
@@ -7305,6 +7994,32 @@ var Polygon = /** @class */ (function () {
|
|
|
7305
7994
|
sum += (vertices[j].x - vertices[i].x) * (vertices[i].y + vertices[j].y);
|
|
7306
7995
|
}
|
|
7307
7996
|
return sum;
|
|
7997
|
+
},
|
|
7998
|
+
/**
|
|
7999
|
+
* Find intersections of a line with a polygon (vertices).
|
|
8000
|
+
*
|
|
8001
|
+
* @param {VertTuple<any>} line - The line to find intersections with.
|
|
8002
|
+
* @param {Array<Vertex>} vertices - The polygon's vertices.
|
|
8003
|
+
* @param {boolean} isOpen - True if the polygon is open, false otherwise.
|
|
8004
|
+
* @param {boolean} inVectorBoundsOnly - If only intersections in strict vector bounds should be returned.
|
|
8005
|
+
* @returns
|
|
8006
|
+
*/
|
|
8007
|
+
locateLineIntersecion: function (line, vertices, isOpen, inVectorBoundsOnly) {
|
|
8008
|
+
// Find the intersections of all lines inside the edge bounds
|
|
8009
|
+
var intersectionPoints = [];
|
|
8010
|
+
var n = isOpen ? vertices.length - 1 : vertices.length;
|
|
8011
|
+
for (var i = 0; i < n; i++) {
|
|
8012
|
+
var polyLine = new Line_1.Line(vertices[i % n], vertices[(i + 1) % n]);
|
|
8013
|
+
var intersection = polyLine.intersection(line);
|
|
8014
|
+
// true => only inside bounds
|
|
8015
|
+
// ignore last edge if open
|
|
8016
|
+
if (intersection !== null &&
|
|
8017
|
+
polyLine.hasPoint(intersection, true) &&
|
|
8018
|
+
(!inVectorBoundsOnly || line.hasPoint(intersection, inVectorBoundsOnly))) {
|
|
8019
|
+
intersectionPoints.push({ edgeIndex: i, intersectionPoint: intersection });
|
|
8020
|
+
}
|
|
8021
|
+
}
|
|
8022
|
+
return intersectionPoints;
|
|
7308
8023
|
}
|
|
7309
8024
|
};
|
|
7310
8025
|
return Polygon;
|
|
@@ -7343,7 +8058,11 @@ exports.Polygon = Polygon;
|
|
|
7343
8058
|
* @modified 2022-02-02 Cleared the `Triangle.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
7344
8059
|
* @modified 2024-11-22 Added static utility function Triangle.utils.determinant; adapted method `determinant`.
|
|
7345
8060
|
* @modified 2024-11-22 Changing visibility of `Triangle.utils` from `private` to `public`.
|
|
7346
|
-
* @
|
|
8061
|
+
* @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.
|
|
8062
|
+
* @modified 2025-14-16 Class `Triangle` now implements interface `IBounded`.
|
|
8063
|
+
* @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.
|
|
8064
|
+
* @modified 2025-14-16 Added method `Triangle.move`.
|
|
8065
|
+
* @version 2.10.0
|
|
7347
8066
|
*
|
|
7348
8067
|
* @file Triangle
|
|
7349
8068
|
* @fileoverview A simple triangle class: three vertices.
|
|
@@ -7356,6 +8075,7 @@ var Circle_1 = __webpack_require__(118);
|
|
|
7356
8075
|
var Line_1 = __webpack_require__(939);
|
|
7357
8076
|
var Polygon_1 = __webpack_require__(687);
|
|
7358
8077
|
var UIDGenerator_1 = __webpack_require__(938);
|
|
8078
|
+
var Vector_1 = __webpack_require__(30);
|
|
7359
8079
|
var Vertex_1 = __webpack_require__(787);
|
|
7360
8080
|
var geomutils_1 = __webpack_require__(328);
|
|
7361
8081
|
/**
|
|
@@ -7457,6 +8177,35 @@ var Triangle = /** @class */ (function () {
|
|
|
7457
8177
|
this.c.scale(factor, centroid);
|
|
7458
8178
|
return this;
|
|
7459
8179
|
};
|
|
8180
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
8181
|
+
/**
|
|
8182
|
+
* Get the bounding box (bounds) of this Triangle.
|
|
8183
|
+
*
|
|
8184
|
+
* @method getBounds
|
|
8185
|
+
* @instance
|
|
8186
|
+
* @memberof Triangle
|
|
8187
|
+
* @return {Bounds} The rectangular bounds of this Triangle.
|
|
8188
|
+
**/
|
|
8189
|
+
Triangle.prototype.getBounds = function () {
|
|
8190
|
+
// return Bounds.computeFromVertices([this.a, this.b, this.c]);
|
|
8191
|
+
return this.bounds();
|
|
8192
|
+
};
|
|
8193
|
+
//--- END --- Implement interface `IBounded`
|
|
8194
|
+
/**
|
|
8195
|
+
* Move the Triangle's vertices by the given amount.
|
|
8196
|
+
*
|
|
8197
|
+
* @method move
|
|
8198
|
+
* @param {XYCoords} amount - The amount to move.
|
|
8199
|
+
* @instance
|
|
8200
|
+
* @memberof Triangle
|
|
8201
|
+
* @return {Triangle} this for chaining
|
|
8202
|
+
**/
|
|
8203
|
+
Triangle.prototype.move = function (amount) {
|
|
8204
|
+
this.a.add(amount);
|
|
8205
|
+
this.b.add(amount);
|
|
8206
|
+
this.c.add(amount);
|
|
8207
|
+
return this;
|
|
8208
|
+
};
|
|
7460
8209
|
/**
|
|
7461
8210
|
* Get the circumcircle of this triangle.
|
|
7462
8211
|
*
|
|
@@ -7582,6 +8331,51 @@ var Triangle = /** @class */ (function () {
|
|
|
7582
8331
|
Triangle.prototype.bounds = function () {
|
|
7583
8332
|
return new Bounds_1.Bounds(new Vertex_1.Vertex(Triangle.utils.min3(this.a.x, this.b.x, this.c.x), Triangle.utils.min3(this.a.y, this.b.y, this.c.y)), new Vertex_1.Vertex(Triangle.utils.max3(this.a.x, this.b.x, this.c.x), Triangle.utils.max3(this.a.y, this.b.y, this.c.y)));
|
|
7584
8333
|
};
|
|
8334
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
8335
|
+
/**
|
|
8336
|
+
* Get all line intersections with this polygon.
|
|
8337
|
+
*
|
|
8338
|
+
* This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.
|
|
8339
|
+
*
|
|
8340
|
+
* See demo `47-closest-vector-projection-on-polygon` for how it works.
|
|
8341
|
+
*
|
|
8342
|
+
* @param {VertTuple} line - The line to find intersections with.
|
|
8343
|
+
* @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).
|
|
8344
|
+
* @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.
|
|
8345
|
+
*/
|
|
8346
|
+
Triangle.prototype.lineIntersections = function (line, inVectorBoundsOnly) {
|
|
8347
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
8348
|
+
// Find the intersections of all lines inside the edge bounds
|
|
8349
|
+
return Polygon_1.Polygon.utils
|
|
8350
|
+
.locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)
|
|
8351
|
+
.map(function (intersectionTuple) { return intersectionTuple.intersectionPoint; });
|
|
8352
|
+
};
|
|
8353
|
+
/**
|
|
8354
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
8355
|
+
*
|
|
8356
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
8357
|
+
*
|
|
8358
|
+
* @param line
|
|
8359
|
+
* @param inVectorBoundsOnly
|
|
8360
|
+
* @returns
|
|
8361
|
+
*/
|
|
8362
|
+
Triangle.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
8363
|
+
var _this = this;
|
|
8364
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
8365
|
+
// Find the intersection tangents of all lines inside the edge bounds
|
|
8366
|
+
return Polygon_1.Polygon.utils
|
|
8367
|
+
.locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)
|
|
8368
|
+
.map(function (intersectionTuple) {
|
|
8369
|
+
// const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
8370
|
+
var polyLine = _this.getEdgeAt(intersectionTuple.edgeIndex);
|
|
8371
|
+
return new Vector_1.Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersectionPoint);
|
|
8372
|
+
});
|
|
8373
|
+
};
|
|
8374
|
+
//--- END --- Implement interface `Intersectable`
|
|
8375
|
+
Triangle.prototype.getEdgeAt = function (edgeIndex) {
|
|
8376
|
+
var modIndex = edgeIndex % 3;
|
|
8377
|
+
return modIndex === 0 ? new Line_1.Line(this.a, this.b) : modIndex === 1 ? new Line_1.Line(this.b, this.c) : new Line_1.Line(this.c, this.a);
|
|
8378
|
+
};
|
|
7585
8379
|
/**
|
|
7586
8380
|
* Convert this triangle to a polygon instance.
|
|
7587
8381
|
*
|
|
@@ -7786,7 +8580,11 @@ exports.UIDGenerator = UIDGenerator;
|
|
|
7786
8580
|
* @modified 2021-03-19 Added the `VEllipse.rotate` function.
|
|
7787
8581
|
* @modified 2022-02-02 Added the `destroy` method.
|
|
7788
8582
|
* @modified 2022-02-02 Cleared the `VEllipse.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
7789
|
-
* @
|
|
8583
|
+
* @modified 2025-03-31 ATTENTION: modified the winding direction of the `tangentAt` method to match with the Circle method. This is a breaking change!
|
|
8584
|
+
* @modified 2025-03-31 Adding the `VEllipse.move(amount: XYCoords)` method.
|
|
8585
|
+
* @modified 2025-04-19 Adding the `VEllipse.getBounds()` method.
|
|
8586
|
+
* @modified 2025-04-24 Adding the `VEllipse.getExtremePoints()` method for calculating minima and maxima.
|
|
8587
|
+
* @version 1.4.0
|
|
7790
8588
|
*
|
|
7791
8589
|
* @file VEllipse
|
|
7792
8590
|
* @fileoverview Ellipses with a center and an x- and a y-axis (stored as a vertex).
|
|
@@ -7798,6 +8596,8 @@ var Vector_1 = __webpack_require__(30);
|
|
|
7798
8596
|
var Vertex_1 = __webpack_require__(787);
|
|
7799
8597
|
var UIDGenerator_1 = __webpack_require__(938);
|
|
7800
8598
|
var CubicBezierCurve_1 = __webpack_require__(973);
|
|
8599
|
+
var Circle_1 = __webpack_require__(118);
|
|
8600
|
+
var Bounds_1 = __webpack_require__(76);
|
|
7801
8601
|
/**
|
|
7802
8602
|
* @classdesc An ellipse class based on two vertices [centerX,centerY] and [radiusX,radiusY].
|
|
7803
8603
|
*
|
|
@@ -7879,11 +8679,96 @@ var VEllipse = /** @class */ (function () {
|
|
|
7879
8679
|
* @return {number} The signed vertical radius of this ellipse.
|
|
7880
8680
|
*/
|
|
7881
8681
|
VEllipse.prototype.signedRadiusV = function () {
|
|
7882
|
-
// return Math.abs(this.axis.y - this.center.y);
|
|
7883
8682
|
// Rotate axis back to origin before calculating radius
|
|
7884
|
-
// return Math.abs(new Vertex(this.axis).rotate(-this.rotation,this.center).y - this.center.y);
|
|
7885
8683
|
return new Vertex_1.Vertex(this.axis).rotate(-this.rotation, this.center).y - this.center.y;
|
|
7886
8684
|
};
|
|
8685
|
+
/**
|
|
8686
|
+
* Get the the minima and maxima (points) of this (rotated) ellipse.
|
|
8687
|
+
*
|
|
8688
|
+
* @method getExtremePoints
|
|
8689
|
+
* @instance
|
|
8690
|
+
* @memberof VEllipse
|
|
8691
|
+
* @return {[Vertex, Vertex, Vertex, Vertex]} Get the the minima and maxima (points) of this (rotated) ellipse.
|
|
8692
|
+
*/
|
|
8693
|
+
VEllipse.prototype.getExtremePoints = function () {
|
|
8694
|
+
var a = this.radiusH();
|
|
8695
|
+
var b = this.radiusV();
|
|
8696
|
+
// Calculate t_x values
|
|
8697
|
+
var t_x1 = Math.atan2(-b * Math.sin(this.rotation), a * Math.cos(this.rotation));
|
|
8698
|
+
var t_x2 = t_x1 + Math.PI;
|
|
8699
|
+
// Calculate x values at t_x
|
|
8700
|
+
var x_x1 = this.center.x + a * Math.cos(t_x1) * Math.cos(this.rotation) - b * Math.sin(t_x1) * Math.sin(this.rotation);
|
|
8701
|
+
var y_x1 = this.center.y + a * Math.cos(t_x1) * Math.sin(this.rotation) + b * Math.sin(t_x1) * Math.cos(this.rotation);
|
|
8702
|
+
var x_x2 = this.center.x + a * Math.cos(t_x2) * Math.cos(this.rotation) - b * Math.sin(t_x2) * Math.sin(this.rotation);
|
|
8703
|
+
var y_x2 = this.center.y + a * Math.cos(t_x2) * Math.sin(this.rotation) + b * Math.sin(t_x2) * Math.cos(this.rotation);
|
|
8704
|
+
var x_max, x_min;
|
|
8705
|
+
if (x_x1 > x_x2) {
|
|
8706
|
+
x_max = new Vertex_1.Vertex(x_x1, y_x1);
|
|
8707
|
+
x_min = new Vertex_1.Vertex(x_x2, y_x2);
|
|
8708
|
+
}
|
|
8709
|
+
else {
|
|
8710
|
+
x_max = new Vertex_1.Vertex(x_x2, y_x2);
|
|
8711
|
+
x_min = new Vertex_1.Vertex(x_x1, y_x1);
|
|
8712
|
+
}
|
|
8713
|
+
// Calculate t_y values
|
|
8714
|
+
var t_y1 = Math.atan2(b * Math.cos(this.rotation), a * Math.sin(this.rotation));
|
|
8715
|
+
var t_y2 = t_y1 + Math.PI;
|
|
8716
|
+
// Calculate y values at t_y
|
|
8717
|
+
var x_y1 = this.center.x + a * Math.cos(t_y1) * Math.cos(this.rotation) - b * Math.sin(t_y1) * Math.sin(this.rotation);
|
|
8718
|
+
var y_y1 = this.center.y + a * Math.cos(t_y1) * Math.sin(this.rotation) + b * Math.sin(t_y1) * Math.cos(this.rotation);
|
|
8719
|
+
var x_y2 = this.center.x + a * Math.cos(t_y2) * Math.cos(this.rotation) - b * Math.sin(t_y2) * Math.sin(this.rotation);
|
|
8720
|
+
var y_y2 = this.center.y + a * Math.cos(t_y2) * Math.sin(this.rotation) + b * Math.sin(t_y2) * Math.cos(this.rotation);
|
|
8721
|
+
var y_max, y_min;
|
|
8722
|
+
if (y_y1 > y_y2) {
|
|
8723
|
+
y_max = new Vertex_1.Vertex(x_y1, y_y1);
|
|
8724
|
+
y_min = new Vertex_1.Vertex(x_y2, y_y2);
|
|
8725
|
+
}
|
|
8726
|
+
else {
|
|
8727
|
+
y_max = new Vertex_1.Vertex(x_y2, y_y2);
|
|
8728
|
+
y_min = new Vertex_1.Vertex(x_y1, y_y1);
|
|
8729
|
+
}
|
|
8730
|
+
return [x_max, x_min, y_max, y_min];
|
|
8731
|
+
};
|
|
8732
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
8733
|
+
/**
|
|
8734
|
+
* Get the bounds of this ellipse.
|
|
8735
|
+
*
|
|
8736
|
+
* The bounds are approximated by the underlying segment buffer; the more segment there are,
|
|
8737
|
+
* the more accurate will be the returned bounds.
|
|
8738
|
+
*
|
|
8739
|
+
* @method getBounds
|
|
8740
|
+
* @instance
|
|
8741
|
+
* @memberof VEllipse
|
|
8742
|
+
* @return {Bounds} The bounds of this ellipse.
|
|
8743
|
+
**/
|
|
8744
|
+
VEllipse.prototype.getBounds = function () {
|
|
8745
|
+
// Thanks to Cuixiping
|
|
8746
|
+
// https://stackoverflow.com/questions/87734/how-do-you-calculate-the-axis-aligned-bounding-box-of-an-ellipse
|
|
8747
|
+
var r1 = this.radiusH();
|
|
8748
|
+
var r2 = this.radiusV();
|
|
8749
|
+
var ux = r1 * Math.cos(this.rotation);
|
|
8750
|
+
var uy = r1 * Math.sin(this.rotation);
|
|
8751
|
+
var vx = r2 * Math.cos(this.rotation + Math.PI / 2);
|
|
8752
|
+
var vy = r2 * Math.sin(this.rotation + Math.PI / 2);
|
|
8753
|
+
var bbox_halfwidth = Math.sqrt(ux * ux + vx * vx);
|
|
8754
|
+
var bbox_halfheight = Math.sqrt(uy * uy + vy * vy);
|
|
8755
|
+
return new Bounds_1.Bounds({ x: this.center.x - bbox_halfwidth, y: this.center.y - bbox_halfheight }, { x: this.center.x + bbox_halfwidth, y: this.center.y + bbox_halfheight });
|
|
8756
|
+
};
|
|
8757
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
8758
|
+
/**
|
|
8759
|
+
* Move the ellipse by the given amount. This is equivalent by moving the `center` and `axis` points.
|
|
8760
|
+
*
|
|
8761
|
+
* @method move
|
|
8762
|
+
* @param {XYCoords} amount - The amount to move.
|
|
8763
|
+
* @instance
|
|
8764
|
+
* @memberof VEllipse
|
|
8765
|
+
* @return {VEllipse} this for chaining
|
|
8766
|
+
**/
|
|
8767
|
+
VEllipse.prototype.move = function (amount) {
|
|
8768
|
+
this.center.add(amount);
|
|
8769
|
+
this.axis.add(amount);
|
|
8770
|
+
return this;
|
|
8771
|
+
};
|
|
7887
8772
|
/**
|
|
7888
8773
|
* Scale this ellipse by the given factor from the center point. The factor will be applied to both radii.
|
|
7889
8774
|
*
|
|
@@ -7941,7 +8826,7 @@ var VEllipse = /** @class */ (function () {
|
|
|
7941
8826
|
* @param {number=1.0} length - [optional, default=1] The length of the returned vector.
|
|
7942
8827
|
*/
|
|
7943
8828
|
VEllipse.prototype.normalAt = function (angle, length) {
|
|
7944
|
-
var point = this.vertAt(angle);
|
|
8829
|
+
var point = this.vertAt(angle - this.rotation); // HERE IS THE CORRECT BEHAVIOR!
|
|
7945
8830
|
var foci = this.getFoci();
|
|
7946
8831
|
// Calculate the angle between [point,focusA] and [point,focusB]
|
|
7947
8832
|
var angleA = new Line_1.Line(point, foci[0]).angle();
|
|
@@ -7953,12 +8838,13 @@ var VEllipse = /** @class */ (function () {
|
|
|
7953
8838
|
.addX(50)
|
|
7954
8839
|
.clone()
|
|
7955
8840
|
.rotate(Math.PI + centerAngle, point);
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
8841
|
+
var resultVector = this.center.distance(endPointA) < this.center.distance(endPointB)
|
|
8842
|
+
? new Vector_1.Vector(point, endPointB)
|
|
8843
|
+
: new Vector_1.Vector(point, endPointA);
|
|
8844
|
+
if (typeof length === "number") {
|
|
8845
|
+
resultVector.setLength(length);
|
|
7961
8846
|
}
|
|
8847
|
+
return resultVector;
|
|
7962
8848
|
};
|
|
7963
8849
|
/**
|
|
7964
8850
|
* Get the tangent vector at the given angle.
|
|
@@ -7977,9 +8863,7 @@ var VEllipse = /** @class */ (function () {
|
|
|
7977
8863
|
*/
|
|
7978
8864
|
VEllipse.prototype.tangentAt = function (angle, length) {
|
|
7979
8865
|
var normal = this.normalAt(angle, length);
|
|
7980
|
-
|
|
7981
|
-
normal.b.rotate(Math.PI / 2, normal.a);
|
|
7982
|
-
return normal;
|
|
8866
|
+
return normal.inv().perp();
|
|
7983
8867
|
};
|
|
7984
8868
|
/**
|
|
7985
8869
|
* Get the perimeter of this ellipse.
|
|
@@ -8030,6 +8914,8 @@ var VEllipse = /** @class */ (function () {
|
|
|
8030
8914
|
/**
|
|
8031
8915
|
* Get equally distributed points on the outline of this ellipse.
|
|
8032
8916
|
*
|
|
8917
|
+
* @method getEquidistantVertices
|
|
8918
|
+
* @instance
|
|
8033
8919
|
* @param {number} pointCount - The number of points.
|
|
8034
8920
|
* @returns {Array<Vertex>}
|
|
8035
8921
|
*/
|
|
@@ -8041,6 +8927,78 @@ var VEllipse = /** @class */ (function () {
|
|
|
8041
8927
|
}
|
|
8042
8928
|
return result;
|
|
8043
8929
|
};
|
|
8930
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
8931
|
+
/**
|
|
8932
|
+
* Get the line intersections as vectors with this ellipse.
|
|
8933
|
+
*
|
|
8934
|
+
* @method lineIntersections
|
|
8935
|
+
* @instance
|
|
8936
|
+
* @param {VertTuple<Vector> ray - The line/ray to intersect this ellipse with.
|
|
8937
|
+
* @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.
|
|
8938
|
+
* @returns
|
|
8939
|
+
*/
|
|
8940
|
+
VEllipse.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {
|
|
8941
|
+
// Question: what happens to extreme versions when ellipse is a line (width or height is zero)?
|
|
8942
|
+
// This would result in a Division_by_Zero exception!
|
|
8943
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
8944
|
+
// Step A: create clones for operations (keep originals unchanged)
|
|
8945
|
+
var ellipseCopy = this.clone(); // VEllipse
|
|
8946
|
+
var rayCopy = ray.clone(); // Vector
|
|
8947
|
+
// Step B: move both so ellipse's center is located at (0,0)
|
|
8948
|
+
var moveAmount = ellipseCopy.center.clone().inv();
|
|
8949
|
+
ellipseCopy.move(moveAmount);
|
|
8950
|
+
rayCopy.add(moveAmount);
|
|
8951
|
+
// Step C: rotate eclipse backwards it's rotation, so that rotation is zero (0.0).
|
|
8952
|
+
// Rotate together with ray!
|
|
8953
|
+
var rotationAmount = -ellipseCopy.rotation;
|
|
8954
|
+
ellipseCopy.rotate(rotationAmount); // Rotation around (0,0) = center of translated ellipse
|
|
8955
|
+
rayCopy.a.rotate(rotationAmount, ellipseCopy.center);
|
|
8956
|
+
rayCopy.b.rotate(rotationAmount, ellipseCopy.center);
|
|
8957
|
+
// Step D: find x/y factors to use for scaling to transform the ellipse to a circle.
|
|
8958
|
+
// Scale together with vector ray.
|
|
8959
|
+
var radiusH = ellipseCopy.radiusH();
|
|
8960
|
+
var radiusV = ellipseCopy.radiusV();
|
|
8961
|
+
var scalingFactors = radiusH > radiusV ? { x: radiusV / radiusH, y: 1.0 } : { x: 1.0, y: radiusH / radiusV };
|
|
8962
|
+
// Step E: scale ellipse AND ray by calculated factors.
|
|
8963
|
+
ellipseCopy.axis.scaleXY(scalingFactors);
|
|
8964
|
+
rayCopy.a.scaleXY(scalingFactors);
|
|
8965
|
+
rayCopy.b.scaleXY(scalingFactors);
|
|
8966
|
+
// Intermediate result: now the ellipse is transformed to a circle and we can calculate intersections :)
|
|
8967
|
+
// Step F: calculate circle+line intersecions
|
|
8968
|
+
var tmpCircle = new Circle_1.Circle(new Vertex_1.Vertex(), ellipseCopy.radiusH()); // radiusH() === radiusV()
|
|
8969
|
+
var intersections = tmpCircle.lineIntersections(rayCopy, inVectorBoundsOnly);
|
|
8970
|
+
// Step G: transform intersecions back to original configuration
|
|
8971
|
+
intersections.forEach(function (intersectionPoint) {
|
|
8972
|
+
// Reverse transformation from above.
|
|
8973
|
+
intersectionPoint.scaleXY({ x: 1 / scalingFactors.x, y: 1 / scalingFactors.y }, ellipseCopy.center);
|
|
8974
|
+
intersectionPoint.rotate(-rotationAmount, ellipseCopy.center);
|
|
8975
|
+
intersectionPoint.sub(moveAmount);
|
|
8976
|
+
});
|
|
8977
|
+
return intersections;
|
|
8978
|
+
};
|
|
8979
|
+
/**
|
|
8980
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
8981
|
+
*
|
|
8982
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
8983
|
+
*
|
|
8984
|
+
* @param line
|
|
8985
|
+
* @param lineIntersectionTangents
|
|
8986
|
+
* @returns
|
|
8987
|
+
*/
|
|
8988
|
+
VEllipse.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
8989
|
+
var _this = this;
|
|
8990
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
8991
|
+
// Find the intersections of all lines plus their tangents inside the circle bounds
|
|
8992
|
+
var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);
|
|
8993
|
+
return interSectionPoints.map(function (vert) {
|
|
8994
|
+
// Calculate angle
|
|
8995
|
+
var lineFromCenter = new Line_1.Line(_this.center, vert);
|
|
8996
|
+
var angle = lineFromCenter.angle();
|
|
8997
|
+
// Calculate tangent at angle
|
|
8998
|
+
return _this.tangentAt(angle);
|
|
8999
|
+
});
|
|
9000
|
+
};
|
|
9001
|
+
//--- END --- Implement interface `Intersectable`
|
|
8044
9002
|
/**
|
|
8045
9003
|
* Convert this ellipse into cubic Bézier curves.
|
|
8046
9004
|
*
|
|
@@ -8053,7 +9011,7 @@ var VEllipse = /** @class */ (function () {
|
|
|
8053
9011
|
// Math by Luc Maisonobe
|
|
8054
9012
|
// http://www.spaceroots.org/documents/ellipse/node22.html
|
|
8055
9013
|
// Note that ellipses with radiusH=0 or radiusV=0 cannot be represented as Bézier curves.
|
|
8056
|
-
// Return a single line here (as a Bézier curve)
|
|
9014
|
+
// Return a single line here (as a Bézier curve)?
|
|
8057
9015
|
// if (Math.abs(this.radiusV()) < 0.00001) {
|
|
8058
9016
|
// const radiusH = this.radiusH();
|
|
8059
9017
|
// return [
|
|
@@ -8083,10 +9041,10 @@ var VEllipse = /** @class */ (function () {
|
|
|
8083
9041
|
var radiusV = this.radiusV();
|
|
8084
9042
|
var curves = [];
|
|
8085
9043
|
var angles = VEllipse.utils.equidistantVertAngles(radiusH, radiusV, segmentCount);
|
|
8086
|
-
var curAngle = angles[0];
|
|
9044
|
+
var curAngle = angles[0] + this.rotation;
|
|
8087
9045
|
var startPoint = this.vertAt(curAngle);
|
|
8088
9046
|
for (var i = 0; i < angles.length; i++) {
|
|
8089
|
-
var nextAngle = angles[(i + 1) % angles.length];
|
|
9047
|
+
var nextAngle = angles[(i + 1) % angles.length] + this.rotation;
|
|
8090
9048
|
var endPoint = this.vertAt(nextAngle);
|
|
8091
9049
|
if (Math.abs(radiusV) < 0.0001 || Math.abs(radiusH) < 0.0001) {
|
|
8092
9050
|
// Distorted ellipses can only be approximated by linear Bézier segments
|
|
@@ -8095,8 +9053,8 @@ var VEllipse = /** @class */ (function () {
|
|
|
8095
9053
|
curves.push(curve);
|
|
8096
9054
|
}
|
|
8097
9055
|
else {
|
|
8098
|
-
var startTangent = this.tangentAt(curAngle);
|
|
8099
|
-
var endTangent = this.tangentAt(nextAngle);
|
|
9056
|
+
var startTangent = this.tangentAt(curAngle + this.rotation);
|
|
9057
|
+
var endTangent = this.tangentAt(nextAngle + this.rotation);
|
|
8100
9058
|
// Find intersection (ignore that the result might be null in some extreme cases)
|
|
8101
9059
|
var intersection = startTangent.intersection(endTangent);
|
|
8102
9060
|
// What if intersection is undefined?
|
|
@@ -8197,10 +9155,18 @@ exports.VEllipse = VEllipse;
|
|
|
8197
9155
|
* @date 2021-02-26
|
|
8198
9156
|
* @modified 2022-02-02 Added the `destroy` method.
|
|
8199
9157
|
* @modified 2022-11-01 Tweaked the `endpointToCenterParameters` function to handle negative values, too, without errors.
|
|
8200
|
-
* @
|
|
9158
|
+
* @modified 2025-04-01 Adapting a the `toCubicBezier` calculation to match an underlying change in the vertAt and tangentAt calculation of ellipses (was required to hamonize both methods with circles).
|
|
9159
|
+
* @modified 2025-04-02 Adding `VEllipseSector.containsAngle` method.
|
|
9160
|
+
* @modified 2025-04-02 Adding `VEllipseSector.lineIntersections` and `VEllipseSector.lineIntersectionTangents` and implementing `Intersectable`.
|
|
9161
|
+
* @modified 2025-04-07 Adding value wrapping (0 to TWO_PI) to the `VEllipseSector.containsAngle` method.
|
|
9162
|
+
* @modified 2025-04-09 Adding the `VEllipseSector.move` method.
|
|
9163
|
+
* @modified 2025-04-19 Added the `VEllipseSector.getStartPoint` and `getEndPoint` methods.
|
|
9164
|
+
* @modified 2025-04-23 Added the `VEllipseSector.getBounds` method.
|
|
9165
|
+
* @version 1.2.0
|
|
8201
9166
|
*/
|
|
8202
9167
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
8203
9168
|
exports.VEllipseSector = void 0;
|
|
9169
|
+
var Bounds_1 = __webpack_require__(76);
|
|
8204
9170
|
var CubicBezierCurve_1 = __webpack_require__(973);
|
|
8205
9171
|
var geomutils_1 = __webpack_require__(328);
|
|
8206
9172
|
var Line_1 = __webpack_require__(939);
|
|
@@ -8241,6 +9207,142 @@ var VEllipseSector = /** @class */ (function () {
|
|
|
8241
9207
|
this.startAngle = geomutils_1.geomutils.wrapMinMax(startAngle, 0, Math.PI * 2);
|
|
8242
9208
|
this.endAngle = geomutils_1.geomutils.wrapMinMax(endAngle, 0, Math.PI * 2);
|
|
8243
9209
|
}
|
|
9210
|
+
/**
|
|
9211
|
+
* Move the ellipse sector by the given amount.
|
|
9212
|
+
*
|
|
9213
|
+
* @method move
|
|
9214
|
+
* @param {XYCoords} amount - The amount to move.
|
|
9215
|
+
* @instance
|
|
9216
|
+
* @memberof VEllipseSector
|
|
9217
|
+
* @return {VEllipseSector} this for chaining
|
|
9218
|
+
**/
|
|
9219
|
+
VEllipseSector.prototype.move = function (amount) {
|
|
9220
|
+
this.ellipse.move(amount);
|
|
9221
|
+
return this;
|
|
9222
|
+
};
|
|
9223
|
+
/**
|
|
9224
|
+
* Checks wether the given angle (must be inside 0 and PI*2) is contained inside this sector.
|
|
9225
|
+
*
|
|
9226
|
+
* @param {number} angle - The numeric angle to check.
|
|
9227
|
+
* @method containsAngle
|
|
9228
|
+
* @instance
|
|
9229
|
+
* @memberof VEllipseSectpr
|
|
9230
|
+
* @return {boolean} True if (and only if) this sector contains the given angle.
|
|
9231
|
+
*/
|
|
9232
|
+
VEllipseSector.prototype.containsAngle = function (angle) {
|
|
9233
|
+
angle = geomutils_1.geomutils.mapAngleTo2PI(angle); // wrapMinMax(angle, 0, Math.PI * 2);
|
|
9234
|
+
var sAngle = geomutils_1.geomutils.mapAngleTo2PI(this.startAngle);
|
|
9235
|
+
var eAngle = geomutils_1.geomutils.mapAngleTo2PI(this.endAngle);
|
|
9236
|
+
// TODO: cleanup
|
|
9237
|
+
// if (this.startAngle <= this.endAngle) {
|
|
9238
|
+
// return angle >= this.startAngle && angle < this.endAngle;
|
|
9239
|
+
// } else {
|
|
9240
|
+
// // startAngle > endAngle
|
|
9241
|
+
// return angle >= this.startAngle || angle < this.endAngle;
|
|
9242
|
+
// }
|
|
9243
|
+
if (sAngle <= eAngle) {
|
|
9244
|
+
return angle >= sAngle && angle < eAngle;
|
|
9245
|
+
}
|
|
9246
|
+
else {
|
|
9247
|
+
// startAngle > endAngle
|
|
9248
|
+
return angle >= sAngle || angle < eAngle;
|
|
9249
|
+
}
|
|
9250
|
+
};
|
|
9251
|
+
/**
|
|
9252
|
+
* Get the sectors starting point (on the underlying ellipse, located at the start angle).
|
|
9253
|
+
*
|
|
9254
|
+
* @method getStartPoint
|
|
9255
|
+
* @instance
|
|
9256
|
+
* @memberof VEllipseSector
|
|
9257
|
+
* @return {Vertex} The sector's stating point.
|
|
9258
|
+
*/
|
|
9259
|
+
VEllipseSector.prototype.getStartPoint = function () {
|
|
9260
|
+
return this.ellipse.vertAt(this.startAngle);
|
|
9261
|
+
};
|
|
9262
|
+
/**
|
|
9263
|
+
* Get the sectors ending point (on the underlying ellipse, located at the end angle).
|
|
9264
|
+
*
|
|
9265
|
+
* @method getEndPoint
|
|
9266
|
+
* @instance
|
|
9267
|
+
* @memberof VEllipseSector
|
|
9268
|
+
* @return {Vertex} The sector's ending point.
|
|
9269
|
+
*/
|
|
9270
|
+
VEllipseSector.prototype.getEndPoint = function () {
|
|
9271
|
+
return this.ellipse.vertAt(this.endAngle);
|
|
9272
|
+
};
|
|
9273
|
+
//--- BEGIN --- Implement interface `IBounded`
|
|
9274
|
+
/**
|
|
9275
|
+
* Get the bounds of this elliptic sector.
|
|
9276
|
+
*
|
|
9277
|
+
* The bounds are approximated by the underlying segment buffer; the more segment there are,
|
|
9278
|
+
* the more accurate will be the returned bounds.
|
|
9279
|
+
*
|
|
9280
|
+
* @method getBounds
|
|
9281
|
+
* @instance
|
|
9282
|
+
* @memberof VEllipse
|
|
9283
|
+
* @return {Bounds} The bounds of this elliptic sector.
|
|
9284
|
+
**/
|
|
9285
|
+
VEllipseSector.prototype.getBounds = function () {
|
|
9286
|
+
var _this = this;
|
|
9287
|
+
// Calculage angles from east, west, north and south box points and check if they are inside
|
|
9288
|
+
var extremes = this.ellipse.getExtremePoints();
|
|
9289
|
+
var candidates = extremes.filter(function (point) {
|
|
9290
|
+
var angle = new Line_1.Line(_this.ellipse.center, point).angle() - _this.ellipse.rotation;
|
|
9291
|
+
return _this.containsAngle(angle);
|
|
9292
|
+
});
|
|
9293
|
+
return Bounds_1.Bounds.computeFromVertices([this.getStartPoint(), this.getEndPoint()].concat(candidates));
|
|
9294
|
+
};
|
|
9295
|
+
//--- BEGIN --- Implement interface `Intersectable`
|
|
9296
|
+
/**
|
|
9297
|
+
* Get the line intersections as vectors with this ellipse.
|
|
9298
|
+
*
|
|
9299
|
+
* @method lineIntersections
|
|
9300
|
+
* @instance
|
|
9301
|
+
* @memberof VEllipseSectpr
|
|
9302
|
+
* @param {VertTuple<Vector>} ray - The line/ray to intersect this ellipse with.
|
|
9303
|
+
* @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.
|
|
9304
|
+
* @returns
|
|
9305
|
+
*/
|
|
9306
|
+
VEllipseSector.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {
|
|
9307
|
+
var _this = this;
|
|
9308
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
9309
|
+
// First get all line intersections from underlying ellipse.
|
|
9310
|
+
var ellipseIntersections = this.ellipse.lineIntersections(ray, inVectorBoundsOnly);
|
|
9311
|
+
// Drop all intersection points that are not contained in the circle sectors bounds.
|
|
9312
|
+
var tmpLine = new Line_1.Line(this.ellipse.center, new Vertex_1.Vertex());
|
|
9313
|
+
return ellipseIntersections.filter(function (intersectionPoint) {
|
|
9314
|
+
tmpLine.b.set(intersectionPoint);
|
|
9315
|
+
var lineAngle = tmpLine.angle();
|
|
9316
|
+
return _this.containsAngle(lineAngle - _this.ellipse.rotation);
|
|
9317
|
+
});
|
|
9318
|
+
};
|
|
9319
|
+
/**
|
|
9320
|
+
* Get all line intersections of this polygon and their tangents along the shape.
|
|
9321
|
+
*
|
|
9322
|
+
* This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.
|
|
9323
|
+
*
|
|
9324
|
+
* @method lineIntersections
|
|
9325
|
+
* @memberof VEllipseSectpr
|
|
9326
|
+
* @param line
|
|
9327
|
+
* @param lineIntersectionTangents
|
|
9328
|
+
* @returns
|
|
9329
|
+
*/
|
|
9330
|
+
VEllipseSector.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {
|
|
9331
|
+
var _this = this;
|
|
9332
|
+
if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }
|
|
9333
|
+
// Find the intersections of all lines plus their tangents inside the circle bounds
|
|
9334
|
+
var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);
|
|
9335
|
+
return interSectionPoints.map(function (vert) {
|
|
9336
|
+
// Calculate angle
|
|
9337
|
+
var lineFromCenter = new Line_1.Line(_this.ellipse.center, vert);
|
|
9338
|
+
var angle = lineFromCenter.angle();
|
|
9339
|
+
// console.log("angle", (angle / Math.PI) * 180.0);
|
|
9340
|
+
// const angle = Math.random() * Math.PI * 2; // TODO
|
|
9341
|
+
// Calculate tangent at angle
|
|
9342
|
+
return _this.ellipse.tangentAt(angle);
|
|
9343
|
+
});
|
|
9344
|
+
};
|
|
9345
|
+
//--- END --- Implement interface `Intersectable`
|
|
8244
9346
|
/**
|
|
8245
9347
|
* Convert this elliptic sector into cubic Bézier curves.
|
|
8246
9348
|
*
|
|
@@ -8268,8 +9370,8 @@ var VEllipseSector = /** @class */ (function () {
|
|
|
8268
9370
|
for (var i = 0; i + 1 < angles.length; i++) {
|
|
8269
9371
|
var nextAngle = angles[(i + 1) % angles.length];
|
|
8270
9372
|
var endPoint = this.ellipse.vertAt(nextAngle);
|
|
8271
|
-
var startTangent = this.ellipse.tangentAt(curAngle);
|
|
8272
|
-
var endTangent = this.ellipse.tangentAt(nextAngle);
|
|
9373
|
+
var startTangent = this.ellipse.tangentAt(curAngle + this.ellipse.rotation);
|
|
9374
|
+
var endTangent = this.ellipse.tangentAt(nextAngle + this.ellipse.rotation);
|
|
8273
9375
|
// Distorted ellipses can only be approximated by linear Bézier segments
|
|
8274
9376
|
if (Math.abs(radiusV) < 0.0001 || Math.abs(radiusH) < 0.0001) {
|
|
8275
9377
|
var diff = startPoint.difference(endPoint);
|
|
@@ -8379,7 +9481,7 @@ var VEllipseSector = /** @class */ (function () {
|
|
|
8379
9481
|
return angle >= startAngle || (angle <= endAngle && angle >= 0);
|
|
8380
9482
|
};
|
|
8381
9483
|
// Drop all angles outside the sector
|
|
8382
|
-
|
|
9484
|
+
ellipseAngles = ellipseAngles.filter(angleIsInRange);
|
|
8383
9485
|
// Now we need to sort the angles to the first one in the array is the closest to startAngle.
|
|
8384
9486
|
// --> find the angle that is closest to the start angle
|
|
8385
9487
|
var startIndex = VEllipseSector.ellipseSectorUtils.findClosestToStartAngle(startAngle, endAngle, ellipseAngles);
|
|
@@ -8493,7 +9595,8 @@ exports.VEllipseSector = VEllipseSector;
|
|
|
8493
9595
|
* @modified 2022-02-02 Added the `destroy` method.
|
|
8494
9596
|
* @modified 2022-02-02 Cleared the `Vector.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
8495
9597
|
* @modified 2022-10-25 Added the `getOrthogonal` method.
|
|
8496
|
-
* @
|
|
9598
|
+
* @modified 2025-04-14 Added the `Vector.rotate(number)` method.
|
|
9599
|
+
* @version 1.6.0
|
|
8497
9600
|
*
|
|
8498
9601
|
* @file Vector
|
|
8499
9602
|
* @public
|
|
@@ -8548,7 +9651,6 @@ var Vector = /** @class */ (function (_super) {
|
|
|
8548
9651
|
/**
|
|
8549
9652
|
* Get the perpendicular of this vector which is located at a.
|
|
8550
9653
|
*
|
|
8551
|
-
* @param {Number} t The position on the vector.
|
|
8552
9654
|
* @return {Vector} A new vector being the perpendicular of this vector sitting on a.
|
|
8553
9655
|
**/
|
|
8554
9656
|
Vector.prototype.perp = function () {
|
|
@@ -8624,6 +9726,19 @@ var Vector = /** @class */ (function (_super) {
|
|
|
8624
9726
|
startPoint.y = tmp;
|
|
8625
9727
|
return new Vector(linePoint, startPoint.add(this.a));
|
|
8626
9728
|
};
|
|
9729
|
+
/**
|
|
9730
|
+
* Rotate this vector by the given angle around the first point `a`.
|
|
9731
|
+
*
|
|
9732
|
+
* @name rotate
|
|
9733
|
+
* @method rotate
|
|
9734
|
+
* @return {Vector} this - for chaining.
|
|
9735
|
+
* @instance
|
|
9736
|
+
* @memberof Vector
|
|
9737
|
+
*/
|
|
9738
|
+
Vector.prototype.rotate = function (angle) {
|
|
9739
|
+
this.b.rotate(angle, this.a);
|
|
9740
|
+
return this;
|
|
9741
|
+
};
|
|
8627
9742
|
Vector.utils = {
|
|
8628
9743
|
/**
|
|
8629
9744
|
* Generate a four-point arrow head, starting at the vector end minus the
|
|
@@ -8686,7 +9801,10 @@ exports.Vector = Vector;
|
|
|
8686
9801
|
* @modified 2024-09-10 Chaging the first param of `pointDistance` from `Vertex` to less strict type `XYCoords`. This should not break anything.
|
|
8687
9802
|
* @modified 2024-09-10 Adding the optional `epsilon` param to the `hasPoint` method.
|
|
8688
9803
|
* @modified 2024-12-02 Added the `epsilon` param to the `colinear` method. Default is 1.0e-6.
|
|
8689
|
-
* @
|
|
9804
|
+
* @modified 2025-03-31 Added the `VertTuple.revert` method.
|
|
9805
|
+
* @modified 2025-04-15 Changed param of `VertTuple.moveTo` method from `Vertex` to `XYCoords`.
|
|
9806
|
+
* @modified 2025-04-15 Added method `VertTuple.move` method.
|
|
9807
|
+
* @version 1.4.0
|
|
8690
9808
|
*/
|
|
8691
9809
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
8692
9810
|
exports.VertTuple = void 0;
|
|
@@ -8755,15 +9873,31 @@ var VertTuple = /** @class */ (function () {
|
|
|
8755
9873
|
*
|
|
8756
9874
|
* @method add
|
|
8757
9875
|
* @param {XYCoords} amount The amount (x,y) to add.
|
|
8758
|
-
* @return {Line} this
|
|
8759
9876
|
* @instance
|
|
8760
9877
|
* @memberof VertTuple
|
|
9878
|
+
* @return {VertTuple<T>} this
|
|
8761
9879
|
**/
|
|
8762
9880
|
VertTuple.prototype.add = function (amount) {
|
|
8763
9881
|
this.a.add(amount);
|
|
8764
9882
|
this.b.add(amount);
|
|
8765
9883
|
return this;
|
|
8766
9884
|
};
|
|
9885
|
+
/**
|
|
9886
|
+
* Reverse this vertex tuple: a becomes b, and b becomes a.
|
|
9887
|
+
* This operation is in-place.
|
|
9888
|
+
*
|
|
9889
|
+
* @method add
|
|
9890
|
+
* @param {XYCoords} amount The amount (x,y) to add.
|
|
9891
|
+
* @instance
|
|
9892
|
+
* @memberof VertTuple
|
|
9893
|
+
* @return {VertTuple<T>} this
|
|
9894
|
+
*/
|
|
9895
|
+
VertTuple.prototype.revert = function () {
|
|
9896
|
+
var tmp = this.a;
|
|
9897
|
+
this.a = this.b;
|
|
9898
|
+
this.b = tmp;
|
|
9899
|
+
return this;
|
|
9900
|
+
};
|
|
8767
9901
|
/**
|
|
8768
9902
|
* Normalize this line (set to length 1).
|
|
8769
9903
|
*
|
|
@@ -8793,7 +9927,7 @@ var VertTuple = /** @class */ (function () {
|
|
|
8793
9927
|
* Move this line to a new location.
|
|
8794
9928
|
*
|
|
8795
9929
|
* @method moveTo
|
|
8796
|
-
* @param {
|
|
9930
|
+
* @param {XYCoords} newA - The new desired location of 'a'. Vertex 'b' will be moved, too.
|
|
8797
9931
|
* @return {VertTuple} this
|
|
8798
9932
|
* @instance
|
|
8799
9933
|
* @memberof VertTuple
|
|
@@ -8804,6 +9938,20 @@ var VertTuple = /** @class */ (function () {
|
|
|
8804
9938
|
this.b.add(diff);
|
|
8805
9939
|
return this;
|
|
8806
9940
|
};
|
|
9941
|
+
/**
|
|
9942
|
+
* Move this line by the given amount
|
|
9943
|
+
*
|
|
9944
|
+
* @method move
|
|
9945
|
+
* @param {XYCoords} amount - The amount to move both point of this tuple.
|
|
9946
|
+
* @return {VertTuple} this
|
|
9947
|
+
* @instance
|
|
9948
|
+
* @memberof VertTuple
|
|
9949
|
+
**/
|
|
9950
|
+
VertTuple.prototype.move = function (amount) {
|
|
9951
|
+
this.a.add(amount);
|
|
9952
|
+
this.b.add(amount);
|
|
9953
|
+
return this;
|
|
9954
|
+
};
|
|
8807
9955
|
/**
|
|
8808
9956
|
* Get the angle between this and the passed line (in radians).
|
|
8809
9957
|
*
|
|
@@ -9027,7 +10175,9 @@ exports.VertTuple = VertTuple;
|
|
|
9027
10175
|
* @modified 2023-09-29 Added the `Vertex.abs()` method as it seems useful.
|
|
9028
10176
|
* @modified 2024-03-08 Added the optional `precision` param to the `toString` method.
|
|
9029
10177
|
* @modified 2024-12-17 Outsourced the euclidean distance calculation of `Vertex.distance` to `geomutils.dist4`.
|
|
9030
|
-
* @
|
|
10178
|
+
* @modified 2025-03-24 Making the second parameter `center` of the `Vertex.rotate` method optional.
|
|
10179
|
+
* @modified 2025-04-13 Adding the `Vertex.move(amount: XYCoords)` method (does the same as `add`, added by naming convention).
|
|
10180
|
+
* @version 2.10.0
|
|
9031
10181
|
*
|
|
9032
10182
|
* @file Vertex
|
|
9033
10183
|
* @public
|
|
@@ -9224,6 +10374,21 @@ var Vertex = /** @class */ (function () {
|
|
|
9224
10374
|
}
|
|
9225
10375
|
return this;
|
|
9226
10376
|
};
|
|
10377
|
+
/**
|
|
10378
|
+
* Move this point by the given amount.
|
|
10379
|
+
*
|
|
10380
|
+
* This method just calls `add(amount).
|
|
10381
|
+
*
|
|
10382
|
+
*
|
|
10383
|
+
* @method move
|
|
10384
|
+
* @param {Vertex} amount - The amount to move this vertex.
|
|
10385
|
+
* @return {Vertex} this - For chaining.
|
|
10386
|
+
* @instance
|
|
10387
|
+
* @memberof Vertex
|
|
10388
|
+
*/
|
|
10389
|
+
Vertex.prototype.move = function (amount) {
|
|
10390
|
+
return this.add(amount);
|
|
10391
|
+
};
|
|
9227
10392
|
/**
|
|
9228
10393
|
* Add the passed amounts to the x- and y- components of this vertex.
|
|
9229
10394
|
*
|