plotboilerplate 1.28.1 → 1.29.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 +8 -0
- package/dist/index.esm.js +335 -39
- 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 +335 -37
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +1 -1
- package/src/cjs/Circle.d.ts +70 -3
- package/src/cjs/Circle.js +159 -4
- package/src/cjs/Circle.js.map +1 -1
- package/src/cjs/Triangle.d.ts +40 -4
- package/src/cjs/Triangle.js +127 -31
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/VertTuple.d.ts +4 -1
- package/src/cjs/VertTuple.js +6 -1
- package/src/cjs/VertTuple.js.map +1 -1
- package/src/cjs/Vertex.d.ts +25 -2
- package/src/cjs/Vertex.js +43 -1
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/utils/algorithms/minimalContainingCircleFromPoints.d.ts +21 -0
- package/src/cjs/utils/algorithms/minimalContainingCircleFromPoints.js +73 -0
- package/src/cjs/utils/algorithms/minimalContainingCircleFromPoints.js.map +1 -0
- package/src/cjs/utils/algorithms/minimalEnclosingCircleFromPoints.d.ts +21 -0
- package/src/cjs/utils/algorithms/minimalEnclosingCircleFromPoints.js +73 -0
- package/src/cjs/utils/algorithms/minimalEnclosingCircleFromPoints.js.map +1 -0
- package/src/cjs/utils/algorithms/pointsMinimalContainingCircle.d.ts +21 -0
- package/src/cjs/utils/algorithms/pointsMinimalContainingCircle.js +73 -0
- package/src/cjs/utils/algorithms/pointsMinimalContainingCircle.js.map +1 -0
- package/src/cjs/utils/algorithms/solveApollonius3.d.ts +69 -0
- package/src/cjs/utils/algorithms/solveApollonius3.js +118 -0
- package/src/cjs/utils/algorithms/solveApollonius3.js.map +1 -0
- package/src/esm/Circle.d.ts +70 -3
- package/src/esm/Circle.js +159 -4
- package/src/esm/Circle.js.map +1 -1
- package/src/esm/Triangle.d.ts +40 -4
- package/src/esm/Triangle.js +128 -32
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/VertTuple.d.ts +4 -1
- package/src/esm/VertTuple.js +6 -1
- package/src/esm/VertTuple.js.map +1 -1
- package/src/esm/Vertex.d.ts +25 -2
- package/src/esm/Vertex.js +44 -2
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/utils/algorithms/minimalContainingCircleFromPoints.d.ts +21 -0
- package/src/esm/utils/algorithms/minimalContainingCircleFromPoints.js +69 -0
- package/src/esm/utils/algorithms/minimalContainingCircleFromPoints.js.map +1 -0
- package/src/esm/utils/algorithms/minimalEnclosingCircleFromPoints.d.ts +21 -0
- package/src/esm/utils/algorithms/minimalEnclosingCircleFromPoints.js +69 -0
- package/src/esm/utils/algorithms/minimalEnclosingCircleFromPoints.js.map +1 -0
- package/src/esm/utils/algorithms/pointsMinimalContainingCircle.d.ts +21 -0
- package/src/esm/utils/algorithms/pointsMinimalContainingCircle.js +69 -0
- package/src/esm/utils/algorithms/pointsMinimalContainingCircle.js.map +1 -0
- package/src/esm/utils/algorithms/solveApollonius3.d.ts +69 -0
- package/src/esm/utils/algorithms/solveApollonius3.js +114 -0
- package/src/esm/utils/algorithms/solveApollonius3.js.map +1 -0
- package/src/index-gl.js +5 -2
- package/src/index.js +25 -17
- package/src/ts/Circle.ts +178 -5
- package/src/ts/Triangle.ts +148 -41
- package/src/ts/VertTuple.ts +14 -1
- package/src/ts/Vertex.ts +44 -2
- package/src/ts/utils/algorithms/minimalEnclosingCircleFromPoints.ts +69 -0
- package/src/ts/utils/algorithms/solveApollonius3.ts +132 -0
package/dist/plotboilerplate.js
CHANGED
|
@@ -1742,7 +1742,15 @@ exports.Bounds = Bounds;
|
|
|
1742
1742
|
* @modified 2022-08-23 Added the `closestPoint` function.
|
|
1743
1743
|
* @modified 2025-04-09 Added the `Circle.move(amount: XYCoords)` method.
|
|
1744
1744
|
* @modified 2025-04-16 Class `Circle` now implements interface `Intersectable`.
|
|
1745
|
-
* @
|
|
1745
|
+
* @modified 2026-06-10 Adding the utility function `Circle.circleUtils.containsPoint`.
|
|
1746
|
+
* @modified 2026-06-10 Adding the `Circle.clone` method.
|
|
1747
|
+
* @modified 2026-01-13 Adding helper function `Circle.circleUtils.containsPoint` and refactored the member method `containsPoint`.
|
|
1748
|
+
* @modified 2026-07-03 Adding the optional `epsilon` parameter to the `Circle.containsCircle` method.
|
|
1749
|
+
* @modified 2026-07-03 Fixing the `Circle.clone` method; the center had not been cloned at all, this was fixed.
|
|
1750
|
+
* @modified 2026-07-08 Adding the `Circle.setRadius` method (for chaining).
|
|
1751
|
+
* @mofified 2026-07-31 Adding the `radicalAxis(Circle)` method. Added the `Circle.circleUtils.createRadicalAxisHelperCircle` and `.circleDistance` helper methods.
|
|
1752
|
+
* @modified 2026-08-03 Adding `Circle.tangentsFromPoint`.
|
|
1753
|
+
* @version 1.7.0
|
|
1746
1754
|
**/
|
|
1747
1755
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1748
1756
|
exports.Circle = void 0;
|
|
@@ -1751,6 +1759,7 @@ var Line_1 = __webpack_require__(939);
|
|
|
1751
1759
|
var UIDGenerator_1 = __webpack_require__(938);
|
|
1752
1760
|
var Vector_1 = __webpack_require__(30);
|
|
1753
1761
|
var Vertex_1 = __webpack_require__(787);
|
|
1762
|
+
var geomutils_1 = __webpack_require__(328);
|
|
1754
1763
|
/**
|
|
1755
1764
|
* @classdesc A simple circle: center point and radius.
|
|
1756
1765
|
*
|
|
@@ -1780,6 +1789,20 @@ var Circle = /** @class */ (function () {
|
|
|
1780
1789
|
this.center = center;
|
|
1781
1790
|
this.radius = radius;
|
|
1782
1791
|
}
|
|
1792
|
+
/**
|
|
1793
|
+
* Set the radius of this circle.
|
|
1794
|
+
* The method is meant for chaining, you may also alter the `radius` attribute directly.
|
|
1795
|
+
*
|
|
1796
|
+
* @method setRadius
|
|
1797
|
+
* @param {number} radius - The amount to move.
|
|
1798
|
+
* @instance
|
|
1799
|
+
* @memberof Circle
|
|
1800
|
+
* @return {Circle} this for chaining
|
|
1801
|
+
**/
|
|
1802
|
+
Circle.prototype.setRadius = function (radius) {
|
|
1803
|
+
this.radius = radius;
|
|
1804
|
+
return this;
|
|
1805
|
+
};
|
|
1783
1806
|
/**
|
|
1784
1807
|
* Move the circle by the given amount.
|
|
1785
1808
|
*
|
|
@@ -1803,7 +1826,8 @@ var Circle = /** @class */ (function () {
|
|
|
1803
1826
|
* @return {boolean} `true` if the given point is inside this circle.
|
|
1804
1827
|
*/
|
|
1805
1828
|
Circle.prototype.containsPoint = function (point) {
|
|
1806
|
-
return this.center.distance(point) < this.radius
|
|
1829
|
+
// return this.center.distance(point) < this.radius;//
|
|
1830
|
+
return Circle.circleUtils.containsPoint(this.center, this.radius, point);
|
|
1807
1831
|
};
|
|
1808
1832
|
/**
|
|
1809
1833
|
* Check if the given circle is fully contained inside this circle.
|
|
@@ -1814,8 +1838,13 @@ var Circle = /** @class */ (function () {
|
|
|
1814
1838
|
* @memberof Circle
|
|
1815
1839
|
* @return {boolean} `true` if any only if the given circle is completely inside this circle.
|
|
1816
1840
|
*/
|
|
1817
|
-
Circle.prototype.containsCircle = function (circle) {
|
|
1818
|
-
|
|
1841
|
+
Circle.prototype.containsCircle = function (circle, epsilon) {
|
|
1842
|
+
if (typeof epsilon === "undefined" || Number.isNaN(epsilon)) {
|
|
1843
|
+
return this.center.distance(circle.center) + circle.radius < this.radius;
|
|
1844
|
+
}
|
|
1845
|
+
else {
|
|
1846
|
+
return this.center.distance(circle.center) + circle.radius < this.radius + Math.abs(epsilon);
|
|
1847
|
+
}
|
|
1819
1848
|
};
|
|
1820
1849
|
/**
|
|
1821
1850
|
* Calculate the distance from this circle to the given line.
|
|
@@ -2021,6 +2050,40 @@ var Circle = /** @class */ (function () {
|
|
|
2021
2050
|
});
|
|
2022
2051
|
};
|
|
2023
2052
|
//--- END --- Implement interface `Intersectable`
|
|
2053
|
+
/**
|
|
2054
|
+
* Calculate the radical axis of this and a different circle.
|
|
2055
|
+
* The two circles must not be co-centric.
|
|
2056
|
+
*
|
|
2057
|
+
* See this article for details:
|
|
2058
|
+
* https://www.cut-the-knot.org/Curriculum/Geometry/GeoGebra/RadicalAxes.shtml
|
|
2059
|
+
*
|
|
2060
|
+
* @method radicalAxis
|
|
2061
|
+
* @instance
|
|
2062
|
+
* @memberof Circle
|
|
2063
|
+
* @param {Circle} circleB - The second circle to calculated the radical axis for.
|
|
2064
|
+
* @return {Line} A line defining the radical axis of the two circles.
|
|
2065
|
+
**/
|
|
2066
|
+
Circle.prototype.radicalAxis = function (circleB) {
|
|
2067
|
+
var helperCircle = Circle.circleUtils.createRadicalAxisHelperCircle(this, circleB);
|
|
2068
|
+
var intersectionLineA = this.circleIntersection(helperCircle);
|
|
2069
|
+
var intersectionLineB = circleB.circleIntersection(helperCircle);
|
|
2070
|
+
var intersection = this.circleIntersection(circleB);
|
|
2071
|
+
if (!intersectionLineA || !intersectionLineB) {
|
|
2072
|
+
console.error("Critical error: none of the two intersections must be null.");
|
|
2073
|
+
return intersection; // Fallback
|
|
2074
|
+
}
|
|
2075
|
+
var lineA = new Line_1.Line(intersectionLineA.a, intersectionLineA.b);
|
|
2076
|
+
var lineB = new Line_1.Line(intersectionLineB.a, intersectionLineB.b);
|
|
2077
|
+
var firstRadicalAxisPoint = lineA.intersection(lineB);
|
|
2078
|
+
var centerConnectLine = new Line_1.Line(this.center, circleB.center);
|
|
2079
|
+
var secondRadicalAxisPoint = centerConnectLine.getClosestPoint(firstRadicalAxisPoint);
|
|
2080
|
+
// Create a mirrored version of the second radical axis point so both are located
|
|
2081
|
+
// symmetrical from the circle connect point.
|
|
2082
|
+
// (currently the second point is located ON the connect line)
|
|
2083
|
+
var secondRadicalAxisPoint_mirrored = secondRadicalAxisPoint.clone().scale(2.0, firstRadicalAxisPoint);
|
|
2084
|
+
var radicalAxis = new Line_1.Line(firstRadicalAxisPoint, secondRadicalAxisPoint_mirrored);
|
|
2085
|
+
return intersection && intersection.length() > radicalAxis.length() ? intersection : radicalAxis;
|
|
2086
|
+
};
|
|
2024
2087
|
/**
|
|
2025
2088
|
* Calculate the closest point on the outline of this circle to the given point.
|
|
2026
2089
|
*
|
|
@@ -2044,6 +2107,71 @@ var Circle = /** @class */ (function () {
|
|
|
2044
2107
|
return lineIntersection.b;
|
|
2045
2108
|
}
|
|
2046
2109
|
};
|
|
2110
|
+
/**
|
|
2111
|
+
* Get the two tangent vectors for the given point.
|
|
2112
|
+
* If the point is on or in the circle then null is returned.
|
|
2113
|
+
*
|
|
2114
|
+
* @method tangentsFromPoint
|
|
2115
|
+
* @instance
|
|
2116
|
+
* @memberof Circle
|
|
2117
|
+
* @param {Vertex} vert - The point to find the two tangents for.
|
|
2118
|
+
* @return {[Vector,Vector]} The two tangent vector
|
|
2119
|
+
**/
|
|
2120
|
+
Circle.prototype.tangentsFromPoint = function (vert) {
|
|
2121
|
+
// Inspired by
|
|
2122
|
+
// https://www.omnicalculator.com/math/tangent-circle
|
|
2123
|
+
var centerDistance = this.center.distance(vert);
|
|
2124
|
+
var tangentLength = Math.sqrt(centerDistance * centerDistance - this.radius * this.radius);
|
|
2125
|
+
// console.log("this.radius ", this.radius, "centerDistance", centerDistance, "tangentLength", tangentLength);
|
|
2126
|
+
if (Number.isNaN(tangentLength)) {
|
|
2127
|
+
// vertex is inside circle
|
|
2128
|
+
console.log("tangentLength is NaN", tangentLength);
|
|
2129
|
+
return null;
|
|
2130
|
+
}
|
|
2131
|
+
var helperCircle = new Circle(vert, tangentLength);
|
|
2132
|
+
var intersection = this.circleIntersection(helperCircle);
|
|
2133
|
+
if (!intersection) {
|
|
2134
|
+
// No intersection (vertex is inside circle)
|
|
2135
|
+
return null;
|
|
2136
|
+
}
|
|
2137
|
+
return [new Vector_1.Vector(intersection.a, vert), new Vector_1.Vector(intersection.b, vert)];
|
|
2138
|
+
};
|
|
2139
|
+
/**
|
|
2140
|
+
* Create a deep copy of this circle.
|
|
2141
|
+
*
|
|
2142
|
+
* @method clone
|
|
2143
|
+
* @return {Circle} A new circle, an exact copy of this one.
|
|
2144
|
+
* @instance
|
|
2145
|
+
* @memberof Circle
|
|
2146
|
+
**/
|
|
2147
|
+
Circle.prototype.clone = function () {
|
|
2148
|
+
return new Circle(this.center.clone(), this.radius);
|
|
2149
|
+
};
|
|
2150
|
+
Circle.fromICircle = function (obj) {
|
|
2151
|
+
return new Circle(new Vertex_1.Vertex(obj.center), obj.radius);
|
|
2152
|
+
};
|
|
2153
|
+
// static fromObject(obj: object): Circle {
|
|
2154
|
+
// if (!obj) {
|
|
2155
|
+
// return null;
|
|
2156
|
+
// }
|
|
2157
|
+
// if (typeof obj !== "object") {
|
|
2158
|
+
// return null;
|
|
2159
|
+
// }
|
|
2160
|
+
// if (!obj.hasOwnProperty("center") || typeof (obj as any).center != "object") {
|
|
2161
|
+
// return null;
|
|
2162
|
+
// }
|
|
2163
|
+
// if (!obj.hasOwnProperty("radius") || typeof !(obj as any).radius != "number") {
|
|
2164
|
+
// return null;
|
|
2165
|
+
// }
|
|
2166
|
+
// var center = (obj as any).center;
|
|
2167
|
+
// if (!center.hasOwnProperty("x") || typeof (center as any).x != "number") {
|
|
2168
|
+
// return null;
|
|
2169
|
+
// }
|
|
2170
|
+
// if (!center.hasOwnProperty("y") || typeof (center as any).y != "number") {
|
|
2171
|
+
// return null;
|
|
2172
|
+
// }
|
|
2173
|
+
// return new Circle(new Vertex(center), (obj as any).radius);
|
|
2174
|
+
// }
|
|
2047
2175
|
/**
|
|
2048
2176
|
* This function should invalidate any installed listeners and invalidate this object.
|
|
2049
2177
|
* After calling this function the object might not hold valid data any more and
|
|
@@ -2058,6 +2186,33 @@ var Circle = /** @class */ (function () {
|
|
|
2058
2186
|
/* return new Vertex( Math.sin(angle) * radius,
|
|
2059
2187
|
Math.cos(angle) * radius ); */
|
|
2060
2188
|
return new Vertex_1.Vertex(Math.cos(angle) * radius, Math.sin(angle) * radius);
|
|
2189
|
+
},
|
|
2190
|
+
containsPoint: function (circleCenter, circleRadius, point) {
|
|
2191
|
+
// TODO: cleanup
|
|
2192
|
+
// return (
|
|
2193
|
+
// (circle.center.x - point.x) * (circle.center.x - point.x) + (circle.center.y - point.y) * (circle.center.y - point.y) <=
|
|
2194
|
+
// circle.radius * circle.radius
|
|
2195
|
+
// );
|
|
2196
|
+
return geomutils_1.geomutils.dist4(point.x, point.y, circleCenter.x, circleCenter.y) < circleRadius;
|
|
2197
|
+
},
|
|
2198
|
+
createRadicalAxisHelperCircle: function (circleA, circleB) {
|
|
2199
|
+
// We need to create a helper circle that intersects BOTH other circles,
|
|
2200
|
+
// each in TWO points.
|
|
2201
|
+
var circleConnectLine = new Vector_1.Vector(circleA.center.clone(), circleB.center);
|
|
2202
|
+
circleConnectLine.a.set(circleConnectLine.vertAt(0.5));
|
|
2203
|
+
// Get the perpendicular by half the circle distance.
|
|
2204
|
+
var bisector = circleConnectLine.perp();
|
|
2205
|
+
var bisectorLength = Math.max(circleA.radius, circleB.radius, bisector.length());
|
|
2206
|
+
bisector.setLength(bisectorLength);
|
|
2207
|
+
return new Circle(bisector.b, bisector.b.distance(circleA.center));
|
|
2208
|
+
},
|
|
2209
|
+
/**
|
|
2210
|
+
* Calculate the outer distance between two circles. If the circles touch then the
|
|
2211
|
+
* distance is 0.0.
|
|
2212
|
+
* If the circles intersect then the distance in negative.
|
|
2213
|
+
*/
|
|
2214
|
+
circleDistance: function (circleA, circleB) {
|
|
2215
|
+
return circleA.center.distance(circleB.center) - circleA.radius - circleB.radius;
|
|
2061
2216
|
}
|
|
2062
2217
|
};
|
|
2063
2218
|
return Circle;
|
|
@@ -8122,7 +8277,8 @@ exports["default"] = PlotBoilerplate;
|
|
|
8122
8277
|
* @modified 2025-03-31 Added the `VertTuple.revert` method.
|
|
8123
8278
|
* @modified 2025-04-15 Changed param of `VertTuple.moveTo` method from `Vertex` to `XYCoords`.
|
|
8124
8279
|
* @modified 2025-04-15 Added method `VertTuple.move` method.
|
|
8125
|
-
* @
|
|
8280
|
+
* @modified 2026-06-10 Adding helper function `VertTuple.utils.calcCircumcircle`.
|
|
8281
|
+
* @version 1.5.0
|
|
8126
8282
|
*/
|
|
8127
8283
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
8128
8284
|
exports.VertTuple = void 0;
|
|
@@ -8445,6 +8601,10 @@ var VertTuple = /** @class */ (function () {
|
|
|
8445
8601
|
VertTuple.vtutils = {
|
|
8446
8602
|
dist2: function (v, w) {
|
|
8447
8603
|
return (v.x - w.x) * (v.x - w.x) + (v.y - w.y) * (v.y - w.y);
|
|
8604
|
+
},
|
|
8605
|
+
calcCircumcircle: function (p1, p2) {
|
|
8606
|
+
var p1x = p1.x, p1y = p1.y, p2x = p2.x, p2y = p2.y, cx = 0.5 * (p1x + p2x), cy = 0.5 * (p1y + p2y);
|
|
8607
|
+
return { center: { x: cx, y: cy }, radius: Math.sqrt((p1x - cx) * (p1x - cx) + (p1y - cy) * (p1y - cy)) };
|
|
8448
8608
|
}
|
|
8449
8609
|
};
|
|
8450
8610
|
return VertTuple;
|
|
@@ -11479,7 +11639,10 @@ exports.BezierPath = BezierPath;
|
|
|
11479
11639
|
* @modified 2025-14-16 Class `Triangle` now implements interface `IBounded`.
|
|
11480
11640
|
* @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.
|
|
11481
11641
|
* @modified 2025-14-16 Added method `Triangle.move`.
|
|
11482
|
-
* @
|
|
11642
|
+
* @modified 2026-06-10 Refactoring the `Trianble.bounds` method and added a plain `Triangle.utils.bounds` method.
|
|
11643
|
+
* @modified 2026-06-10 Refactoring the `Trianble.calcCircumCircle` method and added a plain `Triangle.utils.calcCircumCircle` method.
|
|
11644
|
+
* @modified 2026-06-13 Adding `Triangle.getVertices()`.
|
|
11645
|
+
* @version 2.11.0
|
|
11483
11646
|
*
|
|
11484
11647
|
* @file Triangle
|
|
11485
11648
|
* @fileoverview A simple triangle class: three vertices.
|
|
@@ -11493,6 +11656,7 @@ var Line_1 = __webpack_require__(939);
|
|
|
11493
11656
|
var Polygon_1 = __webpack_require__(687);
|
|
11494
11657
|
var UIDGenerator_1 = __webpack_require__(938);
|
|
11495
11658
|
var Vector_1 = __webpack_require__(30);
|
|
11659
|
+
var VertTuple_1 = __webpack_require__(590);
|
|
11496
11660
|
var Vertex_1 = __webpack_require__(787);
|
|
11497
11661
|
var geomutils_1 = __webpack_require__(328);
|
|
11498
11662
|
/**
|
|
@@ -11634,7 +11798,7 @@ var Triangle = /** @class */ (function () {
|
|
|
11634
11798
|
* after triangle vertex changes.
|
|
11635
11799
|
*
|
|
11636
11800
|
* @method getCircumcircle
|
|
11637
|
-
* @return {
|
|
11801
|
+
* @return {Circle} - The circle touching exactly all three triangle vertices.
|
|
11638
11802
|
* @instance
|
|
11639
11803
|
* @memberof Triangle
|
|
11640
11804
|
*/
|
|
@@ -11643,6 +11807,33 @@ var Triangle = /** @class */ (function () {
|
|
|
11643
11807
|
this.calcCircumcircle();
|
|
11644
11808
|
return new Circle_1.Circle(this.center.clone(), this.radius);
|
|
11645
11809
|
};
|
|
11810
|
+
/**
|
|
11811
|
+
* Calculates the minimun enclosing circle.
|
|
11812
|
+
*
|
|
11813
|
+
* @method getMinimumEnclosingCircle
|
|
11814
|
+
* @return {Object} - { center:Vertex, radius:float }
|
|
11815
|
+
* @instance
|
|
11816
|
+
* @memberof Triangle
|
|
11817
|
+
* @returns
|
|
11818
|
+
*/
|
|
11819
|
+
Triangle.prototype.getMinimumEnclosingCircle = function () {
|
|
11820
|
+
// First option: two points construct a circle and the third point is contained.
|
|
11821
|
+
var circleAB = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.a, this.b);
|
|
11822
|
+
if (Circle_1.Circle.circleUtils.containsPoint(circleAB.center, circleAB.radius, this.c)) {
|
|
11823
|
+
return Circle_1.Circle.fromICircle(circleAB);
|
|
11824
|
+
}
|
|
11825
|
+
var circleBC = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.b, this.c);
|
|
11826
|
+
if (Circle_1.Circle.circleUtils.containsPoint(circleBC.center, circleBC.radius, this.c)) {
|
|
11827
|
+
return Circle_1.Circle.fromICircle(circleBC);
|
|
11828
|
+
}
|
|
11829
|
+
var circleCA = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.c, this.a);
|
|
11830
|
+
if (Circle_1.Circle.circleUtils.containsPoint(circleCA.center, circleCA.radius, this.c)) {
|
|
11831
|
+
return Circle_1.Circle.fromICircle(circleCA);
|
|
11832
|
+
}
|
|
11833
|
+
// If none of the three upper cases applies: return the circumcircle.
|
|
11834
|
+
var circumCircle = Triangle.utils.calcCircumcircle(this.a, this.b, this.c);
|
|
11835
|
+
return Circle_1.Circle.fromICircle(circumCircle);
|
|
11836
|
+
};
|
|
11646
11837
|
/**
|
|
11647
11838
|
* Check if this triangle and the passed triangle share an
|
|
11648
11839
|
* adjacent edge.
|
|
@@ -11681,6 +11872,17 @@ var Triangle = /** @class */ (function () {
|
|
|
11681
11872
|
//if( this.c.equals(vert1) && this.a.equals(vert2) || this.c.equals(vert2) && this.a.equals(vert1) )
|
|
11682
11873
|
return this.b;
|
|
11683
11874
|
};
|
|
11875
|
+
/**
|
|
11876
|
+
* Get the three triangele vertices in a 3-element array.
|
|
11877
|
+
*
|
|
11878
|
+
* @method getVertices
|
|
11879
|
+
* @returns {[Vertex, Vertex, Vertex]} - The three vertices – real instances, not copies.
|
|
11880
|
+
* @instance
|
|
11881
|
+
* @memberof Triangle
|
|
11882
|
+
*/
|
|
11883
|
+
Triangle.prototype.getVertices = function () {
|
|
11884
|
+
return [this.a, this.b, this.c];
|
|
11885
|
+
};
|
|
11684
11886
|
/**
|
|
11685
11887
|
* Re-compute the circumcircle of this triangle (if the vertices
|
|
11686
11888
|
* have changed).
|
|
@@ -11694,32 +11896,35 @@ var Triangle = /** @class */ (function () {
|
|
|
11694
11896
|
* @memberof Triangle
|
|
11695
11897
|
*/
|
|
11696
11898
|
Triangle.prototype.calcCircumcircle = function () {
|
|
11697
|
-
// From
|
|
11698
|
-
// http://www.exaflop.org/docs/cgafaq/cga1.html
|
|
11699
|
-
|
|
11700
|
-
|
|
11701
|
-
|
|
11702
|
-
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
|
|
11706
|
-
|
|
11707
|
-
if (Math.abs(G) < Triangle.EPSILON) {
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
}
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
this.
|
|
11722
|
-
|
|
11899
|
+
// // From
|
|
11900
|
+
// // http://www.exaflop.org/docs/cgafaq/cga1.html
|
|
11901
|
+
// const A: number = this.b.x - this.a.x;
|
|
11902
|
+
// const B: number = this.b.y - this.a.y;
|
|
11903
|
+
// const C: number = this.c.x - this.a.x;
|
|
11904
|
+
// const D: number = this.c.y - this.a.y;
|
|
11905
|
+
// const E: number = A * (this.a.x + this.b.x) + B * (this.a.y + this.b.y);
|
|
11906
|
+
// const F: number = C * (this.a.x + this.c.x) + D * (this.a.y + this.c.y);
|
|
11907
|
+
// const G: number = 2.0 * (A * (this.c.y - this.b.y) - B * (this.c.x - this.b.x));
|
|
11908
|
+
// let dx: number, dy: number;
|
|
11909
|
+
// if (Math.abs(G) < Triangle.EPSILON) {
|
|
11910
|
+
// // Collinear - find extremes and use the midpoint
|
|
11911
|
+
// const bounds: Bounds = this.bounds();
|
|
11912
|
+
// this.center = new Vertex((bounds.min.x + bounds.max.x) / 2, (bounds.min.y + bounds.max.y) / 2);
|
|
11913
|
+
// dx = this.center.x - bounds.min.x;
|
|
11914
|
+
// dy = this.center.y - bounds.min.y;
|
|
11915
|
+
// } else {
|
|
11916
|
+
// const cx: number = (D * E - B * F) / G;
|
|
11917
|
+
// const cy: number = (A * F - C * E) / G;
|
|
11918
|
+
// this.center = new Vertex(cx, cy);
|
|
11919
|
+
// dx = this.center.x - this.a.x;
|
|
11920
|
+
// dy = this.center.y - this.a.y;
|
|
11921
|
+
// }
|
|
11922
|
+
// this.radius_squared = dx * dx + dy * dy;
|
|
11923
|
+
// this.radius = Math.sqrt(this.radius_squared);
|
|
11924
|
+
var tmpCircle = Triangle.utils.calcCircumcircle(this.a, this.b, this.c);
|
|
11925
|
+
this.center = new Vertex_1.Vertex(tmpCircle.center.x, tmpCircle.center.y);
|
|
11926
|
+
this.radius = tmpCircle.radius;
|
|
11927
|
+
this.radius_squared = tmpCircle.radius_squared;
|
|
11723
11928
|
}; // END calcCircumcircle
|
|
11724
11929
|
/**
|
|
11725
11930
|
* Check if the passed vertex is inside this triangle's
|
|
@@ -11746,7 +11951,11 @@ var Triangle = /** @class */ (function () {
|
|
|
11746
11951
|
* @memberof Triangle
|
|
11747
11952
|
*/
|
|
11748
11953
|
Triangle.prototype.bounds = function () {
|
|
11749
|
-
return new
|
|
11954
|
+
// return new Bounds(
|
|
11955
|
+
// new 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)),
|
|
11956
|
+
// new 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))
|
|
11957
|
+
// );
|
|
11958
|
+
return Triangle.utils.bounds(this.a, this.b, this.c);
|
|
11750
11959
|
};
|
|
11751
11960
|
//--- BEGIN --- Implement interface `Intersectable`
|
|
11752
11961
|
/**
|
|
@@ -11872,8 +12081,9 @@ var Triangle = /** @class */ (function () {
|
|
|
11872
12081
|
* @return Vertex The incenter of this triangle.
|
|
11873
12082
|
**/
|
|
11874
12083
|
Triangle.prototype.getIncenter = function () {
|
|
11875
|
-
if (!this.center || !this.radius)
|
|
12084
|
+
if (!this.center || !this.radius) {
|
|
11876
12085
|
this.calcCircumcircle();
|
|
12086
|
+
}
|
|
11877
12087
|
return this.center.clone();
|
|
11878
12088
|
};
|
|
11879
12089
|
/**
|
|
@@ -11940,7 +12150,53 @@ var Triangle = /** @class */ (function () {
|
|
|
11940
12150
|
*/
|
|
11941
12151
|
determinant: function (a, b, c) {
|
|
11942
12152
|
return (b.y - a.y) * (c.x - b.x) - (c.y - b.y) * (b.x - a.x);
|
|
11943
|
-
}
|
|
12153
|
+
},
|
|
12154
|
+
bounds: function (a, b, c) {
|
|
12155
|
+
return new Bounds_1.Bounds(new Vertex_1.Vertex(Triangle.utils.min3(a.x, b.x, c.x), Triangle.utils.min3(a.y, b.y, c.y)), new Vertex_1.Vertex(Triangle.utils.max3(a.x, b.x, c.x), Triangle.utils.max3(a.y, b.y, c.y)));
|
|
12156
|
+
},
|
|
12157
|
+
/**
|
|
12158
|
+
* Re-compute the circumcircle of this triangle (if the vertices
|
|
12159
|
+
* have changed).
|
|
12160
|
+
*
|
|
12161
|
+
* The circumcenter and radius are stored in this.center and
|
|
12162
|
+
* this.radius. There is a third result: radius_squared (for internal computations).
|
|
12163
|
+
*
|
|
12164
|
+
* @method calcCircumcircle
|
|
12165
|
+
* @return void
|
|
12166
|
+
* @instance
|
|
12167
|
+
* @memberof Triangle
|
|
12168
|
+
*/
|
|
12169
|
+
calcCircumcircle: function (a, b, c) {
|
|
12170
|
+
// From
|
|
12171
|
+
// http://www.exaflop.org/docs/cgafaq/cga1.html
|
|
12172
|
+
var A = b.x - a.x;
|
|
12173
|
+
var B = b.y - a.y;
|
|
12174
|
+
var C = c.x - a.x;
|
|
12175
|
+
var D = c.y - a.y;
|
|
12176
|
+
var E = A * (a.x + b.x) + B * (a.y + b.y);
|
|
12177
|
+
var F = C * (a.x + c.x) + D * (a.y + c.y);
|
|
12178
|
+
var G = 2.0 * (A * (c.y - b.y) - B * (c.x - b.x));
|
|
12179
|
+
var dx, dy;
|
|
12180
|
+
var center;
|
|
12181
|
+
if (Math.abs(G) < Triangle.EPSILON) {
|
|
12182
|
+
// Collinear - find extremes and use the midpoint
|
|
12183
|
+
// const bounds: Bounds = this.bounds();
|
|
12184
|
+
var bounds = Triangle.utils.bounds(a, b, c);
|
|
12185
|
+
center = new Vertex_1.Vertex((bounds.min.x + bounds.max.x) / 2, (bounds.min.y + bounds.max.y) / 2);
|
|
12186
|
+
dx = center.x - bounds.min.x;
|
|
12187
|
+
dy = center.y - bounds.min.y;
|
|
12188
|
+
}
|
|
12189
|
+
else {
|
|
12190
|
+
var cx = (D * E - B * F) / G;
|
|
12191
|
+
var cy = (A * F - C * E) / G;
|
|
12192
|
+
center = new Vertex_1.Vertex(cx, cy);
|
|
12193
|
+
dx = center.x - a.x;
|
|
12194
|
+
dy = center.y - a.y;
|
|
12195
|
+
}
|
|
12196
|
+
var radius_squared = dx * dx + dy * dy;
|
|
12197
|
+
var radius = Math.sqrt(radius_squared);
|
|
12198
|
+
return { center: center, radius: radius, radius_squared: radius_squared };
|
|
12199
|
+
} // END calcCircumcircle
|
|
11944
12200
|
};
|
|
11945
12201
|
return Triangle;
|
|
11946
12202
|
}());
|
|
@@ -11991,7 +12247,8 @@ exports.Triangle = Triangle;
|
|
|
11991
12247
|
* @modified 2025-03-24 Making the second parameter `center` of the `Vertex.rotate` method optional.
|
|
11992
12248
|
* @modified 2025-04-13 Adding the `Vertex.move(amount: XYCoords)` method (does the same as `add`, added by naming convention).
|
|
11993
12249
|
* @modified 2025-05-07 Class `Vertex` is now implementing interface `IBounded` (to meet convention).
|
|
11994
|
-
* @
|
|
12250
|
+
* @modified 2026-06-10 Adding methods `Vertex.findClosestPoint` and `Vertex.findFarestPoint`.
|
|
12251
|
+
* @version 2.12.0
|
|
11995
12252
|
*
|
|
11996
12253
|
* @file Vertex
|
|
11997
12254
|
* @public
|
|
@@ -12558,6 +12815,47 @@ var Vertex = /** @class */ (function () {
|
|
|
12558
12815
|
return Bounds_1.Bounds.computeFromVertices([this]);
|
|
12559
12816
|
};
|
|
12560
12817
|
//--- END --- Implement interface `IBounded`
|
|
12818
|
+
/**
|
|
12819
|
+
* Find the one of two given points that's closest to this point.
|
|
12820
|
+
*
|
|
12821
|
+
* @method findClosestPoint
|
|
12822
|
+
* @instance
|
|
12823
|
+
* @memberof Vertex
|
|
12824
|
+
* @param {XYCoords | Vertex} pointA
|
|
12825
|
+
* @param {XYCoords | Vertex} pointB
|
|
12826
|
+
* @returns {XYCoords | Vertex}
|
|
12827
|
+
*/
|
|
12828
|
+
Vertex.prototype.findClosestPoint = function (pointA, pointB) {
|
|
12829
|
+
// TODO: put this implementation to geomutils?
|
|
12830
|
+
var distA = this.distance(pointA);
|
|
12831
|
+
var distB = this.distance(pointB);
|
|
12832
|
+
if (distA < distB) {
|
|
12833
|
+
return pointA;
|
|
12834
|
+
}
|
|
12835
|
+
else {
|
|
12836
|
+
return pointB;
|
|
12837
|
+
}
|
|
12838
|
+
};
|
|
12839
|
+
/**
|
|
12840
|
+
* Find the one of two given points that's farest from this point.
|
|
12841
|
+
*
|
|
12842
|
+
* @method findFarestPoint
|
|
12843
|
+
* @instance
|
|
12844
|
+
* @memberof Vertex
|
|
12845
|
+
* @param {XYCoords | Vertex} pointA
|
|
12846
|
+
* @param {XYCoords | Vertex} pointB
|
|
12847
|
+
* @returns {XYCoords | Vertex}
|
|
12848
|
+
*/
|
|
12849
|
+
Vertex.prototype.findFarestPoint = function (pointA, pointB) {
|
|
12850
|
+
var distA = this.distance(pointA);
|
|
12851
|
+
var distB = this.distance(pointB);
|
|
12852
|
+
if (distA > distB) {
|
|
12853
|
+
return pointA;
|
|
12854
|
+
}
|
|
12855
|
+
else {
|
|
12856
|
+
return pointB;
|
|
12857
|
+
}
|
|
12858
|
+
};
|
|
12561
12859
|
/**
|
|
12562
12860
|
* Get a string representation of this vertex.
|
|
12563
12861
|
*
|