poly-extrude 0.20.5 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5,5 +5,6 @@ import { expandPaths } from './path';
5
5
  import { expandTubes } from './tube';
6
6
  import { plane } from './plane';
7
7
  import { extrudePolygonsOnPath } from './polygonpath';
8
+ import { polylineOffset } from './polylineoffset';
8
9
  import { isClockwise, merge } from './util';
9
- export { isClockwise, merge, extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane, extrudePolygonsOnPath, polygons };
10
+ export { isClockwise, merge, extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane, extrudePolygonsOnPath, polygons, polylineOffset };
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import { expandPaths } from './path';
5
5
  import { expandTubes } from './tube';
6
6
  import { plane } from './plane';
7
7
  import { extrudePolygonsOnPath } from './polygonpath';
8
+ import { polylineOffset } from './polylineoffset';
8
9
  import { isClockwise, merge } from './util';
9
- export { isClockwise, merge, extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane, extrudePolygonsOnPath, polygons };
10
+ export { isClockwise, merge, extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane, extrudePolygonsOnPath, polygons, polylineOffset };
10
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EACH,WAAW,EAAE,KAAK,EAClB,eAAe,EAAE,gBAAgB,EACjC,aAAa,EAAE,UAAU,EAAE,UAAU,EACrC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EACzC,qBAAqB,EACrB,QAAQ,EACX,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EACH,WAAW,EAAE,KAAK,EAClB,eAAe,EAAE,gBAAgB,EACjC,aAAa,EAAE,UAAU,EAAE,UAAU,EACrC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EACzC,qBAAqB,EACrB,QAAQ,EACR,cAAc,EACjB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * poly-extrude v0.20.5
2
+ * poly-extrude v0.21.0
3
3
  */
4
4
  (function (global, factory) {
5
5
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
@@ -2454,6 +2454,7 @@
2454
2454
  i++;
2455
2455
  continue;
2456
2456
  }
2457
+ let lastRepeat = false;
2457
2458
  // last vertex
2458
2459
  if (i === len - 1) {
2459
2460
  p1 = line[len - 2];
@@ -2478,6 +2479,16 @@
2478
2479
  }
2479
2480
  }
2480
2481
  }
2482
+ if (equal(p1, p2)) {
2483
+ lastRepeat = true;
2484
+ for (let j = line.indexOf(p1); j >= 0; j--) {
2485
+ const p = line[j];
2486
+ if (!equal(p, current)) {
2487
+ p1 = p;
2488
+ break;
2489
+ }
2490
+ }
2491
+ }
2481
2492
  }
2482
2493
  if (equal(p1, p2)) {
2483
2494
  console.error('not find next vertex:index:', i, line);
@@ -2489,7 +2500,7 @@
2489
2500
  let rangle = 0;
2490
2501
  const rad = Math.atan2(dy, dx);
2491
2502
  const angle = radToDeg(rad);
2492
- if (i === 0 || i === len - 1) {
2503
+ if (i === 0 || i === len - 1 || lastRepeat) {
2493
2504
  rangle = angle - 90;
2494
2505
  }
2495
2506
  else {
@@ -4865,6 +4876,196 @@
4865
4876
  mergeArray(indices, indexs);
4866
4877
  }
4867
4878
 
4879
+ function lineEquation(pt1, pt2) {
4880
+ if (pt1.x === pt2.x) {
4881
+ return pt1.y === pt2.y ? null : { x: pt1.x };
4882
+ }
4883
+ var a = (pt2.y - pt1.y) / (pt2.x - pt1.x);
4884
+ return {
4885
+ a: a,
4886
+ b: pt1.y - a * pt1.x,
4887
+ };
4888
+ }
4889
+ function calZ(p1, p2, p) {
4890
+ const dx = p2.x - p1.x, dy = p2.y - p1.y;
4891
+ const distance = Math.sqrt(dx * dx + dy * dy);
4892
+ const dx1 = p.x - p1.x, dy1 = p.y - p1.y;
4893
+ const dis = Math.sqrt(dx1 * dx1 + dy1 * dy1);
4894
+ const percent = dis / distance;
4895
+ const dz = p2.z - p1.z;
4896
+ return p1.z + dz * percent;
4897
+ }
4898
+ /**
4899
+ Return the intersection point of two lines defined by two points each
4900
+ Return null when there's no unique intersection
4901
+ */
4902
+ function intersection(l1a, l1b, l2a, l2b) {
4903
+ var line1 = lineEquation(l1a, l1b);
4904
+ var line2 = lineEquation(l2a, l2b);
4905
+ if (line1 === null || line2 === null) {
4906
+ return null;
4907
+ }
4908
+ if (line1.hasOwnProperty('x')) {
4909
+ if (line2.hasOwnProperty('x')) {
4910
+ return null;
4911
+ }
4912
+ const p = {
4913
+ x: line1.x,
4914
+ y: line2.a * line1.x + line2.b,
4915
+ z: 0
4916
+ };
4917
+ p.z = calZ(l1a, l1b, p);
4918
+ return p;
4919
+ }
4920
+ if (line2.hasOwnProperty('x')) {
4921
+ const p = {
4922
+ x: line2.x,
4923
+ y: line1.a * line2.x + line1.b,
4924
+ z: 0
4925
+ };
4926
+ p.z = calZ(l1a, l1b, p);
4927
+ return p;
4928
+ }
4929
+ if (line1.a === line2.a) {
4930
+ return null;
4931
+ }
4932
+ var x = (line2.b - line1.b) / (line1.a - line2.a);
4933
+ const p = {
4934
+ x: x,
4935
+ y: line1.a * x + line1.b,
4936
+ z: 0
4937
+ };
4938
+ p.z = calZ(l1a, l1b, p);
4939
+ return p;
4940
+ }
4941
+ function translatePoint(pt, dist, heading) {
4942
+ return {
4943
+ x: pt.x + dist * Math.cos(heading),
4944
+ y: pt.y + dist * Math.sin(heading),
4945
+ z: pt.z || 0
4946
+ };
4947
+ }
4948
+ function offsetPointLine(points, distance) {
4949
+ var offsetSegments = [];
4950
+ for (let i = 1, len = points.length; i < len; i++) {
4951
+ let a = points[i - 1], b = points[i];
4952
+ const [x1, y1, z1] = a;
4953
+ const [x2, y2, z2] = b;
4954
+ if (x1 === x2 && y1 === y2) {
4955
+ continue;
4956
+ }
4957
+ a = {
4958
+ x: x1,
4959
+ y: y1,
4960
+ z: z1 || 0
4961
+ };
4962
+ b = {
4963
+ x: x2,
4964
+ y: y2,
4965
+ z: z2 || 0
4966
+ };
4967
+ var segmentAngle = Math.atan2(a.y - b.y, a.x - b.x);
4968
+ var offsetAngle = segmentAngle - Math.PI / 2;
4969
+ offsetSegments.push({
4970
+ offsetAngle: offsetAngle,
4971
+ original: [a, b],
4972
+ offset: [
4973
+ translatePoint(a, distance, offsetAngle),
4974
+ translatePoint(b, distance, offsetAngle)
4975
+ ]
4976
+ });
4977
+ }
4978
+ return offsetSegments;
4979
+ }
4980
+ /**
4981
+ Join 2 line segments defined by 2 points each with a circular arc
4982
+ */
4983
+ function joinSegments(s1, s2, offset) {
4984
+ // TODO: different join styles
4985
+ return circularArc(s1, s2, offset)
4986
+ .filter(function (x) { return x; });
4987
+ }
4988
+ function joinLineSegments(segments, offset) {
4989
+ var joinedPoints = [];
4990
+ var first = segments[0];
4991
+ var last = segments[segments.length - 1];
4992
+ if (first && last) {
4993
+ joinedPoints.push(first.offset[0]);
4994
+ for (let i = 1, len = segments.length; i < len; i++) {
4995
+ let s1 = segments[i - 1], s2 = segments[i];
4996
+ const pts = joinSegments(s1, s2, offset);
4997
+ mergeArray(joinedPoints, pts);
4998
+ }
4999
+ joinedPoints.push(last.offset[1]);
5000
+ }
5001
+ return joinedPoints;
5002
+ }
5003
+ function segmentAsVector(s) {
5004
+ return {
5005
+ x: s[1].x - s[0].x,
5006
+ y: s[1].y - s[0].y,
5007
+ };
5008
+ }
5009
+ function getSignedAngle(s1, s2) {
5010
+ const a = segmentAsVector(s1);
5011
+ const b = segmentAsVector(s2);
5012
+ return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
5013
+ }
5014
+ /**
5015
+ Interpolates points between two offset segments in a circular form
5016
+ */
5017
+ function circularArc(s1, s2, distance) {
5018
+ // if the segments are the same angle,
5019
+ // there should be a single join point
5020
+ if (s1.offsetAngle === s2.offsetAngle) {
5021
+ return [s1.offset[1]];
5022
+ }
5023
+ const signedAngle = getSignedAngle(s1.offset, s2.offset);
5024
+ // for inner angles, just find the offset segments intersection
5025
+ if ((signedAngle * distance > 0) &&
5026
+ (signedAngle * getSignedAngle(s1.offset, [s1.offset[0], s2.offset[1]]) > 0)) {
5027
+ return [intersection(s1.offset[0], s1.offset[1], s2.offset[0], s2.offset[1])];
5028
+ }
5029
+ // draws a circular arc with R = offset distance, C = original meeting point
5030
+ var points = [];
5031
+ var center = s1.original[1];
5032
+ // ensure angles go in the anti-clockwise direction
5033
+ var rightOffset = distance > 0;
5034
+ var startAngle = rightOffset ? s2.offsetAngle : s1.offsetAngle;
5035
+ var endAngle = rightOffset ? s1.offsetAngle : s2.offsetAngle;
5036
+ // and that the end angle is bigger than the start angle
5037
+ if (endAngle < startAngle) {
5038
+ endAngle += Math.PI * 2;
5039
+ }
5040
+ var step = Math.PI / 8;
5041
+ for (var alpha = startAngle; alpha < endAngle; alpha += step) {
5042
+ points.push(translatePoint(center, distance, alpha));
5043
+ }
5044
+ points.push(translatePoint(center, distance, endAngle));
5045
+ return rightOffset ? points.reverse() : points;
5046
+ }
5047
+ function offsetPoints(pts, options) {
5048
+ var offsetSegments = offsetPointLine(pts, options.offset);
5049
+ return joinLineSegments(offsetSegments, options.offset);
5050
+ }
5051
+ function polylineOffset(line, options) {
5052
+ options = Object.assign({ offset: 0 }, options);
5053
+ if (options.offset === 0) {
5054
+ return line;
5055
+ }
5056
+ const pts = offsetPoints(line, options);
5057
+ const result = [];
5058
+ for (let i = 0, len = pts.length; i < len; i++) {
5059
+ const pt = pts[i];
5060
+ if (!pt) {
5061
+ continue;
5062
+ }
5063
+ const { x, y, z } = pt;
5064
+ result.push([x, y, z]);
5065
+ }
5066
+ return result;
5067
+ }
5068
+
4868
5069
  exports.cylinder = cylinder;
4869
5070
  exports.expandLine = expandLine;
4870
5071
  exports.expandPaths = expandPaths;
@@ -4878,6 +5079,7 @@
4878
5079
  exports.merge = merge;
4879
5080
  exports.plane = plane;
4880
5081
  exports.polygons = polygons;
5082
+ exports.polylineOffset = polylineOffset;
4881
5083
 
4882
5084
  Object.defineProperty(exports, '__esModule', { value: true });
4883
5085