plotboilerplate 1.15.0 → 1.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/changelog.md +65 -0
- package/dist/index.esm.js +760 -667
- 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 +765 -571
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +1 -1
- package/src/cjs/BezierPath.d.ts +32 -14
- package/src/cjs/BezierPath.js +65 -24
- package/src/cjs/BezierPath.js.map +1 -1
- package/src/cjs/Bounds.d.ts +33 -1
- package/src/cjs/Bounds.js +38 -1
- package/src/cjs/Bounds.js.map +1 -1
- package/src/cjs/Circle.d.ts +15 -13
- package/src/cjs/Circle.js +16 -34
- package/src/cjs/Circle.js.map +1 -1
- package/src/cjs/CircleSector.d.ts +17 -16
- package/src/cjs/CircleSector.js +12 -24
- package/src/cjs/CircleSector.js.map +1 -1
- package/src/cjs/CubicBezierCurve.d.ts +16 -15
- package/src/cjs/CubicBezierCurve.js +57 -94
- package/src/cjs/CubicBezierCurve.js.map +1 -1
- package/src/cjs/KeyHandler.d.ts +10 -3
- package/src/cjs/KeyHandler.js +28 -23
- package/src/cjs/KeyHandler.js.map +1 -1
- package/src/cjs/Line.d.ts +2 -15
- package/src/cjs/Line.js +6 -31
- package/src/cjs/Line.js.map +1 -1
- package/src/cjs/MouseHandler.js +43 -53
- package/src/cjs/MouseHandler.js.map +1 -1
- package/src/cjs/PBImage.d.ts +15 -13
- package/src/cjs/PBImage.js +11 -15
- package/src/cjs/PBImage.js.map +1 -1
- package/src/cjs/PBText.d.ts +13 -12
- package/src/cjs/PBText.js +8 -12
- package/src/cjs/PBText.js.map +1 -1
- package/src/cjs/PlotBoilerplate.d.ts +3 -1
- package/src/cjs/PlotBoilerplate.js +9 -2
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +23 -14
- package/src/cjs/Polygon.js +22 -35
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Triangle.d.ts +15 -13
- package/src/cjs/Triangle.js +23 -64
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/VEllipse.d.ts +14 -9
- package/src/cjs/VEllipse.js +10 -18
- package/src/cjs/VEllipse.js.map +1 -1
- package/src/cjs/VEllipseSector.d.ts +15 -1
- package/src/cjs/VEllipseSector.js +11 -1
- package/src/cjs/VEllipseSector.js.map +1 -1
- package/src/cjs/Vector.d.ts +3 -15
- package/src/cjs/Vector.js +9 -49
- package/src/cjs/Vector.js.map +1 -1
- package/src/cjs/VertTuple.d.ts +15 -1
- package/src/cjs/VertTuple.js +14 -19
- package/src/cjs/VertTuple.js.map +1 -1
- package/src/cjs/Vertex.d.ts +23 -13
- package/src/cjs/Vertex.js +24 -22
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/VertexListeners.d.ts +12 -8
- package/src/cjs/VertexListeners.js +18 -25
- package/src/cjs/VertexListeners.js.map +1 -1
- package/src/cjs/draw.d.ts +45 -3
- package/src/cjs/draw.js +149 -6
- package/src/cjs/draw.js.map +1 -1
- package/src/cjs/drawgl.d.ts +41 -3
- package/src/cjs/drawgl.js +45 -3
- package/src/cjs/drawgl.js.map +1 -1
- package/src/cjs/drawutilssvg.d.ts +69 -4
- package/src/cjs/drawutilssvg.js +147 -16
- package/src/cjs/drawutilssvg.js.map +1 -1
- package/src/cjs/index.d.ts +0 -1
- package/src/cjs/index.js +0 -1
- package/src/cjs/index.js.map +1 -1
- package/src/cjs/interfaces/DrawLib.d.ts +64 -27
- package/src/cjs/interfaces/DrawLib.js +3 -0
- package/src/cjs/interfaces/DrawLib.js.map +1 -1
- package/src/cjs/interfaces/core.d.ts +2 -12
- package/src/cjs/interfaces/core.js +1 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- package/src/cjs/module.d.ts +1 -3
- package/src/cjs/module.js +2 -5
- package/src/cjs/module.js.map +1 -1
- package/src/cjs/utils/creategui.js +16 -2
- package/src/cjs/utils/datastructures/Color.d.ts +3 -1
- package/src/cjs/utils/datastructures/Color.js +17 -6
- package/src/cjs/utils/datastructures/Color.js.map +1 -1
- package/src/cjs/utils/datastructures/Girih.d.ts +5 -0
- package/src/cjs/utils/datastructures/Girih.js +18 -14
- package/src/cjs/utils/datastructures/Girih.js.map +1 -1
- package/src/cjs/utils/datastructures/GirihPenroseRhombus.js +42 -25
- package/src/cjs/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
- package/src/cjs/utils/datastructures/GirihTile.js +2 -13
- package/src/cjs/utils/datastructures/GirihTile.js.map +1 -1
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +17 -1
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +50 -32
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/cjs/utils/io/DndFileHandler.d.ts +63 -0
- package/src/cjs/utils/io/DndFileHandler.js +112 -0
- package/src/cjs/utils/io/DndFileHandler.js.map +1 -0
- package/src/cjs/utils/io/FileDrop.d.ts +98 -0
- package/src/cjs/utils/io/FileDrop.js +142 -0
- package/src/cjs/utils/io/FileDrop.js.map +1 -0
- package/src/esm/BezierPath.d.ts +32 -14
- package/src/esm/BezierPath.js +65 -24
- package/src/esm/BezierPath.js.map +1 -1
- package/src/esm/Bounds.d.ts +33 -1
- package/src/esm/Bounds.js +38 -1
- package/src/esm/Bounds.js.map +1 -1
- package/src/esm/Circle.d.ts +15 -13
- package/src/esm/Circle.js +16 -34
- package/src/esm/Circle.js.map +1 -1
- package/src/esm/CircleSector.d.ts +17 -16
- package/src/esm/CircleSector.js +12 -24
- package/src/esm/CircleSector.js.map +1 -1
- package/src/esm/CubicBezierCurve.d.ts +16 -15
- package/src/esm/CubicBezierCurve.js +57 -94
- package/src/esm/CubicBezierCurve.js.map +1 -1
- package/src/esm/KeyHandler.d.ts +10 -3
- package/src/esm/KeyHandler.js +28 -23
- package/src/esm/KeyHandler.js.map +1 -1
- package/src/esm/Line.d.ts +2 -15
- package/src/esm/Line.js +6 -31
- package/src/esm/Line.js.map +1 -1
- package/src/esm/MouseHandler.js +43 -53
- package/src/esm/MouseHandler.js.map +1 -1
- package/src/esm/PBImage.d.ts +15 -13
- package/src/esm/PBImage.js +11 -15
- package/src/esm/PBImage.js.map +1 -1
- package/src/esm/PBText.d.ts +13 -12
- package/src/esm/PBText.js +8 -12
- package/src/esm/PBText.js.map +1 -1
- package/src/esm/PlotBoilerplate.d.ts +3 -1
- package/src/esm/PlotBoilerplate.js +9 -2
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +23 -14
- package/src/esm/Polygon.js +22 -35
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Triangle.d.ts +15 -13
- package/src/esm/Triangle.js +23 -64
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/VEllipse.d.ts +14 -9
- package/src/esm/VEllipse.js +10 -18
- package/src/esm/VEllipse.js.map +1 -1
- package/src/esm/VEllipseSector.d.ts +15 -1
- package/src/esm/VEllipseSector.js +11 -1
- package/src/esm/VEllipseSector.js.map +1 -1
- package/src/esm/Vector.d.ts +3 -15
- package/src/esm/Vector.js +9 -49
- package/src/esm/Vector.js.map +1 -1
- package/src/esm/VertTuple.d.ts +15 -1
- package/src/esm/VertTuple.js +14 -19
- package/src/esm/VertTuple.js.map +1 -1
- package/src/esm/Vertex.d.ts +23 -13
- package/src/esm/Vertex.js +24 -22
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/VertexListeners.d.ts +12 -8
- package/src/esm/VertexListeners.js +18 -25
- package/src/esm/VertexListeners.js.map +1 -1
- package/src/esm/draw.d.ts +45 -3
- package/src/esm/draw.js +147 -6
- package/src/esm/draw.js.map +1 -1
- package/src/esm/drawgl.d.ts +41 -3
- package/src/esm/drawgl.js +44 -3
- package/src/esm/drawgl.js.map +1 -1
- package/src/esm/drawutilssvg.d.ts +69 -4
- package/src/esm/drawutilssvg.js +146 -16
- package/src/esm/drawutilssvg.js.map +1 -1
- package/src/esm/index.d.ts +0 -1
- package/src/esm/index.js +0 -1
- package/src/esm/index.js.map +1 -1
- package/src/esm/interfaces/DrawLib.d.ts +64 -27
- package/src/esm/interfaces/DrawLib.js +3 -0
- package/src/esm/interfaces/DrawLib.js.map +1 -1
- package/src/esm/interfaces/core.d.ts +2 -12
- package/src/esm/interfaces/core.js +1 -0
- package/src/esm/interfaces/core.js.map +1 -1
- package/src/esm/module.d.ts +1 -3
- package/src/esm/module.js +5 -4
- package/src/esm/module.js.map +1 -1
- package/src/esm/utils/datastructures/Color.d.ts +3 -1
- package/src/esm/utils/datastructures/Color.js +17 -6
- package/src/esm/utils/datastructures/Color.js.map +1 -1
- package/src/esm/utils/datastructures/Girih.d.ts +5 -0
- package/src/esm/utils/datastructures/Girih.js +18 -14
- package/src/esm/utils/datastructures/Girih.js.map +1 -1
- package/src/esm/utils/datastructures/GirihPenroseRhombus.js +42 -25
- package/src/esm/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
- package/src/esm/utils/datastructures/GirihTile.js +2 -13
- package/src/esm/utils/datastructures/GirihTile.js.map +1 -1
- package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +17 -1
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js +49 -32
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/esm/utils/io/DndFileHandler.d.ts +63 -0
- package/src/esm/utils/io/DndFileHandler.js +106 -0
- package/src/esm/utils/io/DndFileHandler.js.map +1 -0
- package/src/esm/utils/io/FileDrop.d.ts +98 -0
- package/src/esm/utils/io/FileDrop.js +136 -0
- package/src/esm/utils/io/FileDrop.js.map +1 -0
- package/src/ts/BezierPath.ts +78 -22
- package/src/ts/Bounds.ts +40 -1
- package/src/ts/Circle.ts +187 -200
- package/src/ts/CircleSector.ts +141 -141
- package/src/ts/CubicBezierCurve.ts +738 -810
- package/src/ts/KeyHandler.ts +221 -212
- package/src/ts/Line.ts +48 -80
- package/src/ts/MouseHandler.ts +356 -368
- package/src/ts/PBImage.ts +67 -69
- package/src/ts/PBText.ts +16 -14
- package/src/ts/PlotBoilerplate.ts +9 -2
- package/src/ts/Polygon.ts +34 -34
- package/src/ts/Triangle.ts +444 -489
- package/src/ts/VEllipse.ts +18 -17
- package/src/ts/VEllipseSector.ts +20 -1
- package/src/ts/Vector.ts +124 -160
- package/src/ts/VertTuple.ts +333 -338
- package/src/ts/Vertex.ts +35 -21
- package/src/ts/VertexListeners.ts +248 -266
- package/src/ts/draw.ts +201 -6
- package/src/ts/drawgl.ts +47 -3
- package/src/ts/drawutilssvg.ts +187 -16
- package/src/ts/index.ts +0 -1
- package/src/ts/interfaces/DrawLib.ts +72 -27
- package/src/ts/interfaces/core.ts +3 -13
- package/src/ts/module.ts +2 -4
- package/src/ts/utils/datastructures/Color.ts +17 -6
- package/src/ts/utils/datastructures/Girih.ts +204 -209
- package/src/ts/utils/datastructures/GirihPenroseRhombus.ts +170 -152
- package/src/ts/utils/datastructures/GirihTile.ts +394 -419
- package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +56 -34
- package/src/ts/utils/io/FileDrop.ts +178 -0
- package/src/ts/SVGBuilder.ts +0 -109
package/src/ts/Triangle.ts
CHANGED
|
@@ -19,14 +19,15 @@
|
|
|
19
19
|
* @modified 2020-12-28 Added the `getArea` function.
|
|
20
20
|
* @modified 2021-01-20 Added UID.
|
|
21
21
|
* @modified 2021-01-22 Always updating circumcircle when retieving it.
|
|
22
|
-
* @
|
|
22
|
+
* @modified 2022-02-02 Added the `destroy` method.
|
|
23
|
+
* @modified 2022-02-02 Cleared the `Triangle.toSVGString` function (deprecated). Use `drawutilssvg` instead.
|
|
24
|
+
* @version 2.6.0
|
|
23
25
|
*
|
|
24
26
|
* @file Triangle
|
|
25
27
|
* @fileoverview A simple triangle class: three vertices.
|
|
26
28
|
* @public
|
|
27
29
|
**/
|
|
28
30
|
|
|
29
|
-
|
|
30
31
|
import { Bounds } from "./Bounds";
|
|
31
32
|
import { Circle } from "./Circle";
|
|
32
33
|
import { Line } from "./Line";
|
|
@@ -36,11 +37,10 @@ import { Vertex } from "./Vertex";
|
|
|
36
37
|
import { geomutils } from "./geomutils";
|
|
37
38
|
import { SVGSerializable, UID } from "./interfaces";
|
|
38
39
|
|
|
39
|
-
|
|
40
40
|
/**
|
|
41
41
|
* @classdesc A triangle class for triangulations.
|
|
42
42
|
*
|
|
43
|
-
* The class was written for a Delaunay trinagulation demo so it might
|
|
43
|
+
* The class was written for a Delaunay trinagulation demo so it might
|
|
44
44
|
* contain some strange and unexpected functions.
|
|
45
45
|
*
|
|
46
46
|
* @requires Bounds
|
|
@@ -55,495 +55,450 @@ import { SVGSerializable, UID } from "./interfaces";
|
|
|
55
55
|
*
|
|
56
56
|
*/
|
|
57
57
|
export class Triangle implements SVGSerializable {
|
|
58
|
+
/**
|
|
59
|
+
* Required to generate proper CSS classes and other class related IDs.
|
|
60
|
+
**/
|
|
61
|
+
readonly className: string = "Triangle";
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The UID of this drawable object.
|
|
65
|
+
*
|
|
66
|
+
* @member {UID}
|
|
67
|
+
* @memberof Triangle
|
|
68
|
+
* @instance
|
|
69
|
+
* @readonly
|
|
70
|
+
*/
|
|
71
|
+
readonly uid: UID;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* An epsilon for comparison.
|
|
75
|
+
* This should be the same epsilon as in Vertex.
|
|
76
|
+
*
|
|
77
|
+
* @private
|
|
78
|
+
**/
|
|
79
|
+
static readonly EPSILON: number = 1.0e-6;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @member {Vertex}
|
|
83
|
+
* @memberof Triangle
|
|
84
|
+
* @instance
|
|
85
|
+
*/
|
|
86
|
+
a: Vertex;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @member {Vertex}
|
|
90
|
+
* @memberof Triangle
|
|
91
|
+
* @instance
|
|
92
|
+
*/
|
|
93
|
+
b: Vertex;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @member {Vertex}
|
|
97
|
+
* @memberof Triangle
|
|
98
|
+
* @instance
|
|
99
|
+
*/
|
|
100
|
+
c: Vertex;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @member {Vertex}
|
|
104
|
+
* @memberof Triangle
|
|
105
|
+
* @instance
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
private center: Vertex;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @member {number}
|
|
112
|
+
* @memberof Triangle
|
|
113
|
+
* @instance
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
private radius_squared: number;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @member {number}
|
|
120
|
+
* @memberof Triangle
|
|
121
|
+
* @instance
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
private radius: number;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @member isDestroyed
|
|
128
|
+
* @memberof Triangle
|
|
129
|
+
* @type {boolean}
|
|
130
|
+
* @instance
|
|
131
|
+
*/
|
|
132
|
+
isDestroyed: boolean;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The constructor.
|
|
136
|
+
*
|
|
137
|
+
* @constructor
|
|
138
|
+
* @name Triangle
|
|
139
|
+
* @param {Vertex} a - The first vertex of the triangle.
|
|
140
|
+
* @param {Vertex} b - The second vertex of the triangle.
|
|
141
|
+
* @param {Vertex} c - The third vertex of the triangle.
|
|
142
|
+
**/
|
|
143
|
+
constructor(a: Vertex, b: Vertex, c: Vertex) {
|
|
144
|
+
this.uid = UIDGenerator.next();
|
|
145
|
+
this.a = a;
|
|
146
|
+
this.b = b;
|
|
147
|
+
this.c = c;
|
|
148
|
+
|
|
149
|
+
this.calcCircumcircle();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Create a new triangle from the given array of vertices.
|
|
154
|
+
*
|
|
155
|
+
* The array must have at least three vertices, otherwise an error will be raised.
|
|
156
|
+
* This function will not create copies of the vertices.
|
|
157
|
+
*
|
|
158
|
+
* @method fromArray
|
|
159
|
+
* @static
|
|
160
|
+
* @param {Array<Vertex>} arr - The required array with at least three vertices.
|
|
161
|
+
* @memberof Vertex
|
|
162
|
+
* @return {Triangle}
|
|
163
|
+
**/
|
|
164
|
+
static fromArray(arr: Array<Vertex>): Triangle {
|
|
165
|
+
if (arr.length < 3) throw `Cannot create triangle from array with less than three vertices (${arr.length})`;
|
|
166
|
+
return new Triangle(arr[0], arr[1], arr[2]);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get the area of this triangle. The returned area is never negative.
|
|
171
|
+
*
|
|
172
|
+
* If you are interested in the signed area, please consider using the
|
|
173
|
+
* `Triangle.utils.signedArea` helper function. This method just returns
|
|
174
|
+
* the absolute value of the signed area.
|
|
175
|
+
*
|
|
176
|
+
* @method getArea
|
|
177
|
+
* @instance
|
|
178
|
+
* @memberof Triangle
|
|
179
|
+
* @return {number} The non-negative area of this triangle.
|
|
180
|
+
*/
|
|
181
|
+
getArea(): number {
|
|
182
|
+
return Math.abs(Triangle.utils.signedArea(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get the centroid of this triangle.
|
|
187
|
+
*
|
|
188
|
+
* The centroid is the average midpoint for each side.
|
|
189
|
+
*
|
|
190
|
+
* @method getCentroid
|
|
191
|
+
* @return {Vertex} The centroid
|
|
192
|
+
* @instance
|
|
193
|
+
* @memberof Triangle
|
|
194
|
+
**/
|
|
195
|
+
getCentroid(): Vertex {
|
|
196
|
+
return new Vertex((this.a.x + this.b.x + this.c.x) / 3, (this.a.y + this.b.y + this.c.y) / 3);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Scale the triangle towards its centroid.
|
|
201
|
+
*
|
|
202
|
+
* @method scaleToCentroid
|
|
203
|
+
* @param {number} - The scale factor to use. That can be any scalar.
|
|
204
|
+
* @return {Triangle} this (for chaining)
|
|
205
|
+
* @instance
|
|
206
|
+
* @memberof Triangle
|
|
207
|
+
*/
|
|
208
|
+
scaleToCentroid(factor: number): Triangle {
|
|
209
|
+
let centroid: Vertex = this.getCentroid();
|
|
210
|
+
this.a.scale(factor, centroid);
|
|
211
|
+
this.b.scale(factor, centroid);
|
|
212
|
+
this.c.scale(factor, centroid);
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Get the circumcircle of this triangle.
|
|
218
|
+
*
|
|
219
|
+
* The circumcircle is that unique circle on which all three
|
|
220
|
+
* vertices of this triangle are located on.
|
|
221
|
+
*
|
|
222
|
+
* Please note that for performance reasons any changes to vertices will not reflect in changes
|
|
223
|
+
* of the circumcircle (center or radius). Please call the calcCirumcircle() function
|
|
224
|
+
* after triangle vertex changes.
|
|
225
|
+
*
|
|
226
|
+
* @method getCircumcircle
|
|
227
|
+
* @return {Object} - { center:Vertex, radius:float }
|
|
228
|
+
* @instance
|
|
229
|
+
* @memberof Triangle
|
|
230
|
+
*/
|
|
231
|
+
getCircumcircle(): Circle {
|
|
232
|
+
// if( !this.center || !this.radius )
|
|
233
|
+
this.calcCircumcircle();
|
|
234
|
+
return new Circle(this.center.clone(), this.radius);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Check if this triangle and the passed triangle share an
|
|
239
|
+
* adjacent edge.
|
|
240
|
+
*
|
|
241
|
+
* For edge-checking Vertex.equals is used which uses an
|
|
242
|
+
* an epsilon for comparison.
|
|
243
|
+
*
|
|
244
|
+
* @method isAdjacent
|
|
245
|
+
* @param {Triangle} tri - The second triangle to check adjacency with.
|
|
246
|
+
* @return {boolean} - True if this and the passed triangle have at least one common edge.
|
|
247
|
+
* @instance
|
|
248
|
+
* @memberof Triangle
|
|
249
|
+
*/
|
|
250
|
+
isAdjacent(tri: Triangle): boolean {
|
|
251
|
+
var a: boolean = this.a.equals(tri.a) || this.a.equals(tri.b) || this.a.equals(tri.c);
|
|
252
|
+
var b: boolean = this.b.equals(tri.a) || this.b.equals(tri.b) || this.b.equals(tri.c);
|
|
253
|
+
var c: boolean = this.c.equals(tri.a) || this.c.equals(tri.b) || this.c.equals(tri.c);
|
|
254
|
+
return (a && b) || (a && c) || (b && c);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Get that vertex of this triangle (a,b,c) that is not vert1 nor vert2 of
|
|
259
|
+
* the passed two.
|
|
260
|
+
*
|
|
261
|
+
* @method getThirdVertex
|
|
262
|
+
* @param {Vertex} vert1 - The first vertex.
|
|
263
|
+
* @param {Vertex} vert2 - The second vertex.
|
|
264
|
+
* @return {Vertex} - The third vertex of this triangle that makes up the whole triangle with vert1 and vert2.
|
|
265
|
+
* @instance
|
|
266
|
+
* @memberof Triangle
|
|
267
|
+
*/
|
|
268
|
+
getThirdVertex(vert1: Vertex, vert2: Vertex): Vertex {
|
|
269
|
+
if ((this.a.equals(vert1) && this.b.equals(vert2)) || (this.a.equals(vert2) && this.b.equals(vert1))) return this.c;
|
|
270
|
+
if ((this.b.equals(vert1) && this.c.equals(vert2)) || (this.b.equals(vert2) && this.c.equals(vert1))) return this.a;
|
|
271
|
+
//if( this.c.equals(vert1) && this.a.equals(vert2) || this.c.equals(vert2) && this.a.equals(vert1) )
|
|
272
|
+
return this.b;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Re-compute the circumcircle of this triangle (if the vertices
|
|
277
|
+
* have changed).
|
|
278
|
+
*
|
|
279
|
+
* The circumcenter and radius are stored in this.center and
|
|
280
|
+
* this.radius. There is a third result: radius_squared (for internal computations).
|
|
281
|
+
*
|
|
282
|
+
* @method calcCircumcircle
|
|
283
|
+
* @return void
|
|
284
|
+
* @instance
|
|
285
|
+
* @memberof Triangle
|
|
286
|
+
*/
|
|
287
|
+
calcCircumcircle() {
|
|
288
|
+
// From
|
|
289
|
+
// http://www.exaflop.org/docs/cgafaq/cga1.html
|
|
290
|
+
|
|
291
|
+
const A: number = this.b.x - this.a.x;
|
|
292
|
+
const B: number = this.b.y - this.a.y;
|
|
293
|
+
const C: number = this.c.x - this.a.x;
|
|
294
|
+
const D: number = this.c.y - this.a.y;
|
|
295
|
+
|
|
296
|
+
const E: number = A * (this.a.x + this.b.x) + B * (this.a.y + this.b.y);
|
|
297
|
+
const F: number = C * (this.a.x + this.c.x) + D * (this.a.y + this.c.y);
|
|
298
|
+
|
|
299
|
+
const G: number = 2.0 * (A * (this.c.y - this.b.y) - B * (this.c.x - this.b.x));
|
|
300
|
+
|
|
301
|
+
let dx: number, dy: number;
|
|
302
|
+
|
|
303
|
+
if (Math.abs(G) < Triangle.EPSILON) {
|
|
304
|
+
// Collinear - find extremes and use the midpoint
|
|
305
|
+
const bounds: Bounds = this.bounds();
|
|
306
|
+
this.center = new Vertex((bounds.min.x + bounds.max.x) / 2, (bounds.min.y + bounds.max.y) / 2);
|
|
307
|
+
dx = this.center.x - bounds.min.x;
|
|
308
|
+
dy = this.center.y - bounds.min.y;
|
|
309
|
+
} else {
|
|
310
|
+
const cx: number = (D * E - B * F) / G;
|
|
311
|
+
const cy: number = (A * F - C * E) / G;
|
|
312
|
+
this.center = new Vertex(cx, cy);
|
|
313
|
+
dx = this.center.x - this.a.x;
|
|
314
|
+
dy = this.center.y - this.a.y;
|
|
315
|
+
}
|
|
58
316
|
|
|
317
|
+
this.radius_squared = dx * dx + dy * dy;
|
|
318
|
+
this.radius = Math.sqrt(this.radius_squared);
|
|
319
|
+
} // END calcCircumcircle
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Check if the passed vertex is inside this triangle's
|
|
323
|
+
* circumcircle.
|
|
324
|
+
*
|
|
325
|
+
* @method inCircumcircle
|
|
326
|
+
* @param {Vertex} v - The vertex to check.
|
|
327
|
+
* @return {boolean}
|
|
328
|
+
* @instance
|
|
329
|
+
* @memberof Triangle
|
|
330
|
+
*/
|
|
331
|
+
inCircumcircle(v: Vertex): boolean {
|
|
332
|
+
const dx: number = this.center.x - v.x;
|
|
333
|
+
const dy: number = this.center.y - v.y;
|
|
334
|
+
const dist_squared: number = dx * dx + dy * dy;
|
|
335
|
+
return dist_squared <= this.radius_squared;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Get the rectangular bounds for this triangle.
|
|
340
|
+
*
|
|
341
|
+
* @method bounds
|
|
342
|
+
* @return {Bounds} - The min/max bounds of this triangle.
|
|
343
|
+
* @instance
|
|
344
|
+
* @memberof Triangle
|
|
345
|
+
*/
|
|
346
|
+
bounds(): Bounds {
|
|
347
|
+
return new Bounds(
|
|
348
|
+
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)),
|
|
349
|
+
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))
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Convert this triangle to a polygon instance.
|
|
355
|
+
*
|
|
356
|
+
* Plase note that this conversion does not perform a deep clone.
|
|
357
|
+
*
|
|
358
|
+
* @method toPolygon
|
|
359
|
+
* @return {Polygon} A new polygon representing this triangle.
|
|
360
|
+
* @instance
|
|
361
|
+
* @memberof Triangle
|
|
362
|
+
**/
|
|
363
|
+
toPolygon(): Polygon {
|
|
364
|
+
return new Polygon([this.a, this.b, this.c]);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Get the determinant of this triangle.
|
|
369
|
+
*
|
|
370
|
+
* @method determinant
|
|
371
|
+
* @return {number} - The determinant (float).
|
|
372
|
+
* @instance
|
|
373
|
+
* @memberof Triangle
|
|
374
|
+
*/
|
|
375
|
+
determinant(): number {
|
|
376
|
+
// (b.y - a.y)*(c.x - b.x) - (c.y - b.y)*(b.x - a.x);
|
|
377
|
+
return (this.b.y - this.a.y) * (this.c.x - this.b.x) - (this.c.y - this.b.y) * (this.b.x - this.a.x);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Checks if the passed vertex (p) is inside this triangle.
|
|
382
|
+
*
|
|
383
|
+
* Note: matrix determinants rock.
|
|
384
|
+
*
|
|
385
|
+
* @method containsPoint
|
|
386
|
+
* @param {Vertex} p - The vertex to check.
|
|
387
|
+
* @return {boolean}
|
|
388
|
+
* @instance
|
|
389
|
+
* @memberof Triangle
|
|
390
|
+
*/
|
|
391
|
+
containsPoint(p: Vertex): boolean {
|
|
392
|
+
return Triangle.utils.pointIsInTriangle(p.x, p.y, this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Get that inner triangle which defines the maximal incircle.
|
|
397
|
+
*
|
|
398
|
+
* @return {Triangle} The triangle of those points in this triangle that define the incircle.
|
|
399
|
+
*/
|
|
400
|
+
getIncircularTriangle(): Triangle {
|
|
401
|
+
const lineA = new Line(this.a, this.b);
|
|
402
|
+
const lineB = new Line(this.b, this.c);
|
|
403
|
+
const lineC = new Line(this.c, this.a);
|
|
404
|
+
|
|
405
|
+
const bisector1 = geomutils.nsectAngle(this.b, this.a, this.c, 2)[0]; // bisector of first angle (in b)
|
|
406
|
+
const bisector2 = geomutils.nsectAngle(this.c, this.b, this.a, 2)[0]; // bisector of second angle (in c)
|
|
407
|
+
const intersection = bisector1.intersection(bisector2);
|
|
408
|
+
|
|
409
|
+
// Find the closest points on one of the polygon lines (all have same distance by construction)
|
|
410
|
+
const circleIntersA = lineA.getClosestPoint(intersection);
|
|
411
|
+
const circleIntersB = lineB.getClosestPoint(intersection);
|
|
412
|
+
const circleIntersC = lineC.getClosestPoint(intersection);
|
|
413
|
+
|
|
414
|
+
return new Triangle(circleIntersA, circleIntersB, circleIntersC);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Get the incircle of this triangle. That is the circle that touches each side
|
|
419
|
+
* of this triangle in exactly one point.
|
|
420
|
+
*
|
|
421
|
+
* Note this just calls getIncircularTriangle().getCircumcircle()
|
|
422
|
+
*
|
|
423
|
+
* @return {Circle} The incircle of this triangle.
|
|
424
|
+
*/
|
|
425
|
+
getIncircle(): Circle {
|
|
426
|
+
return this.getIncircularTriangle().getCircumcircle();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Get the incenter of this triangle (which is the center of the circumcircle).
|
|
431
|
+
*
|
|
432
|
+
* Note: due to performance reasonst the incenter is buffered inside the triangle because
|
|
433
|
+
* computing it is relatively expensive. If a, b or c have changed you should call the
|
|
434
|
+
* calcCircumcircle() function first, otherwise you might get wrong results.
|
|
435
|
+
* @return Vertex The incenter of this triangle.
|
|
436
|
+
**/
|
|
437
|
+
getIncenter(): Vertex {
|
|
438
|
+
if (!this.center || !this.radius) this.calcCircumcircle();
|
|
439
|
+
return this.center.clone();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Converts this triangle into a human-readable string.
|
|
444
|
+
*
|
|
445
|
+
* @method toString
|
|
446
|
+
* @return {string}
|
|
447
|
+
* @instance
|
|
448
|
+
* @memberof Triangle
|
|
449
|
+
*/
|
|
450
|
+
toString(): string {
|
|
451
|
+
return "{ a : " + this.a.toString() + ", b : " + this.b.toString() + ", c : " + this.c.toString() + "}";
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* This function should invalidate any installed listeners and invalidate this object.
|
|
456
|
+
* After calling this function the object might not hold valid data any more and
|
|
457
|
+
* should not be used.
|
|
458
|
+
*/
|
|
459
|
+
destroy() {
|
|
460
|
+
this.a.destroy();
|
|
461
|
+
this.b.destroy();
|
|
462
|
+
this.c.destroy();
|
|
463
|
+
this.isDestroyed = true;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
private static utils = {
|
|
467
|
+
// Used in the bounds() function.
|
|
468
|
+
max3(a: number, b: number, c: number): number {
|
|
469
|
+
return a >= b && a >= c ? a : b >= a && b >= c ? b : c;
|
|
470
|
+
},
|
|
471
|
+
min3(a: number, b: number, c: number): number {
|
|
472
|
+
return a <= b && a <= c ? a : b <= a && b <= c ? b : c;
|
|
473
|
+
},
|
|
474
|
+
signedArea(p0x: number, p0y: number, p1x: number, p1y: number, p2x: number, p2y: number): number {
|
|
475
|
+
return 0.5 * (-p1y * p2x + p0y * (-p1x + p2x) + p0x * (p1y - p2y) + p1x * p2y);
|
|
476
|
+
},
|
|
59
477
|
/**
|
|
60
|
-
*
|
|
61
|
-
**/
|
|
62
|
-
readonly className : string = "Triangle";
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* The UID of this drawable object.
|
|
67
|
-
*
|
|
68
|
-
* @member {UID}
|
|
69
|
-
* @memberof Triangle
|
|
70
|
-
* @instance
|
|
71
|
-
* @readonly
|
|
72
|
-
*/
|
|
73
|
-
readonly uid : UID;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* An epsilon for comparison.
|
|
78
|
-
* This should be the same epsilon as in Vertex.
|
|
478
|
+
* Used by the containsPoint() function.
|
|
79
479
|
*
|
|
80
480
|
* @private
|
|
81
481
|
**/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
*/
|
|
103
|
-
c:Vertex;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @member {Vertex}
|
|
107
|
-
* @memberof Triangle
|
|
108
|
-
* @instance
|
|
109
|
-
* @private
|
|
110
|
-
*/
|
|
111
|
-
private center:Vertex;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* @member {number}
|
|
115
|
-
* @memberof Triangle
|
|
116
|
-
* @instance
|
|
117
|
-
* @private
|
|
118
|
-
*/
|
|
119
|
-
private radius_squared:number;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* @member {number}
|
|
123
|
-
* @memberof Triangle
|
|
124
|
-
* @instance
|
|
125
|
-
* @private
|
|
126
|
-
*/
|
|
127
|
-
private radius:number;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* The constructor.
|
|
132
|
-
*
|
|
133
|
-
* @constructor
|
|
134
|
-
* @name Triangle
|
|
135
|
-
* @param {Vertex} a - The first vertex of the triangle.
|
|
136
|
-
* @param {Vertex} b - The second vertex of the triangle.
|
|
137
|
-
* @param {Vertex} c - The third vertex of the triangle.
|
|
138
|
-
**/
|
|
139
|
-
constructor( a:Vertex, b:Vertex, c:Vertex ) {
|
|
140
|
-
this.uid = UIDGenerator.next();
|
|
141
|
-
this.a = a;
|
|
142
|
-
this.b = b;
|
|
143
|
-
this.c = c;
|
|
144
|
-
|
|
145
|
-
this.calcCircumcircle();
|
|
146
|
-
|
|
482
|
+
pointIsInTriangle(
|
|
483
|
+
px: number,
|
|
484
|
+
py: number,
|
|
485
|
+
p0x: number,
|
|
486
|
+
p0y: number,
|
|
487
|
+
p1x: number,
|
|
488
|
+
p1y: number,
|
|
489
|
+
p2x: number,
|
|
490
|
+
p2y: number
|
|
491
|
+
): boolean {
|
|
492
|
+
//
|
|
493
|
+
// Point-in-Triangle test found at
|
|
494
|
+
// http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-2d-triangle
|
|
495
|
+
// var area : number = 1/2*(-p1y*p2x + p0y*(-p1x + p2x) + p0x*(p1y - p2y) + p1x*p2y);
|
|
496
|
+
var area: number = Triangle.utils.signedArea(p0x, p0y, p1x, p1y, p2x, p2y);
|
|
497
|
+
|
|
498
|
+
var s: number = (1 / (2 * area)) * (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py);
|
|
499
|
+
var t: number = (1 / (2 * area)) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);
|
|
500
|
+
|
|
501
|
+
return s > 0 && t > 0 && 1 - s - t > 0;
|
|
147
502
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Create a new triangle from the given array of vertices.
|
|
152
|
-
*
|
|
153
|
-
* The array must have at least three vertices, otherwise an error will be raised.
|
|
154
|
-
* This function will not create copies of the vertices.
|
|
155
|
-
*
|
|
156
|
-
* @method fromArray
|
|
157
|
-
* @static
|
|
158
|
-
* @param {Array<Vertex>} arr - The required array with at least three vertices.
|
|
159
|
-
* @memberof Vertex
|
|
160
|
-
* @return {Triangle}
|
|
161
|
-
**/
|
|
162
|
-
static fromArray( arr:Array<Vertex> ) : Triangle {
|
|
163
|
-
if( arr.length < 3 )
|
|
164
|
-
throw `Cannot create triangle from array with less than three vertices (${arr.length})`;
|
|
165
|
-
return new Triangle( arr[0], arr[1], arr[2] );
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Get the area of this triangle. The returned area is never negative.
|
|
171
|
-
*
|
|
172
|
-
* If you are interested in the signed area, please consider using the
|
|
173
|
-
* `Triangle.utils.signedArea` helper function. This method just returns
|
|
174
|
-
* the absolute value of the signed area.
|
|
175
|
-
*
|
|
176
|
-
* @method getArea
|
|
177
|
-
* @instance
|
|
178
|
-
* @memberof Triangle
|
|
179
|
-
* @return {number} The non-negative area of this triangle.
|
|
180
|
-
*/
|
|
181
|
-
getArea() : number {
|
|
182
|
-
return Math.abs(
|
|
183
|
-
Triangle.utils.signedArea(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y)
|
|
184
|
-
);
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Get the centroid of this triangle.
|
|
190
|
-
*
|
|
191
|
-
* The centroid is the average midpoint for each side.
|
|
192
|
-
*
|
|
193
|
-
* @method getCentroid
|
|
194
|
-
* @return {Vertex} The centroid
|
|
195
|
-
* @instance
|
|
196
|
-
* @memberof Triangle
|
|
197
|
-
**/
|
|
198
|
-
getCentroid() : Vertex {
|
|
199
|
-
return new Vertex( (this.a.x + this.b.x + this.c.x)/3,
|
|
200
|
-
(this.a.y + this.b.y + this.c.y)/3
|
|
201
|
-
);
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Scale the triangle towards its centroid.
|
|
208
|
-
*
|
|
209
|
-
* @method scaleToCentroid
|
|
210
|
-
* @param {number} - The scale factor to use. That can be any scalar.
|
|
211
|
-
* @return {Triangle} this (for chaining)
|
|
212
|
-
* @instance
|
|
213
|
-
* @memberof Triangle
|
|
214
|
-
*/
|
|
215
|
-
scaleToCentroid ( factor:number ) : Triangle {
|
|
216
|
-
let centroid : Vertex = this.getCentroid();
|
|
217
|
-
this.a.scale( factor, centroid );
|
|
218
|
-
this.b.scale( factor, centroid );
|
|
219
|
-
this.c.scale( factor, centroid );
|
|
220
|
-
return this;
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Get the circumcircle of this triangle.
|
|
227
|
-
*
|
|
228
|
-
* The circumcircle is that unique circle on which all three
|
|
229
|
-
* vertices of this triangle are located on.
|
|
230
|
-
*
|
|
231
|
-
* Please note that for performance reasons any changes to vertices will not reflect in changes
|
|
232
|
-
* of the circumcircle (center or radius). Please call the calcCirumcircle() function
|
|
233
|
-
* after triangle vertex changes.
|
|
234
|
-
*
|
|
235
|
-
* @method getCircumcircle
|
|
236
|
-
* @return {Object} - { center:Vertex, radius:float }
|
|
237
|
-
* @instance
|
|
238
|
-
* @memberof Triangle
|
|
239
|
-
*/
|
|
240
|
-
getCircumcircle() : Circle {
|
|
241
|
-
// if( !this.center || !this.radius )
|
|
242
|
-
this.calcCircumcircle();
|
|
243
|
-
return new Circle( this.center.clone(), this.radius );
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Check if this triangle and the passed triangle share an
|
|
250
|
-
* adjacent edge.
|
|
251
|
-
*
|
|
252
|
-
* For edge-checking Vertex.equals is used which uses an
|
|
253
|
-
* an epsilon for comparison.
|
|
254
|
-
*
|
|
255
|
-
* @method isAdjacent
|
|
256
|
-
* @param {Triangle} tri - The second triangle to check adjacency with.
|
|
257
|
-
* @return {boolean} - True if this and the passed triangle have at least one common edge.
|
|
258
|
-
* @instance
|
|
259
|
-
* @memberof Triangle
|
|
260
|
-
*/
|
|
261
|
-
isAdjacent( tri:Triangle ) : boolean {
|
|
262
|
-
var a : boolean = this.a.equals(tri.a) || this.a.equals(tri.b) || this.a.equals(tri.c);
|
|
263
|
-
var b : boolean = this.b.equals(tri.a) || this.b.equals(tri.b) || this.b.equals(tri.c);
|
|
264
|
-
var c : boolean = this.c.equals(tri.a) || this.c.equals(tri.b) || this.c.equals(tri.c);
|
|
265
|
-
return (a&&b) || (a&&c) || (b&&c);
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Get that vertex of this triangle (a,b,c) that is not vert1 nor vert2 of
|
|
272
|
-
* the passed two.
|
|
273
|
-
*
|
|
274
|
-
* @method getThirdVertex
|
|
275
|
-
* @param {Vertex} vert1 - The first vertex.
|
|
276
|
-
* @param {Vertex} vert2 - The second vertex.
|
|
277
|
-
* @return {Vertex} - The third vertex of this triangle that makes up the whole triangle with vert1 and vert2.
|
|
278
|
-
* @instance
|
|
279
|
-
* @memberof Triangle
|
|
280
|
-
*/
|
|
281
|
-
getThirdVertex( vert1:Vertex, vert2:Vertex ) : Vertex {
|
|
282
|
-
if( this.a.equals(vert1) && this.b.equals(vert2) || this.a.equals(vert2) && this.b.equals(vert1) ) return this.c;
|
|
283
|
-
if( this.b.equals(vert1) && this.c.equals(vert2) || this.b.equals(vert2) && this.c.equals(vert1) ) return this.a;
|
|
284
|
-
//if( this.c.equals(vert1) && this.a.equals(vert2) || this.c.equals(vert2) && this.a.equals(vert1) )
|
|
285
|
-
return this.b;
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Re-compute the circumcircle of this triangle (if the vertices
|
|
291
|
-
* have changed).
|
|
292
|
-
*
|
|
293
|
-
* The circumcenter and radius are stored in this.center and
|
|
294
|
-
* this.radius. There is a third result: radius_squared (for internal computations).
|
|
295
|
-
*
|
|
296
|
-
* @method calcCircumcircle
|
|
297
|
-
* @return void
|
|
298
|
-
* @instance
|
|
299
|
-
* @memberof Triangle
|
|
300
|
-
*/
|
|
301
|
-
calcCircumcircle() {
|
|
302
|
-
// From
|
|
303
|
-
// http://www.exaflop.org/docs/cgafaq/cga1.html
|
|
304
|
-
|
|
305
|
-
const A : number = this.b.x - this.a.x;
|
|
306
|
-
const B : number = this.b.y - this.a.y;
|
|
307
|
-
const C : number = this.c.x - this.a.x;
|
|
308
|
-
const D : number = this.c.y - this.a.y;
|
|
309
|
-
|
|
310
|
-
const E : number = A*(this.a.x + this.b.x) + B*(this.a.y + this.b.y);
|
|
311
|
-
const F : number = C*(this.a.x + this.c.x) + D*(this.a.y + this.c.y);
|
|
312
|
-
|
|
313
|
-
const G : number = 2.0*(A*(this.c.y - this.b.y)-B*(this.c.x - this.b.x));
|
|
314
|
-
|
|
315
|
-
let dx : number, dy : number;
|
|
316
|
-
|
|
317
|
-
if( Math.abs(G) < Triangle.EPSILON ) {
|
|
318
|
-
// Collinear - find extremes and use the midpoint
|
|
319
|
-
const bounds : Bounds = this.bounds();
|
|
320
|
-
this.center = new Vertex( ( bounds.min.x + bounds.max.x ) / 2, ( bounds.min.y + bounds.max.y ) / 2 );
|
|
321
|
-
dx = this.center.x - bounds.min.x;
|
|
322
|
-
dy = this.center.y - bounds.min.y;
|
|
323
|
-
} else {
|
|
324
|
-
const cx : number = (D*E - B*F) / G;
|
|
325
|
-
const cy : number = (A*F - C*E) / G;
|
|
326
|
-
this.center = new Vertex( cx, cy );
|
|
327
|
-
dx = this.center.x - this.a.x;
|
|
328
|
-
dy = this.center.y - this.a.y;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
this.radius_squared = dx * dx + dy * dy;
|
|
332
|
-
this.radius = Math.sqrt( this.radius_squared );
|
|
333
|
-
}; // END calcCircumcircle
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Check if the passed vertex is inside this triangle's
|
|
339
|
-
* circumcircle.
|
|
340
|
-
*
|
|
341
|
-
* @method inCircumcircle
|
|
342
|
-
* @param {Vertex} v - The vertex to check.
|
|
343
|
-
* @return {boolean}
|
|
344
|
-
* @instance
|
|
345
|
-
* @memberof Triangle
|
|
346
|
-
*/
|
|
347
|
-
inCircumcircle( v:Vertex ) : boolean {
|
|
348
|
-
const dx : number = this.center.x - v.x;
|
|
349
|
-
const dy : number = this.center.y - v.y;
|
|
350
|
-
const dist_squared : number = dx * dx + dy * dy;
|
|
351
|
-
return ( dist_squared <= this.radius_squared );
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Get the rectangular bounds for this triangle.
|
|
358
|
-
*
|
|
359
|
-
* @method bounds
|
|
360
|
-
* @return {Bounds} - The min/max bounds of this triangle.
|
|
361
|
-
* @instance
|
|
362
|
-
* @memberof Triangle
|
|
363
|
-
*/
|
|
364
|
-
bounds() : Bounds {
|
|
365
|
-
return new Bounds( new Vertex( Triangle.utils.min3( this.a.x, this.b.x, this.c.x ),
|
|
366
|
-
Triangle.utils.min3( this.a.y, this.b.y, this.c.y ) ),
|
|
367
|
-
new Vertex( Triangle.utils.max3( this.a.x, this.b.x, this.c.x ),
|
|
368
|
-
Triangle.utils.max3( this.a.y, this.b.y, this.c.y ) )
|
|
369
|
-
);
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Convert this triangle to a polygon instance.
|
|
375
|
-
*
|
|
376
|
-
* Plase note that this conversion does not perform a deep clone.
|
|
377
|
-
*
|
|
378
|
-
* @method toPolygon
|
|
379
|
-
* @return {Polygon} A new polygon representing this triangle.
|
|
380
|
-
* @instance
|
|
381
|
-
* @memberof Triangle
|
|
382
|
-
**/
|
|
383
|
-
toPolygon() : Polygon {
|
|
384
|
-
return new Polygon( [ this.a, this.b, this.c ] );
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Get the determinant of this triangle.
|
|
390
|
-
*
|
|
391
|
-
* @method determinant
|
|
392
|
-
* @return {number} - The determinant (float).
|
|
393
|
-
* @instance
|
|
394
|
-
* @memberof Triangle
|
|
395
|
-
*/
|
|
396
|
-
determinant() : number {
|
|
397
|
-
// (b.y - a.y)*(c.x - b.x) - (c.y - b.y)*(b.x - a.x);
|
|
398
|
-
return (this.b.y - this.a.y)*(this.c.x - this.b.x) - (this.c.y - this.b.y)*(this.b.x - this.a.x);
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* Checks if the passed vertex (p) is inside this triangle.
|
|
404
|
-
*
|
|
405
|
-
* Note: matrix determinants rock.
|
|
406
|
-
*
|
|
407
|
-
* @method containsPoint
|
|
408
|
-
* @param {Vertex} p - The vertex to check.
|
|
409
|
-
* @return {boolean}
|
|
410
|
-
* @instance
|
|
411
|
-
* @memberof Triangle
|
|
412
|
-
*/
|
|
413
|
-
containsPoint( p:Vertex ) : boolean {
|
|
414
|
-
return Triangle.utils.pointIsInTriangle( p.x, p.y, this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y );
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Get that inner triangle which defines the maximal incircle.
|
|
420
|
-
*
|
|
421
|
-
* @return {Triangle} The triangle of those points in this triangle that define the incircle.
|
|
422
|
-
*/
|
|
423
|
-
getIncircularTriangle() : Triangle {
|
|
424
|
-
const lineA = new Line( this.a, this.b);
|
|
425
|
-
const lineB = new Line( this.b, this.c);
|
|
426
|
-
const lineC = new Line( this.c, this.a);
|
|
427
|
-
|
|
428
|
-
const bisector1 = geomutils.nsectAngle( this.b, this.a, this.c, 2 )[0]; // bisector of first angle (in b)
|
|
429
|
-
const bisector2 = geomutils.nsectAngle( this.c, this.b, this.a, 2 )[0]; // bisector of second angle (in c)
|
|
430
|
-
const intersection = bisector1.intersection( bisector2 );
|
|
431
|
-
|
|
432
|
-
// Find the closest points on one of the polygon lines (all have same distance by construction)
|
|
433
|
-
const circleIntersA = lineA.getClosestPoint( intersection );
|
|
434
|
-
const circleIntersB = lineB.getClosestPoint( intersection );
|
|
435
|
-
const circleIntersC = lineC.getClosestPoint( intersection );
|
|
436
|
-
|
|
437
|
-
return new Triangle(circleIntersA, circleIntersB, circleIntersC);
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Get the incircle of this triangle. That is the circle that touches each side
|
|
443
|
-
* of this triangle in exactly one point.
|
|
444
|
-
*
|
|
445
|
-
* Note this just calls getIncircularTriangle().getCircumcircle()
|
|
446
|
-
*
|
|
447
|
-
* @return {Circle} The incircle of this triangle.
|
|
448
|
-
*/
|
|
449
|
-
getIncircle() : Circle {
|
|
450
|
-
return this.getIncircularTriangle().getCircumcircle();
|
|
451
|
-
};
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* Get the incenter of this triangle (which is the center of the circumcircle).
|
|
456
|
-
*
|
|
457
|
-
* Note: due to performance reasonst the incenter is buffered inside the triangle because
|
|
458
|
-
* computing it is relatively expensive. If a, b or c have changed you should call the
|
|
459
|
-
* calcCircumcircle() function first, otherwise you might get wrong results.
|
|
460
|
-
* @return Vertex The incenter of this triangle.
|
|
461
|
-
**/
|
|
462
|
-
getIncenter() : Vertex {
|
|
463
|
-
if( !this.center || !this.radius )
|
|
464
|
-
this.calcCircumcircle();
|
|
465
|
-
return this.center.clone();
|
|
466
|
-
};
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Converts this triangle into a human-readable string.
|
|
471
|
-
*
|
|
472
|
-
* @method toString
|
|
473
|
-
* @return {string}
|
|
474
|
-
* @instance
|
|
475
|
-
* @memberof Triangle
|
|
476
|
-
*/
|
|
477
|
-
toString() : string {
|
|
478
|
-
return '{ a : ' + this.a.toString () + ', b : ' + this.b.toString() + ', c : ' + this.c.toString() + '}';
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Create an SVG representation of this triangle.
|
|
484
|
-
*
|
|
485
|
-
* @deprecated DEPRECATION Please use the drawutilssvg library and an XMLSerializer instead.
|
|
486
|
-
* @method toSVGString
|
|
487
|
-
* @param {object=} options - An optional set of options, like 'className'.
|
|
488
|
-
* @return {string} The SVG string.
|
|
489
|
-
* @instance
|
|
490
|
-
* @memberof Triangle
|
|
491
|
-
**/
|
|
492
|
-
toSVGString( options:{className?:string} ) : string {
|
|
493
|
-
options = options || {};
|
|
494
|
-
var buffer = [];
|
|
495
|
-
buffer.push( '<path' );
|
|
496
|
-
if( options.className )
|
|
497
|
-
buffer.push( ' class="' + options.className + '"' );
|
|
498
|
-
buffer.push( ' d="' );
|
|
499
|
-
var vertices = [ this.a, this.b, this.c ];
|
|
500
|
-
if( vertices.length > 0 ) {
|
|
501
|
-
buffer.push( 'M ' );
|
|
502
|
-
buffer.push( vertices[0].x )
|
|
503
|
-
buffer.push( ' ' );
|
|
504
|
-
buffer.push( vertices[0].y );
|
|
505
|
-
for( var i = 1; i < vertices.length; i++ ) {
|
|
506
|
-
buffer.push( ' L ' );
|
|
507
|
-
buffer.push( vertices[i].x )
|
|
508
|
-
buffer.push( ' ' );
|
|
509
|
-
buffer.push( vertices[i].y );
|
|
510
|
-
}
|
|
511
|
-
//if( !this.isOpen ) {
|
|
512
|
-
buffer.push( ' Z' );
|
|
513
|
-
//}
|
|
514
|
-
}
|
|
515
|
-
buffer.push( '" />' );
|
|
516
|
-
return buffer.join('');
|
|
517
|
-
};
|
|
518
|
-
|
|
519
|
-
private static utils = {
|
|
520
|
-
// Used in the bounds() function.
|
|
521
|
-
max3( a:number, b:number, c:number ) : number {
|
|
522
|
-
return ( a >= b && a >= c ) ? a : ( b >= a && b >= c ) ? b : c;
|
|
523
|
-
},
|
|
524
|
-
min3( a:number, b:number, c:number ) : number {
|
|
525
|
-
return ( a <= b && a <= c ) ? a : ( b <= a && b <= c ) ? b : c;
|
|
526
|
-
},
|
|
527
|
-
signedArea( p0x:number, p0y:number, p1x:number, p1y:number, p2x:number, p2y:number ) : number {
|
|
528
|
-
return 0.5*(-p1y*p2x + p0y*(-p1x + p2x) + p0x*(p1y - p2y) + p1x*p2y);
|
|
529
|
-
},
|
|
530
|
-
/**
|
|
531
|
-
* Used by the containsPoint() function.
|
|
532
|
-
*
|
|
533
|
-
* @private
|
|
534
|
-
**/
|
|
535
|
-
pointIsInTriangle( px:number, py:number, p0x:number, p0y:number, p1x:number, p1y:number, p2x:number, p2y:number ) : boolean {
|
|
536
|
-
//
|
|
537
|
-
// Point-in-Triangle test found at
|
|
538
|
-
// http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-2d-triangle
|
|
539
|
-
// var area : number = 1/2*(-p1y*p2x + p0y*(-p1x + p2x) + p0x*(p1y - p2y) + p1x*p2y);
|
|
540
|
-
var area : number = Triangle.utils.signedArea( p0x, p0y, p1x, p1y, p2x, p2y );
|
|
541
|
-
|
|
542
|
-
var s : number = 1/(2*area)*(p0y*p2x - p0x*p2y + (p2y - p0y)*px + (p0x - p2x)*py);
|
|
543
|
-
var t : number = 1/(2*area)*(p0x*p1y - p0y*p1x + (p0y - p1y)*px + (p1x - p0x)*py);
|
|
544
|
-
|
|
545
|
-
return s > 0 && t > 0 && (1-s-t) > 0;
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
|
|
503
|
+
};
|
|
549
504
|
}
|