plotboilerplate 1.14.0 → 1.15.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 (38) hide show
  1. package/README.md +1 -0
  2. package/changelog.md +8 -0
  3. package/dist/index.esm.js +144 -42
  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 +144 -42
  10. package/dist/plotboilerplate.min.js +1 -1
  11. package/package.json +1 -1
  12. package/src/cjs/PlotBoilerplate.js +2 -1
  13. package/src/cjs/PlotBoilerplate.js.map +1 -1
  14. package/src/cjs/Polygon.d.ts +22 -1
  15. package/src/cjs/Polygon.js +102 -39
  16. package/src/cjs/Polygon.js.map +1 -1
  17. package/src/cjs/Vertex.d.ts +25 -1
  18. package/src/cjs/Vertex.js +39 -1
  19. package/src/cjs/Vertex.js.map +1 -1
  20. package/src/cjs/utils/findInVertexArray.d.ts +19 -0
  21. package/src/cjs/utils/findInVertexArray.js +29 -0
  22. package/src/cjs/utils/findInVertexArray.js.map +1 -0
  23. package/src/esm/PlotBoilerplate.js +2 -1
  24. package/src/esm/PlotBoilerplate.js.map +1 -1
  25. package/src/esm/Polygon.d.ts +22 -1
  26. package/src/esm/Polygon.js +102 -39
  27. package/src/esm/Polygon.js.map +1 -1
  28. package/src/esm/Vertex.d.ts +25 -1
  29. package/src/esm/Vertex.js +39 -1
  30. package/src/esm/Vertex.js.map +1 -1
  31. package/src/esm/utils/findInVertexArray.d.ts +19 -0
  32. package/src/esm/utils/findInVertexArray.js +25 -0
  33. package/src/esm/utils/findInVertexArray.js.map +1 -0
  34. package/src/ts/PlotBoilerplate.ts +3 -1
  35. package/src/ts/Polygon.ts +493 -451
  36. package/src/ts/Vertex.ts +41 -1
  37. package/src/ts/utils/findInVertexArray.ts +28 -0
  38. package/src/ts/utils/algorithms/sh-tmp.ts~ +0 -59
package/README.md CHANGED
@@ -483,6 +483,7 @@ vert.listeners.addDragListener(function (e) {
483
483
  - [Torben Jansen](https://twitter.com/torbenjansen_ "Torben Jansen") for the [SVG-Arc to elliptic-sector conversion](https://observablehq.com/@toja/ellipse-and-elliptical-arc-conversion "SVG-Arc to elliptic-sector conversion")
484
484
  - [3daddict](https://github.com/3daddict) for the [js-stl-parser inspiration](https://github.com/3daddict/js-stl-parser/blob/master/index.js "js-stl-parser inspiration")
485
485
  - [jburkardt](https://people.sc.fsu.edu/~jburkardt/data/obj/obj.html "jburkardt") for the obj test files.
486
+ - [@veltman](https://noahveltman.com/) for the awesome [geometric skeletonization article](https://observablehq.com/@veltman/centerline-labeling)
486
487
 
487
488
  ## Todos
488
489
 
package/changelog.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ - 2022-01-10
4
+ - Added utility function `findInVertexArray`.
5
+ - 2021-12-17
6
+ - Added the functions `Vertex.lerp` and `Vertex.lerpAbs` for linear interpolations.
7
+ - 2021-12-16
8
+ - Added the `Polygon.getEvenDistributionPolygon()` function.
9
+ - 2021-12-14
10
+ - Added the `Polygon.perimeter()` function.
3
11
  - 2021-12-01
4
12
  - Changed the type of param of `BezierPath.scale` to XYCoords.
5
13
  - Added function `BezierPath.scaleXY` for non uniform scaling.
package/dist/index.esm.js CHANGED
@@ -360,7 +360,8 @@ class VertexListeners {
360
360
  * @modified 2021-03-01 Changed the second param `center` in the `rotate` function from Vertex to XYCoords.
361
361
  * @modified 2021-12-01 Changed the type of param of `scale` to XYCoords.
362
362
  * @modified 2021-12-01 Added function `scaleXY` for non uniform scaling.
363
- * @version 2.5.0
363
+ * @modified 2021-12-17 Added the functions `lerp` and `lerpAbs` for linear interpolations.
364
+ * @version 2.6.0
364
365
  *
365
366
  * @file Vertex
366
367
  * @public
@@ -713,6 +714,43 @@ class Vertex {
713
714
  scale(factor, center) {
714
715
  return this.scaleXY({ x: factor, y: factor }, center);
715
716
  }
717
+ /**
718
+ * Perform a linear interpolation towards the given target vertex.
719
+ * The amount value `t` is relative, `t=0.0` means no change, `t=1.0`
720
+ * means this point will be moved to the exact target position.
721
+ *
722
+ * `t=0.5` will move this point to the middle of the connecting
723
+ * linear segment.
724
+ *
725
+ * @param {XYCoords} target - The target position to lerp this vertex to.
726
+ * @param {number} t - The relative amount, usually in [0..1], but other values will work, too.
727
+ * @returns
728
+ */
729
+ lerp(target, t) {
730
+ var diff = this.difference(target);
731
+ // return new Vertex(this.x + diff.x * t, this.y + diff.y * t);
732
+ this.x += diff.x * t;
733
+ this.y += diff.y * t;
734
+ return this;
735
+ }
736
+ /**
737
+ * Perform a linear interpolation towards the given target vertex (absolute variant).
738
+ * The amount value `t` is absolute, which means the lerp amount is a direct distance
739
+ * value. This point will have move the amount of the passed distance `u`.
740
+ *
741
+ * @param {XYCoords} target - The target position to lerp this vertex to.
742
+ * @param {number} t - The absolute move amount to use to lerping.
743
+ * @returns
744
+ */
745
+ lerpAbs(target, u) {
746
+ var dist = this.distance(target);
747
+ var diff = this.difference(target);
748
+ var step = { x: diff.x / dist, y: diff.y / dist };
749
+ // return new Vertex(this.x + step.x * u, this.y + step.y * u);
750
+ this.x += step.x * u;
751
+ this.y += step.y * u;
752
+ return this;
753
+ }
716
754
  /**
717
755
  * This is a vector-like behavior and 'scales' this vertex
718
756
  * towards/from a given center by two independent x- and y- scale factors.
@@ -910,7 +948,9 @@ Vertex.utils = {
910
948
  * @modified 2021-01-29 Added the `isClockwise` function.
911
949
  * @modified 2021-01-29 Added the `area` function.
912
950
  * @modified 2021-01-29 Changed the param type for `containsVert` from Vertex to XYCoords.
913
- * @version 1.7.0
951
+ * @modified 2021-12-14 Added the `perimeter()` function.
952
+ * @modified 2021-12-16 Added the `getEvenDistributionPolygon()` function.
953
+ * @version 1.8.0
914
954
  *
915
955
  * @file Polygon
916
956
  * @public
@@ -941,12 +981,11 @@ class Polygon {
941
981
  **/
942
982
  this.className = "Polygon";
943
983
  this.uid = UIDGenerator.next();
944
- if (typeof vertices == 'undefined')
984
+ if (typeof vertices == "undefined")
945
985
  vertices = [];
946
986
  this.vertices = vertices;
947
987
  this.isOpen = isOpen;
948
988
  }
949
- ;
950
989
  /**
951
990
  * Add a vertex to the end of the `vertices` array.
952
991
  *
@@ -958,7 +997,6 @@ class Polygon {
958
997
  addVertex(vert) {
959
998
  this.vertices.push(vert);
960
999
  }
961
- ;
962
1000
  /**
963
1001
  * Get the polygon vertex at the given position (index).
964
1002
  *
@@ -981,7 +1019,6 @@ class Polygon {
981
1019
  else
982
1020
  return this.vertices[index % this.vertices.length];
983
1021
  }
984
- ;
985
1022
  /**
986
1023
  * Move the polygon's vertices by the given amount.
987
1024
  *
@@ -997,7 +1034,6 @@ class Polygon {
997
1034
  }
998
1035
  return this;
999
1036
  }
1000
- ;
1001
1037
  /**
1002
1038
  * Check if the given vertex is inside this polygon.<br>
1003
1039
  * <br>
@@ -1017,14 +1053,12 @@ class Polygon {
1017
1053
  for (var i = 0, j = this.vertices.length - 1; i < this.vertices.length; j = i++) {
1018
1054
  let xi = this.vertices[i].x, yi = this.vertices[i].y;
1019
1055
  let xj = this.vertices[j].x, yj = this.vertices[j].y;
1020
- var intersect = ((yi > vert.y) != (yj > vert.y))
1021
- && (vert.x < (xj - xi) * (vert.y - yi) / (yj - yi) + xi);
1056
+ var intersect = yi > vert.y != yj > vert.y && vert.x < ((xj - xi) * (vert.y - yi)) / (yj - yi) + xi;
1022
1057
  if (intersect)
1023
1058
  inside = !inside;
1024
1059
  }
1025
1060
  return inside;
1026
1061
  }
1027
- ;
1028
1062
  /**
1029
1063
  * Calculate the area of the given polygon (unsigned).
1030
1064
  *
@@ -1038,7 +1072,6 @@ class Polygon {
1038
1072
  area() {
1039
1073
  return Polygon.utils.area(this.vertices);
1040
1074
  }
1041
- ;
1042
1075
  /**
1043
1076
  * Calulate the signed polyon area by interpreting the polygon as a matrix
1044
1077
  * and calculating its determinant.
@@ -1051,7 +1084,6 @@ class Polygon {
1051
1084
  signedArea() {
1052
1085
  return Polygon.utils.signedArea(this.vertices);
1053
1086
  }
1054
- ;
1055
1087
  /**
1056
1088
  * Get the winding order of this polgon: clockwise or counterclockwise.
1057
1089
  *
@@ -1063,7 +1095,28 @@ class Polygon {
1063
1095
  isClockwise() {
1064
1096
  return Polygon.utils.signedArea(this.vertices) < 0;
1065
1097
  }
1066
- ;
1098
+ /**
1099
+ * Get the perimeter of this polygon.
1100
+ * The perimeter is the absolute length of the outline.
1101
+ *
1102
+ * If this polygon is open then the last segment (connecting the first and the
1103
+ * last vertex) will be skipped.
1104
+ *
1105
+ * @method perimeter
1106
+ * @instance
1107
+ * @memberof Polygon
1108
+ * @return {number}
1109
+ */
1110
+ perimeter() {
1111
+ let length = 0;
1112
+ for (var i = 1; i < this.vertices.length; i++) {
1113
+ length += this.vertices[i - 1].distance(this.vertices[i]);
1114
+ }
1115
+ if (!this.isOpen && this.vertices.length > 1) {
1116
+ length += this.vertices[0].distance(this.vertices[this.vertices.length - 1]);
1117
+ }
1118
+ return length;
1119
+ }
1067
1120
  /**
1068
1121
  * Scale the polygon relative to the given center.
1069
1122
  *
@@ -1076,14 +1129,13 @@ class Polygon {
1076
1129
  **/
1077
1130
  scale(factor, center) {
1078
1131
  for (var i in this.vertices) {
1079
- if (typeof this.vertices[i].scale == 'function')
1132
+ if (typeof this.vertices[i].scale == "function")
1080
1133
  this.vertices[i].scale(factor, center);
1081
1134
  else
1082
- console.log('There seems to be a null vertex!', this.vertices[i]);
1135
+ console.log("There seems to be a null vertex!", this.vertices[i]);
1083
1136
  }
1084
1137
  return this;
1085
1138
  }
1086
- ;
1087
1139
  /**
1088
1140
  * Rotate the polygon around the given center.
1089
1141
  *
@@ -1100,7 +1152,52 @@ class Polygon {
1100
1152
  }
1101
1153
  return this;
1102
1154
  }
1103
- ;
1155
+ /**
1156
+ * Convert this polygon into a new polygon with n evenly distributed vertices.
1157
+ *
1158
+ * @param {number} pointCount - Must not be negative.
1159
+ */
1160
+ getEvenDistributionPolygon(pointCount) {
1161
+ if (pointCount <= 0) {
1162
+ throw new Error("pointCount must be larger than zero; is " + pointCount + ".");
1163
+ }
1164
+ const result = new Polygon([], this.isOpen);
1165
+ if (this.vertices.length === 0) {
1166
+ return result;
1167
+ }
1168
+ // Fetch and add the start point from the source polygon
1169
+ let polygonPoint = new Vertex(this.vertices[0]);
1170
+ result.vertices.push(polygonPoint);
1171
+ if (this.vertices.length === 1) {
1172
+ return result;
1173
+ }
1174
+ const perimeter = this.perimeter();
1175
+ const stepSize = perimeter / pointCount;
1176
+ const n = this.vertices.length;
1177
+ let polygonIndex = 1;
1178
+ let nextPolygonPoint = new Vertex(this.vertices[1]);
1179
+ let segmentLength = polygonPoint.distance(nextPolygonPoint);
1180
+ let loopMax = this.isOpen ? n : n + 1;
1181
+ let curSegmentU = stepSize;
1182
+ var i = 1;
1183
+ while (i < pointCount && polygonIndex < loopMax) {
1184
+ // Check if next eq point is inside this segment
1185
+ if (curSegmentU < segmentLength) {
1186
+ let newPoint = polygonPoint.clone().lerpAbs(nextPolygonPoint, curSegmentU);
1187
+ result.vertices.push(newPoint);
1188
+ curSegmentU += stepSize;
1189
+ i++;
1190
+ }
1191
+ else {
1192
+ polygonIndex++;
1193
+ polygonPoint = nextPolygonPoint;
1194
+ nextPolygonPoint = new Vertex(this.vertices[polygonIndex % n]);
1195
+ curSegmentU = curSegmentU - segmentLength;
1196
+ segmentLength = polygonPoint.distance(nextPolygonPoint);
1197
+ }
1198
+ }
1199
+ return result;
1200
+ }
1104
1201
  /**
1105
1202
  * Get the bounding box (bounds) of this polygon.
1106
1203
  *
@@ -1112,7 +1209,6 @@ class Polygon {
1112
1209
  getBounds() {
1113
1210
  return Bounds.computeFromVertices(this.vertices);
1114
1211
  }
1115
- ;
1116
1212
  /**
1117
1213
  * Convert this polygon to a sequence of quadratic Bézier curves.<br>
1118
1214
  * <br>
@@ -1144,7 +1240,6 @@ class Polygon {
1144
1240
  }
1145
1241
  return qbezier;
1146
1242
  }
1147
- ;
1148
1243
  /**
1149
1244
  * Convert this polygon to a quadratic bezier curve, represented as an SVG data string.
1150
1245
  *
@@ -1157,13 +1252,12 @@ class Polygon {
1157
1252
  var qdata = this.toQuadraticBezierData();
1158
1253
  if (qdata.length == 0)
1159
1254
  return "";
1160
- var buffer = ['M ' + qdata[0].x + ' ' + qdata[0].y];
1255
+ var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
1161
1256
  for (var i = 1; i < qdata.length; i += 2) {
1162
- buffer.push('Q ' + qdata[i].x + ' ' + qdata[i].y + ', ' + qdata[i + 1].x + ' ' + qdata[i + 1].y);
1257
+ buffer.push("Q " + qdata[i].x + " " + qdata[i].y + ", " + qdata[i + 1].x + " " + qdata[i + 1].y);
1163
1258
  }
1164
- return buffer.join(' ');
1259
+ return buffer.join(" ");
1165
1260
  }
1166
- ;
1167
1261
  /**
1168
1262
  * Convert this polygon to a sequence of cubic Bézier curves.<br>
1169
1263
  * <br>
@@ -1180,7 +1274,7 @@ class Polygon {
1180
1274
  * @memberof Polygon
1181
1275
  **/
1182
1276
  toCubicBezierData(threshold) {
1183
- if (typeof threshold == 'undefined')
1277
+ if (typeof threshold == "undefined")
1184
1278
  threshold = 1.0;
1185
1279
  if (this.vertices.length < 3)
1186
1280
  return [];
@@ -1204,7 +1298,6 @@ class Polygon {
1204
1298
  }
1205
1299
  return cbezier;
1206
1300
  }
1207
- ;
1208
1301
  /**
1209
1302
  * Convert this polygon to a cubic bezier curve, represented as an SVG data string.
1210
1303
  *
@@ -1217,13 +1310,23 @@ class Polygon {
1217
1310
  var qdata = this.toCubicBezierData(threshold);
1218
1311
  if (qdata.length == 0)
1219
1312
  return "";
1220
- var buffer = ['M ' + qdata[0].x + ' ' + qdata[0].y];
1313
+ var buffer = ["M " + qdata[0].x + " " + qdata[0].y];
1221
1314
  for (var i = 1; i < qdata.length; i += 3) {
1222
- buffer.push('C ' + qdata[i].x + ' ' + qdata[i].y + ', ' + qdata[i + 1].x + ' ' + qdata[i + 1].y + ', ' + qdata[i + 2].x + ' ' + qdata[i + 2].y);
1223
- }
1224
- return buffer.join(' ');
1315
+ buffer.push("C " +
1316
+ qdata[i].x +
1317
+ " " +
1318
+ qdata[i].y +
1319
+ ", " +
1320
+ qdata[i + 1].x +
1321
+ " " +
1322
+ qdata[i + 1].y +
1323
+ ", " +
1324
+ qdata[i + 2].x +
1325
+ " " +
1326
+ qdata[i + 2].y);
1327
+ }
1328
+ return buffer.join(" ");
1225
1329
  }
1226
- ;
1227
1330
  /**
1228
1331
  * Convert this polygon to a cubic bezier path instance.
1229
1332
  *
@@ -1242,7 +1345,6 @@ class Polygon {
1242
1345
  }
1243
1346
  return BezierPath.fromArray(pathdata);
1244
1347
  }
1245
- ;
1246
1348
  /**
1247
1349
  * Create an SVG representation of this polygon.
1248
1350
  *
@@ -1256,29 +1358,28 @@ class Polygon {
1256
1358
  toSVGString(options) {
1257
1359
  options = options || {};
1258
1360
  var buffer = [];
1259
- buffer.push('<path');
1361
+ buffer.push("<path");
1260
1362
  if (options.className)
1261
1363
  buffer.push(' class="' + options.className + '"');
1262
1364
  buffer.push(' d="');
1263
1365
  if (this.vertices.length > 0) {
1264
- buffer.push('M ');
1366
+ buffer.push("M ");
1265
1367
  buffer.push(this.vertices[0].x.toString());
1266
- buffer.push(' ');
1368
+ buffer.push(" ");
1267
1369
  buffer.push(this.vertices[0].y.toString());
1268
1370
  for (var i = 1; i < this.vertices.length; i++) {
1269
- buffer.push(' L ');
1371
+ buffer.push(" L ");
1270
1372
  buffer.push(this.vertices[i].x.toString());
1271
- buffer.push(' ');
1373
+ buffer.push(" ");
1272
1374
  buffer.push(this.vertices[i].y.toString());
1273
1375
  }
1274
1376
  if (!this.isOpen) {
1275
- buffer.push(' Z');
1377
+ buffer.push(" Z");
1276
1378
  }
1277
1379
  }
1278
1380
  buffer.push('" />');
1279
- return buffer.join('');
1381
+ return buffer.join("");
1280
1382
  }
1281
- ;
1282
1383
  }
1283
1384
  Polygon.utils = {
1284
1385
  /**
@@ -1298,8 +1399,8 @@ Polygon.utils = {
1298
1399
  const addY = vertices[(i + 1) % l].y;
1299
1400
  const subX = vertices[(i + 1) % l].x;
1300
1401
  const subY = vertices[i].y;
1301
- total += (addX * addY * 0.5);
1302
- total -= (subX * subY * 0.5);
1402
+ total += addX * addY * 0.5;
1403
+ total -= subX * subY * 0.5;
1303
1404
  }
1304
1405
  return Math.abs(total);
1305
1406
  },
@@ -10332,8 +10433,9 @@ class PlotBoilerplate {
10332
10433
  **/
10333
10434
  getVertexNear(pixelPosition, pixelTolerance) {
10334
10435
  var p = this.locatePointNear(this.transformMousePosition(pixelPosition.x, pixelPosition.y), pixelTolerance / Math.min(this.config.cssScaleX, this.config.cssScaleY));
10335
- if (p && p.typeName == "vertex")
10436
+ if (p && p.typeName == "vertex") {
10336
10437
  return this.vertices[p.vindex];
10438
+ }
10337
10439
  return undefined;
10338
10440
  }
10339
10441
  /**