plotboilerplate 1.16.0 → 1.17.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.
Files changed (173) hide show
  1. package/README.md +1 -0
  2. package/changelog.md +26 -1
  3. package/dist/index.esm.js +355 -441
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.esm.min.js +1 -1
  6. package/dist/index.esm.min.js.map +1 -1
  7. package/dist/plotboilerplate.browser.min.js +1 -1
  8. package/dist/plotboilerplate.browser.min.js.map +1 -1
  9. package/dist/plotboilerplate.js +357 -345
  10. package/dist/plotboilerplate.min.js +1 -1
  11. package/package.json +1 -1
  12. package/src/cjs/BezierPath.d.ts +0 -14
  13. package/src/cjs/BezierPath.js +0 -26
  14. package/src/cjs/BezierPath.js.map +1 -1
  15. package/src/cjs/Bounds.d.ts +22 -1
  16. package/src/cjs/Bounds.js +24 -1
  17. package/src/cjs/Bounds.js.map +1 -1
  18. package/src/cjs/Circle.d.ts +0 -13
  19. package/src/cjs/Circle.js +0 -23
  20. package/src/cjs/Circle.js.map +1 -1
  21. package/src/cjs/CircleSector.d.ts +0 -13
  22. package/src/cjs/CircleSector.js +0 -27
  23. package/src/cjs/CircleSector.js.map +1 -1
  24. package/src/cjs/CubicBezierCurve.d.ts +0 -15
  25. package/src/cjs/CubicBezierCurve.js +0 -36
  26. package/src/cjs/CubicBezierCurve.js.map +1 -1
  27. package/src/cjs/Line.d.ts +0 -14
  28. package/src/cjs/Line.js +0 -26
  29. package/src/cjs/Line.js.map +1 -1
  30. package/src/cjs/PBImage.d.ts +0 -13
  31. package/src/cjs/PBImage.js +0 -14
  32. package/src/cjs/PBImage.js.map +1 -1
  33. package/src/cjs/PBText.d.ts +0 -13
  34. package/src/cjs/PBText.js +0 -14
  35. package/src/cjs/PBText.js.map +1 -1
  36. package/src/cjs/Polygon.d.ts +9 -15
  37. package/src/cjs/Polygon.js +12 -39
  38. package/src/cjs/Polygon.js.map +1 -1
  39. package/src/cjs/Triangle.d.ts +0 -13
  40. package/src/cjs/Triangle.js +0 -37
  41. package/src/cjs/Triangle.js.map +1 -1
  42. package/src/cjs/VEllipse.d.ts +0 -10
  43. package/src/cjs/VEllipse.js +0 -21
  44. package/src/cjs/VEllipse.js.map +1 -1
  45. package/src/cjs/Vector.d.ts +0 -14
  46. package/src/cjs/Vector.js +0 -36
  47. package/src/cjs/Vector.js.map +1 -1
  48. package/src/cjs/Vertex.d.ts +0 -14
  49. package/src/cjs/Vertex.js +0 -25
  50. package/src/cjs/Vertex.js.map +1 -1
  51. package/src/cjs/draw.d.ts +41 -2
  52. package/src/cjs/draw.js +140 -3
  53. package/src/cjs/draw.js.map +1 -1
  54. package/src/cjs/drawgl.d.ts +38 -2
  55. package/src/cjs/drawgl.js +41 -2
  56. package/src/cjs/drawgl.js.map +1 -1
  57. package/src/cjs/drawutilssvg.d.ts +66 -3
  58. package/src/cjs/drawutilssvg.js +140 -15
  59. package/src/cjs/drawutilssvg.js.map +1 -1
  60. package/src/cjs/index.d.ts +0 -1
  61. package/src/cjs/index.js +0 -1
  62. package/src/cjs/index.js.map +1 -1
  63. package/src/cjs/interfaces/DrawLib.d.ts +61 -26
  64. package/src/cjs/interfaces/DrawLib.js +2 -0
  65. package/src/cjs/interfaces/DrawLib.js.map +1 -1
  66. package/src/cjs/interfaces/core.d.ts +0 -12
  67. package/src/cjs/module.d.ts +1 -3
  68. package/src/cjs/module.js +2 -5
  69. package/src/cjs/module.js.map +1 -1
  70. package/src/cjs/utils/creategui.js +16 -2
  71. package/src/cjs/utils/datastructures/Girih.d.ts +5 -0
  72. package/src/cjs/utils/datastructures/Girih.js +18 -14
  73. package/src/cjs/utils/datastructures/Girih.js.map +1 -1
  74. package/src/cjs/utils/datastructures/GirihPenroseRhombus.js +42 -25
  75. package/src/cjs/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
  76. package/src/cjs/utils/datastructures/GirihTile.js +2 -13
  77. package/src/cjs/utils/datastructures/GirihTile.js.map +1 -1
  78. package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +2 -1
  79. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +9 -18
  80. package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  81. package/src/esm/BezierPath.d.ts +0 -14
  82. package/src/esm/BezierPath.js +0 -26
  83. package/src/esm/BezierPath.js.map +1 -1
  84. package/src/esm/Bounds.d.ts +22 -1
  85. package/src/esm/Bounds.js +24 -1
  86. package/src/esm/Bounds.js.map +1 -1
  87. package/src/esm/Circle.d.ts +0 -13
  88. package/src/esm/Circle.js +0 -23
  89. package/src/esm/Circle.js.map +1 -1
  90. package/src/esm/CircleSector.d.ts +0 -13
  91. package/src/esm/CircleSector.js +0 -27
  92. package/src/esm/CircleSector.js.map +1 -1
  93. package/src/esm/CubicBezierCurve.d.ts +0 -15
  94. package/src/esm/CubicBezierCurve.js +0 -36
  95. package/src/esm/CubicBezierCurve.js.map +1 -1
  96. package/src/esm/Line.d.ts +0 -14
  97. package/src/esm/Line.js +0 -26
  98. package/src/esm/Line.js.map +1 -1
  99. package/src/esm/PBImage.d.ts +0 -13
  100. package/src/esm/PBImage.js +0 -14
  101. package/src/esm/PBImage.js.map +1 -1
  102. package/src/esm/PBText.d.ts +0 -13
  103. package/src/esm/PBText.js +0 -14
  104. package/src/esm/PBText.js.map +1 -1
  105. package/src/esm/Polygon.d.ts +9 -15
  106. package/src/esm/Polygon.js +12 -39
  107. package/src/esm/Polygon.js.map +1 -1
  108. package/src/esm/Triangle.d.ts +0 -13
  109. package/src/esm/Triangle.js +0 -37
  110. package/src/esm/Triangle.js.map +1 -1
  111. package/src/esm/VEllipse.d.ts +0 -10
  112. package/src/esm/VEllipse.js +0 -21
  113. package/src/esm/VEllipse.js.map +1 -1
  114. package/src/esm/Vector.d.ts +0 -14
  115. package/src/esm/Vector.js +0 -36
  116. package/src/esm/Vector.js.map +1 -1
  117. package/src/esm/Vertex.d.ts +0 -14
  118. package/src/esm/Vertex.js +0 -25
  119. package/src/esm/Vertex.js.map +1 -1
  120. package/src/esm/draw.d.ts +41 -2
  121. package/src/esm/draw.js +139 -3
  122. package/src/esm/draw.js.map +1 -1
  123. package/src/esm/drawgl.d.ts +38 -2
  124. package/src/esm/drawgl.js +41 -2
  125. package/src/esm/drawgl.js.map +1 -1
  126. package/src/esm/drawutilssvg.d.ts +66 -3
  127. package/src/esm/drawutilssvg.js +140 -15
  128. package/src/esm/drawutilssvg.js.map +1 -1
  129. package/src/esm/index.d.ts +0 -1
  130. package/src/esm/index.js +0 -1
  131. package/src/esm/index.js.map +1 -1
  132. package/src/esm/interfaces/DrawLib.d.ts +61 -26
  133. package/src/esm/interfaces/DrawLib.js +2 -0
  134. package/src/esm/interfaces/DrawLib.js.map +1 -1
  135. package/src/esm/interfaces/core.d.ts +0 -12
  136. package/src/esm/module.d.ts +1 -3
  137. package/src/esm/module.js +5 -4
  138. package/src/esm/module.js.map +1 -1
  139. package/src/esm/utils/datastructures/Girih.d.ts +5 -0
  140. package/src/esm/utils/datastructures/Girih.js +18 -14
  141. package/src/esm/utils/datastructures/Girih.js.map +1 -1
  142. package/src/esm/utils/datastructures/GirihPenroseRhombus.js +42 -25
  143. package/src/esm/utils/datastructures/GirihPenroseRhombus.js.map +1 -1
  144. package/src/esm/utils/datastructures/GirihTile.js +2 -13
  145. package/src/esm/utils/datastructures/GirihTile.js.map +1 -1
  146. package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +2 -1
  147. package/src/esm/utils/helpers/BezierPathInteractionHelper.js +9 -18
  148. package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
  149. package/src/ts/BezierPath.ts +0 -29
  150. package/src/ts/Bounds.ts +25 -1
  151. package/src/ts/Circle.ts +0 -26
  152. package/src/ts/CircleSector.ts +0 -30
  153. package/src/ts/CubicBezierCurve.ts +0 -39
  154. package/src/ts/Line.ts +0 -29
  155. package/src/ts/PBImage.ts +0 -15
  156. package/src/ts/PBText.ts +0 -17
  157. package/src/ts/Polygon.ts +16 -42
  158. package/src/ts/Triangle.ts +0 -40
  159. package/src/ts/VEllipse.ts +0 -24
  160. package/src/ts/Vector.ts +0 -40
  161. package/src/ts/Vertex.ts +0 -28
  162. package/src/ts/draw.ts +192 -3
  163. package/src/ts/drawgl.ts +44 -2
  164. package/src/ts/drawutilssvg.ts +181 -15
  165. package/src/ts/index.ts +0 -1
  166. package/src/ts/interfaces/DrawLib.ts +69 -26
  167. package/src/ts/interfaces/core.ts +0 -11
  168. package/src/ts/module.ts +2 -4
  169. package/src/ts/utils/datastructures/Girih.ts +204 -209
  170. package/src/ts/utils/datastructures/GirihPenroseRhombus.ts +170 -152
  171. package/src/ts/utils/datastructures/GirihTile.ts +394 -419
  172. package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +9 -18
  173. package/src/ts/SVGBuilder.ts +0 -109
@@ -16,22 +16,20 @@ import { Vertex } from "../../Vertex";
16
16
  import { XYCoords } from "../../interfaces";
17
17
 
18
18
  export enum TileType {
19
- UNKNOWN = "UNKNOWN",
20
- DECAGON = "DECAGON",
21
- PENTAGON = "PENTAGON",
22
- IRREGULAR_HEXAGON = "IRREGULAR_HEXAGON",
23
- RHOMBUS = "RHOMBUS",
24
- BOW_TIE = "BOW_TIE",
25
- // This is not part of the actual girih tile set!
26
- PENROSE_RHOMBUS = "PENROSE_RHOMBUS"
27
- };
19
+ UNKNOWN = "UNKNOWN",
20
+ DECAGON = "DECAGON",
21
+ PENTAGON = "PENTAGON",
22
+ IRREGULAR_HEXAGON = "IRREGULAR_HEXAGON",
23
+ RHOMBUS = "RHOMBUS",
24
+ BOW_TIE = "BOW_TIE",
25
+ // This is not part of the actual girih tile set!
26
+ PENROSE_RHOMBUS = "PENROSE_RHOMBUS"
27
+ }
28
28
 
29
29
  export interface IAdjacency {
30
- edgeIndex : number;
31
- offset : XYCoords;
32
- };
33
-
34
-
30
+ edgeIndex: number;
31
+ offset: XYCoords;
32
+ }
35
33
 
36
34
  /**
37
35
  * @classdesc This is a general tile superclass. All other tile classes extends this one.
@@ -45,409 +43,386 @@ export interface IAdjacency {
45
43
  * @requires XYCoords
46
44
  */
47
45
  export abstract class GirihTile extends Polygon {
48
-
49
- /**
50
- * The center of this tile.
51
- *
52
- * @name position
53
- * @member {Vertex}
54
- * @memberof GirihTile
55
- * @type {Vertex}
56
- * @instance
57
- */
58
- public position:Vertex;
59
-
60
- /**
61
- * The edge length of this tile (all edges of a Girih tile have same length).
62
- *
63
- * @name edgeLength
64
- * @member {number}
65
- * @memberof GirihTile
66
- * @type {number}
67
- * @readonly
68
- * @instance
69
- */
70
- public readonly edgeLength:number;
71
-
72
- /**
73
- * The rotation of this tile. This is stored to make cloning easier.
74
- *
75
- * @name rotation.
76
- * @member {number}
77
- * @memberof GirihTile
78
- * @type {number}
79
- * @instance
80
- */
81
- public rotation:number;
82
-
83
- /**
84
- * The symmetry (=order) of this tile. This is the number of steps used for a full
85
- * rotation (in this Girih case: 10). Future Girih implementations might have other symmetries.
86
- *
87
- * @name symmetry
88
- * @member {number}
89
- * @memberof GirihTile
90
- * @type {number}
91
- * @instance
92
- */
93
- public symmetry:number // Todo: rename to 'symmetries'?
94
-
95
- /**
96
- * The unique symmetries. This must be an nth part of the global `symmetry`.
97
- * Rotating this tile `uniqueSymmetries' times results in the same visual tile (flipped around
98
- * a symmetry axis).
99
- *
100
- * @name uniqueSymmetries
101
- * @member {number}
102
- * @memberof GirihTile
103
- * @type {number}
104
- * @instance
105
- */
106
- public uniqueSymmetries:number;
107
-
108
- /**
109
- * The inner tile polygons.
110
- *
111
- * @name innerTilePolygons
112
- * @member {Array<Polygon>}
113
- * @memberof GirihTile
114
- * @type {Array<Polygon>}
115
- * @instance
116
- */
117
- public innerTilePolygons:Array<Polygon>;
118
-
119
- /**
120
- * The outer tile polygons.
121
- *
122
- * @name outerTilePolygons
123
- * @member {Array<Polygon>}
124
- * @memberof GirihTile
125
- * @type {Array<Polygon>}
126
- * @instance
127
- */
128
- public outerTilePolygons:Array<Polygon>;
129
-
130
- /**
131
- * An identifier for the tile type.
132
- *
133
- * @name tileType
134
- * @member {TileType}
135
- * @memberof GirihTile
136
- * @type {TileType}
137
- * @instance
138
- */
139
- public tileType:TileType;
140
-
141
- /**
142
- * The initial bounds (of the un-rotated tile). These are required to calculate the
143
- * correct texture mapping.
144
- *
145
- * @name baseBounds
146
- * @member {Bounds}
147
- * @memberof GirihTile
148
- * @type {Bounds}
149
- * @instance
150
- */
151
- public baseBounds:Bounds;
152
-
153
- /**
154
- * A rectangle on the shipped texture image (`girihtexture-500px.png`) marking the
155
- * texture position. The bounds are relative, so each component must be in [0..1].
156
- * The texture is a square.
157
- *
158
- * @name textureSource
159
- * @member {Bounds}
160
- * @memberof GirihTile
161
- * @type {Bounds}
162
- * @instance
163
- */
164
- public readonly textureSource:Bounds;
165
-
166
- /**
167
- * An epsilon to use for detecting adjacent edges. 0.001 seems to be a good value.
168
- * Adjust if needed.
169
- *
170
- * @name epsilon
171
- * @member {number}
172
- * @memberof GirihTile
173
- * @type {number}
174
- * @static
175
- */
176
- public static epsilon:number = 0.001;
177
-
178
- /**
179
- * The default edge length.
180
- *
181
- * @name DEFAULT_EDGE_LENGTH
182
- * @member {number}
183
- * @memberof GirihTile
184
- * @type {number}
185
- * @readonly
186
- * @static
187
- */
188
- public static readonly DEFAULT_EDGE_LENGTH:number = 58;
189
-
190
-
191
-
192
- /**
193
- * @constructor
194
- * @memberof GirihTile
195
- * @abstract class
196
- * @param {Vertex} position - The position of the tile.
197
- * @param {number} edgeLength - The edge length (default is GirihTile.DEFAULT_EDGE_LENGTH).
198
- * @param {TileType} tileType - One of `TileType.*` enum members.
199
- **/
200
- constructor( position:Vertex,
201
- edgeLength?:number,
202
- tileType?:TileType
203
- ) {
204
- super( [], false ); // vertices, isOpen
205
-
206
- if( typeof edgeLength === "undefined" )
207
- edgeLength = GirihTile.DEFAULT_EDGE_LENGTH;
208
- if( typeof tileType == "undefined" )
209
- tileType = TileType.UNKNOWN;
210
-
211
- this.edgeLength = edgeLength;
212
- this.position = position;
213
- this.rotation = 0.0; // angle;
214
- this.symmetry = 10;
215
- this.uniqueSymmetries = 10;
216
-
217
- // An array of polygons.
218
- // The inner tile polygons are those that do not share edges with the outer
219
- // tile bounds (vertices are OK).
220
- this.innerTilePolygons = [];
221
-
222
- // A second array of polygons.
223
- // The outer tile polygons are those that make up the whole tile area
224
- // _together with the inner tile polygons (!)_; the union of the
225
- // inner tile polygons and the outer tile polygons covers exactly
226
- // the whole tile polygon.
227
- // The intersection of both sets is empty.
228
- // Outer tile polygon share at least one (partial) edge with the complete
229
- // tile polygon (length > 0).
230
- this.outerTilePolygons = [];
231
- // this.imageProperties = null;
232
- this.textureSource = new Bounds( new Vertex(), new Vertex() );
233
-
234
- this.tileType = tileType;
235
- };
236
-
237
-
238
- /**
239
- * @abstract Subclasses must override this.
240
- */
241
- abstract clone() : GirihTile;
242
-
243
- /**
244
- * Move this tile around (together will all inner polygons).
245
- * As this function overrides Polygon.move(...), the returned
246
- * instance (this) must be of type `Polygon`.
247
- *
248
- * @name move
249
- * @instance
250
- * @override
251
- * @memberof GirihTile
252
- * @param {XYCoords} amount
253
- * @return {Polygon} this
254
- */
255
- move( amount:XYCoords ) : Polygon {
256
- super.move.call( this, amount );
257
- for( var i in this.innerTilePolygons )
258
- this.innerTilePolygons[i].move( amount );
259
- for( var i in this.outerTilePolygons )
260
- this.outerTilePolygons[i].move( amount );
261
- this.position.add( amount );
262
- return this;
263
- };
264
-
265
-
266
- /**
267
- * Find the adjacent tile (given by the template tile)
268
- * Note that the tile itself will be modified (rotated and moved to the correct position).
269
- *
270
- * @name findAdjacentTilePosition
271
- * @memberof GirihTile
272
- * @instance
273
- * @param {number} edgeIndex - The edge number of the you you want to find adjacency for.
274
- * @param {Polygon} tile - The polygon (or tile) you want to find adjacency for at the specified edge.
275
- * @return {IAdjacency|null} Adjacency information or null if the passed tile does not match.
276
- */
277
- findAdjacentTilePosition( edgeIndex:number, tile:Polygon ) : IAdjacency|null {
278
- const edgeA:Line = new Line( this.vertices[ edgeIndex % this.vertices.length ],
279
- this.vertices[ (edgeIndex+1) % this.vertices.length ] );
280
- // Find adjacent edge
281
- for( var i = 0; i < tile.vertices.length; i++ ) {
282
- const edgeB:Line = new Line( tile.vertices[ i % tile.vertices.length ].clone(),
283
- tile.vertices[ (i+1) % tile.vertices.length ].clone() );
284
- // Goal: edgeA.a==edgeB.b && edgeA.b==edgeB.a
285
- // So move edgeB
286
- const offset:XYCoords = edgeB.b.difference(edgeA.a);
287
- edgeB.add( offset );
288
- if( edgeB.a.distance(edgeA.b) < GirihTile.epsilon ) {
289
- return { edgeIndex : i, offset : offset } as IAdjacency;
290
- }
291
- }
292
- return null;
293
- };
294
-
295
-
296
- /**
297
- * Find all possible adjacent tile positions (and rotations) for `neighbourTile`.
298
- *
299
- * @name transformTileToAdjacencies
300
- * @memberof GirihTile
301
- * @instance
302
- * @param {number} baseEdgeIndex - The edge number of the you you want to find adjacencies for.
303
- * @param {GirihTile} neighbourTile - The polygon (or tile) you want to find adjacencies for at the specified edge.
304
- * @return {IAdjacency|null} Adjacency information or null if the passed tile does not match.
305
- */
306
- transformTileToAdjacencies( baseEdgeIndex:number,
307
- neighbourTile:GirihTile ) : Array<GirihTile> {
308
- // Find a rotation for that tile to match
309
- let i : number = 0;
310
- const foundAlignments:Array<GirihTile> = [];
311
- let positionedTile : GirihTile|null = null;
312
- while( i < neighbourTile.uniqueSymmetries ) {
313
- positionedTile = this.transformTilePositionToAdjacency( baseEdgeIndex,
314
- neighbourTile );
315
- if( positionedTile != null ) {
316
- positionedTile = positionedTile.clone();
317
- foundAlignments.push( positionedTile );
318
- }
319
- neighbourTile.rotate( (Math.PI*2)/neighbourTile.symmetry );
320
- i++
321
- }
322
- return foundAlignments;
323
- };
324
-
325
-
326
- /**
327
- * Apply adjacent tile position to `neighbourTile`.
328
- *
329
- * @name transformTilePositionToAdjacencies
330
- * @memberof GirihTile
331
- * @instance
332
- * @param {number} baseEdgeIndex - The edge number of the you you want to apply adjacent position for.
333
- * @param {Polygon} neighbourTile - The polygon (or tile) you want to find adjacency for at the specified edge.
334
- * @return {Polygon|null} the passed tile itself if adjacency was found, null otherwise.
335
- */
336
- transformTilePositionToAdjacency<P extends Polygon>( baseEdgeIndex:number,
337
- neighbourTile:P ) : P {
338
- // Find the position for that tile to match (might not exist)
339
- // { edgeIndex:number, offset:XYCoords }
340
- var adjacency = this.findAdjacentTilePosition( baseEdgeIndex, neighbourTile );
341
- if( adjacency != null ) {
342
- neighbourTile.move( adjacency.offset );
343
- return neighbourTile;
344
- }
345
- return null;
346
- };
347
-
348
-
349
- /**
350
- * Get the inner tile polygon at the given index.
351
- * This function applies MOD to the index.
352
- *
353
- * @name getInnerTilePolygonAt
354
- * @instance
355
- * @memberof GirihTile
356
- * @param {number} index
357
- * @return {Polygon} The sub polygon (inner tile) at the given index.
358
- **/
359
- getInnerTilePolygonAt( index:number ) : Polygon {
360
- if( index < 0 )
361
- return this.innerTilePolygons[ this.innerTilePolygons.length - (Math.abs(index)%this.innerTilePolygons.length) ];
362
- else
363
- return this.innerTilePolygons[ index % this.innerTilePolygons.length ];
364
- };
365
-
366
-
367
- /**
368
- * Get the outer tile polygon at the given index.
369
- * This function applies MOD to the index.
370
- *
371
- * @name getOuterTilePolygonAt
372
- * @instance
373
- * @memberof GirihTile
374
- * @param {number} index
375
- * @return {Polygon} The sub polygon (outer tile) at the given index.
376
- **/
377
- getOuterTilePolygonAt( index:number ) : Polygon {
378
- if( index < 0 )
379
- return this.outerTilePolygons[ this.outerTilePolygons.length - (Math.abs(index)%this.outerTilePolygons.length) ];
380
- else
381
- return this.outerTilePolygons[ index % this.outerTilePolygons.length ];
382
- };
383
-
384
- /**
385
- * Rotate this tile
386
- * Note: this function behaves a bitdifferent than the genuine Polygon.rotate function!
387
- * Polygon has the default center of rotation at (0,0).
388
- * The GirihTile rotates around its center (position) by default.
389
- *
390
- * @name rotate
391
- * @instance
392
- * @memberof GirihTile
393
- * @param {number} angle - The angle to use for rotation.
394
- * @param {Vertex?} center - The center of rotation (default is this.position).
395
- * @return {Polygon} this
396
- **/
397
- rotate( angle:number, center?:Vertex ) : GirihTile {
398
- if( typeof center === "undefined" )
399
- center = this.position;
400
- super.rotate( angle, center );
401
- for( var i in this.innerTilePolygons ) {
402
- this.innerTilePolygons[i].rotate( angle, center );
403
- }
404
- for( var i in this.outerTilePolygons ) {
405
- this.outerTilePolygons[i].rotate( angle, center );
406
- }
407
- this.rotation += angle;
408
- return this;
409
- };
410
-
411
-
412
- /**
413
- * This function locates the closest tile edge (polygon edge)
414
- * to the passed point.
415
- *
416
- * Currently the edge distance to a point is measured by the
417
- * euclidian distance from the edge's middle point.
418
- *
419
- * Idea: move this function to Polygon?
420
- *
421
- * @name locateEdgeAtPoint
422
- * @instance
423
- * @memberof GirihTile
424
- * @param {XYCoords} point - The point to detect the closest edge for.
425
- * @param {number} tolerance - The tolerance (=max distance) the detected edge
426
- * must be inside.
427
- * @return {nmber} the edge index (index of the starting vertex, so [index,index+1] is the edge ) or -1 if not found.
428
- **/
429
- locateEdgeAtPoint( point:XYCoords,
430
- tolerance:number
431
- ) : number {
432
- if( this.vertices.length == 0 )
433
- return -1;
434
- const middle:Vertex = new Vertex( 0, 0 );
435
- let tmpDistance:number = 0;
436
- let resultDistance:number = tolerance*2; // definitely outside the tolerance :)
437
- let resultIndex:number = -1;
438
- for( var i = 0; i < this.vertices.length; i++ ) {
439
- const vertI:Vertex = this.getVertexAt( i );
440
- const vertJ:Vertex = this.getVertexAt( i+1 );
441
- // Create a point in the middle of the edge
442
- middle.x = vertI.x + (vertJ.x - vertI.x)/2.0;
443
- middle.y = vertI.y + (vertJ.y - vertI.y)/2.0;
444
- tmpDistance = middle.distance(point);
445
- if( tmpDistance <= tolerance && (resultIndex == -1 || tmpDistance < resultDistance) ) {
446
- resultDistance = tmpDistance;
447
- resultIndex = i;
448
- }
449
- }
450
- return resultIndex;
46
+ /**
47
+ * The center of this tile.
48
+ *
49
+ * @name position
50
+ * @member {Vertex}
51
+ * @memberof GirihTile
52
+ * @type {Vertex}
53
+ * @instance
54
+ */
55
+ public position: Vertex;
56
+
57
+ /**
58
+ * The edge length of this tile (all edges of a Girih tile have same length).
59
+ *
60
+ * @name edgeLength
61
+ * @member {number}
62
+ * @memberof GirihTile
63
+ * @type {number}
64
+ * @readonly
65
+ * @instance
66
+ */
67
+ public readonly edgeLength: number;
68
+
69
+ /**
70
+ * The rotation of this tile. This is stored to make cloning easier.
71
+ *
72
+ * @name rotation.
73
+ * @member {number}
74
+ * @memberof GirihTile
75
+ * @type {number}
76
+ * @instance
77
+ */
78
+ public rotation: number;
79
+
80
+ /**
81
+ * The symmetry (=order) of this tile. This is the number of steps used for a full
82
+ * rotation (in this Girih case: 10). Future Girih implementations might have other symmetries.
83
+ *
84
+ * @name symmetry
85
+ * @member {number}
86
+ * @memberof GirihTile
87
+ * @type {number}
88
+ * @instance
89
+ */
90
+ public symmetry: number; // Todo: rename to 'symmetries'?
91
+
92
+ /**
93
+ * The unique symmetries. This must be an nth part of the global `symmetry`.
94
+ * Rotating this tile `uniqueSymmetries' times results in the same visual tile (flipped around
95
+ * a symmetry axis).
96
+ *
97
+ * @name uniqueSymmetries
98
+ * @member {number}
99
+ * @memberof GirihTile
100
+ * @type {number}
101
+ * @instance
102
+ */
103
+ public uniqueSymmetries: number;
104
+
105
+ /**
106
+ * The inner tile polygons.
107
+ *
108
+ * @name innerTilePolygons
109
+ * @member {Array<Polygon>}
110
+ * @memberof GirihTile
111
+ * @type {Array<Polygon>}
112
+ * @instance
113
+ */
114
+ public innerTilePolygons: Array<Polygon>;
115
+
116
+ /**
117
+ * The outer tile polygons.
118
+ *
119
+ * @name outerTilePolygons
120
+ * @member {Array<Polygon>}
121
+ * @memberof GirihTile
122
+ * @type {Array<Polygon>}
123
+ * @instance
124
+ */
125
+ public outerTilePolygons: Array<Polygon>;
126
+
127
+ /**
128
+ * An identifier for the tile type.
129
+ *
130
+ * @name tileType
131
+ * @member {TileType}
132
+ * @memberof GirihTile
133
+ * @type {TileType}
134
+ * @instance
135
+ */
136
+ public tileType: TileType;
137
+
138
+ /**
139
+ * The initial bounds (of the un-rotated tile). These are required to calculate the
140
+ * correct texture mapping.
141
+ *
142
+ * @name baseBounds
143
+ * @member {Bounds}
144
+ * @memberof GirihTile
145
+ * @type {Bounds}
146
+ * @instance
147
+ */
148
+ public baseBounds: Bounds;
149
+
150
+ /**
151
+ * A rectangle on the shipped texture image (`girihtexture-500px.png`) marking the
152
+ * texture position. The bounds are relative, so each component must be in [0..1].
153
+ * The texture is a square.
154
+ *
155
+ * @name textureSource
156
+ * @member {Bounds}
157
+ * @memberof GirihTile
158
+ * @type {Bounds}
159
+ * @instance
160
+ */
161
+ public readonly textureSource: Bounds;
162
+
163
+ /**
164
+ * An epsilon to use for detecting adjacent edges. 0.001 seems to be a good value.
165
+ * Adjust if needed.
166
+ *
167
+ * @name epsilon
168
+ * @member {number}
169
+ * @memberof GirihTile
170
+ * @type {number}
171
+ * @static
172
+ */
173
+ public static epsilon: number = 0.001;
174
+
175
+ /**
176
+ * The default edge length.
177
+ *
178
+ * @name DEFAULT_EDGE_LENGTH
179
+ * @member {number}
180
+ * @memberof GirihTile
181
+ * @type {number}
182
+ * @readonly
183
+ * @static
184
+ */
185
+ public static readonly DEFAULT_EDGE_LENGTH: number = 58;
186
+
187
+ /**
188
+ * @constructor
189
+ * @memberof GirihTile
190
+ * @abstract class
191
+ * @param {Vertex} position - The position of the tile.
192
+ * @param {number} edgeLength - The edge length (default is GirihTile.DEFAULT_EDGE_LENGTH).
193
+ * @param {TileType} tileType - One of `TileType.*` enum members.
194
+ **/
195
+ constructor(position: Vertex, edgeLength?: number, tileType?: TileType) {
196
+ super([], false); // vertices, isOpen
197
+
198
+ if (typeof edgeLength === "undefined") edgeLength = GirihTile.DEFAULT_EDGE_LENGTH;
199
+ if (typeof tileType == "undefined") tileType = TileType.UNKNOWN;
200
+
201
+ this.edgeLength = edgeLength;
202
+ this.position = position;
203
+ this.rotation = 0.0; // angle;
204
+ this.symmetry = 10;
205
+ this.uniqueSymmetries = 10;
206
+
207
+ // An array of polygons.
208
+ // The inner tile polygons are those that do not share edges with the outer
209
+ // tile bounds (vertices are OK).
210
+ this.innerTilePolygons = [];
211
+
212
+ // A second array of polygons.
213
+ // The outer tile polygons are those that make up the whole tile area
214
+ // _together with the inner tile polygons (!)_; the union of the
215
+ // inner tile polygons and the outer tile polygons covers exactly
216
+ // the whole tile polygon.
217
+ // The intersection of both sets is empty.
218
+ // Outer tile polygon share at least one (partial) edge with the complete
219
+ // tile polygon (length > 0).
220
+ this.outerTilePolygons = [];
221
+ // this.imageProperties = null;
222
+ this.textureSource = new Bounds(new Vertex(), new Vertex());
223
+
224
+ this.tileType = tileType;
225
+ }
226
+
227
+ /**
228
+ * @abstract Subclasses must override this.
229
+ */
230
+ abstract clone(): GirihTile;
231
+
232
+ /**
233
+ * Move this tile around (together will all inner polygons).
234
+ * As this function overrides Polygon.move(...), the returned
235
+ * instance (this) must be of type `Polygon`.
236
+ *
237
+ * @name move
238
+ * @instance
239
+ * @override
240
+ * @memberof GirihTile
241
+ * @param {XYCoords} amount
242
+ * @return {Polygon} this
243
+ */
244
+ move(amount: XYCoords): Polygon {
245
+ super.move.call(this, amount);
246
+ for (var i in this.innerTilePolygons) this.innerTilePolygons[i].move(amount);
247
+ for (var i in this.outerTilePolygons) this.outerTilePolygons[i].move(amount);
248
+ this.position.add(amount);
249
+ return this;
250
+ }
251
+
252
+ /**
253
+ * Find the adjacent tile (given by the template tile)
254
+ * Note that the tile itself will be modified (rotated and moved to the correct position).
255
+ *
256
+ * @name findAdjacentTilePosition
257
+ * @memberof GirihTile
258
+ * @instance
259
+ * @param {number} edgeIndex - The edge number of the you you want to find adjacency for.
260
+ * @param {Polygon} tile - The polygon (or tile) you want to find adjacency for at the specified edge.
261
+ * @return {IAdjacency|null} Adjacency information or null if the passed tile does not match.
262
+ */
263
+ findAdjacentTilePosition(edgeIndex: number, tile: Polygon): IAdjacency | null {
264
+ const edgeA: Line = new Line(
265
+ this.vertices[edgeIndex % this.vertices.length],
266
+ this.vertices[(edgeIndex + 1) % this.vertices.length]
267
+ );
268
+ // Find adjacent edge
269
+ for (var i = 0; i < tile.vertices.length; i++) {
270
+ const edgeB: Line = new Line(
271
+ tile.vertices[i % tile.vertices.length].clone(),
272
+ tile.vertices[(i + 1) % tile.vertices.length].clone()
273
+ );
274
+ // Goal: edgeA.a==edgeB.b && edgeA.b==edgeB.a
275
+ // So move edgeB
276
+ const offset: XYCoords = edgeB.b.difference(edgeA.a);
277
+ edgeB.add(offset);
278
+ if (edgeB.a.distance(edgeA.b) < GirihTile.epsilon) {
279
+ return { edgeIndex: i, offset: offset } as IAdjacency;
280
+ }
451
281
  }
452
- }; // END class
453
-
282
+ return null;
283
+ }
284
+
285
+ /**
286
+ * Find all possible adjacent tile positions (and rotations) for `neighbourTile`.
287
+ *
288
+ * @name transformTileToAdjacencies
289
+ * @memberof GirihTile
290
+ * @instance
291
+ * @param {number} baseEdgeIndex - The edge number of the you you want to find adjacencies for.
292
+ * @param {GirihTile} neighbourTile - The polygon (or tile) you want to find adjacencies for at the specified edge.
293
+ * @return {IAdjacency|null} Adjacency information or null if the passed tile does not match.
294
+ */
295
+ transformTileToAdjacencies(baseEdgeIndex: number, neighbourTile: GirihTile): Array<GirihTile> {
296
+ // Find a rotation for that tile to match
297
+ let i: number = 0;
298
+ const foundAlignments: Array<GirihTile> = [];
299
+ let positionedTile: GirihTile | null = null;
300
+ while (i < neighbourTile.uniqueSymmetries) {
301
+ positionedTile = this.transformTilePositionToAdjacency(baseEdgeIndex, neighbourTile);
302
+ if (positionedTile != null) {
303
+ positionedTile = positionedTile.clone();
304
+ foundAlignments.push(positionedTile);
305
+ }
306
+ neighbourTile.rotate((Math.PI * 2) / neighbourTile.symmetry);
307
+ i++;
308
+ }
309
+ return foundAlignments;
310
+ }
311
+
312
+ /**
313
+ * Apply adjacent tile position to `neighbourTile`.
314
+ *
315
+ * @name transformTilePositionToAdjacencies
316
+ * @memberof GirihTile
317
+ * @instance
318
+ * @param {number} baseEdgeIndex - The edge number of the you you want to apply adjacent position for.
319
+ * @param {Polygon} neighbourTile - The polygon (or tile) you want to find adjacency for at the specified edge.
320
+ * @return {Polygon|null} the passed tile itself if adjacency was found, null otherwise.
321
+ */
322
+ transformTilePositionToAdjacency<P extends Polygon>(baseEdgeIndex: number, neighbourTile: P): P {
323
+ // Find the position for that tile to match (might not exist)
324
+ // { edgeIndex:number, offset:XYCoords }
325
+ var adjacency = this.findAdjacentTilePosition(baseEdgeIndex, neighbourTile);
326
+ if (adjacency != null) {
327
+ neighbourTile.move(adjacency.offset);
328
+ return neighbourTile;
329
+ }
330
+ return null;
331
+ }
332
+
333
+ /**
334
+ * Get the inner tile polygon at the given index.
335
+ * This function applies MOD to the index.
336
+ *
337
+ * @name getInnerTilePolygonAt
338
+ * @instance
339
+ * @memberof GirihTile
340
+ * @param {number} index
341
+ * @return {Polygon} The sub polygon (inner tile) at the given index.
342
+ **/
343
+ getInnerTilePolygonAt(index: number): Polygon {
344
+ if (index < 0)
345
+ return this.innerTilePolygons[this.innerTilePolygons.length - (Math.abs(index) % this.innerTilePolygons.length)];
346
+ else return this.innerTilePolygons[index % this.innerTilePolygons.length];
347
+ }
348
+
349
+ /**
350
+ * Get the outer tile polygon at the given index.
351
+ * This function applies MOD to the index.
352
+ *
353
+ * @name getOuterTilePolygonAt
354
+ * @instance
355
+ * @memberof GirihTile
356
+ * @param {number} index
357
+ * @return {Polygon} The sub polygon (outer tile) at the given index.
358
+ **/
359
+ getOuterTilePolygonAt(index: number): Polygon {
360
+ if (index < 0)
361
+ return this.outerTilePolygons[this.outerTilePolygons.length - (Math.abs(index) % this.outerTilePolygons.length)];
362
+ else return this.outerTilePolygons[index % this.outerTilePolygons.length];
363
+ }
364
+
365
+ /**
366
+ * Rotate this tile
367
+ * Note: this function behaves a bitdifferent than the genuine Polygon.rotate function!
368
+ * Polygon has the default center of rotation at (0,0).
369
+ * The GirihTile rotates around its center (position) by default.
370
+ *
371
+ * @name rotate
372
+ * @instance
373
+ * @memberof GirihTile
374
+ * @param {number} angle - The angle to use for rotation.
375
+ * @param {Vertex?} center - The center of rotation (default is this.position).
376
+ * @return {Polygon} this
377
+ **/
378
+ rotate(angle: number, center?: Vertex): GirihTile {
379
+ if (typeof center === "undefined") center = this.position;
380
+ super.rotate(angle, center);
381
+ for (var i in this.innerTilePolygons) {
382
+ this.innerTilePolygons[i].rotate(angle, center);
383
+ }
384
+ for (var i in this.outerTilePolygons) {
385
+ this.outerTilePolygons[i].rotate(angle, center);
386
+ }
387
+ this.rotation += angle;
388
+ return this;
389
+ }
390
+
391
+ /**
392
+ * This function locates the closest tile edge (polygon edge)
393
+ * to the passed point.
394
+ *
395
+ * Currently the edge distance to a point is measured by the
396
+ * euclidian distance from the edge's middle point.
397
+ *
398
+ * Idea: move this function to Polygon?
399
+ *
400
+ * @name locateEdgeAtPoint
401
+ * @instance
402
+ * @memberof GirihTile
403
+ * @param {XYCoords} point - The point to detect the closest edge for.
404
+ * @param {number} tolerance - The tolerance (=max distance) the detected edge
405
+ * must be inside.
406
+ * @return {nmber} the edge index (index of the starting vertex, so [index,index+1] is the edge ) or -1 if not found.
407
+ **/
408
+ locateEdgeAtPoint(point: XYCoords, tolerance: number): number {
409
+ if (this.vertices.length == 0) return -1;
410
+ const middle: Vertex = new Vertex(0, 0);
411
+ let tmpDistance: number = 0;
412
+ let resultDistance: number = tolerance * 2; // definitely outside the tolerance :)
413
+ let resultIndex: number = -1;
414
+ for (var i = 0; i < this.vertices.length; i++) {
415
+ const vertI: Vertex = this.getVertexAt(i);
416
+ const vertJ: Vertex = this.getVertexAt(i + 1);
417
+ // Create a point in the middle of the edge
418
+ middle.x = vertI.x + (vertJ.x - vertI.x) / 2.0;
419
+ middle.y = vertI.y + (vertJ.y - vertI.y) / 2.0;
420
+ tmpDistance = middle.distance(point);
421
+ if (tmpDistance <= tolerance && (resultIndex == -1 || tmpDistance < resultDistance)) {
422
+ resultDistance = tmpDistance;
423
+ resultIndex = i;
424
+ }
425
+ }
426
+ return resultIndex;
427
+ }
428
+ } // END class