poly-extrude 0.20.6 → 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.
@@ -0,0 +1,6 @@
1
+ import { PolylineType } from "./type";
2
+ type polylineOffsetOptions = {
3
+ offset: number;
4
+ };
5
+ export declare function polylineOffset(line: PolylineType, options: polylineOffsetOptions): PolylineType;
6
+ export {};
@@ -0,0 +1,191 @@
1
+ import { mergeArray } from "./util";
2
+ function lineEquation(pt1, pt2) {
3
+ if (pt1.x === pt2.x) {
4
+ return pt1.y === pt2.y ? null : { x: pt1.x };
5
+ }
6
+ var a = (pt2.y - pt1.y) / (pt2.x - pt1.x);
7
+ return {
8
+ a: a,
9
+ b: pt1.y - a * pt1.x,
10
+ };
11
+ }
12
+ function calZ(p1, p2, p) {
13
+ const dx = p2.x - p1.x, dy = p2.y - p1.y;
14
+ const distance = Math.sqrt(dx * dx + dy * dy);
15
+ const dx1 = p.x - p1.x, dy1 = p.y - p1.y;
16
+ const dis = Math.sqrt(dx1 * dx1 + dy1 * dy1);
17
+ const percent = dis / distance;
18
+ const dz = p2.z - p1.z;
19
+ return p1.z + dz * percent;
20
+ }
21
+ /**
22
+ Return the intersection point of two lines defined by two points each
23
+ Return null when there's no unique intersection
24
+ */
25
+ function intersection(l1a, l1b, l2a, l2b) {
26
+ var line1 = lineEquation(l1a, l1b);
27
+ var line2 = lineEquation(l2a, l2b);
28
+ if (line1 === null || line2 === null) {
29
+ return null;
30
+ }
31
+ if (line1.hasOwnProperty('x')) {
32
+ if (line2.hasOwnProperty('x')) {
33
+ return null;
34
+ }
35
+ const p = {
36
+ x: line1.x,
37
+ y: line2.a * line1.x + line2.b,
38
+ z: 0
39
+ };
40
+ p.z = calZ(l1a, l1b, p);
41
+ return p;
42
+ }
43
+ if (line2.hasOwnProperty('x')) {
44
+ const p = {
45
+ x: line2.x,
46
+ y: line1.a * line2.x + line1.b,
47
+ z: 0
48
+ };
49
+ p.z = calZ(l1a, l1b, p);
50
+ return p;
51
+ }
52
+ if (line1.a === line2.a) {
53
+ return null;
54
+ }
55
+ var x = (line2.b - line1.b) / (line1.a - line2.a);
56
+ const p = {
57
+ x: x,
58
+ y: line1.a * x + line1.b,
59
+ z: 0
60
+ };
61
+ p.z = calZ(l1a, l1b, p);
62
+ return p;
63
+ }
64
+ function translatePoint(pt, dist, heading) {
65
+ return {
66
+ x: pt.x + dist * Math.cos(heading),
67
+ y: pt.y + dist * Math.sin(heading),
68
+ z: pt.z || 0
69
+ };
70
+ }
71
+ function offsetPointLine(points, distance) {
72
+ var offsetSegments = [];
73
+ for (let i = 1, len = points.length; i < len; i++) {
74
+ let a = points[i - 1], b = points[i];
75
+ const [x1, y1, z1] = a;
76
+ const [x2, y2, z2] = b;
77
+ if (x1 === x2 && y1 === y2) {
78
+ continue;
79
+ }
80
+ a = {
81
+ x: x1,
82
+ y: y1,
83
+ z: z1 || 0
84
+ };
85
+ b = {
86
+ x: x2,
87
+ y: y2,
88
+ z: z2 || 0
89
+ };
90
+ var segmentAngle = Math.atan2(a.y - b.y, a.x - b.x);
91
+ var offsetAngle = segmentAngle - Math.PI / 2;
92
+ offsetSegments.push({
93
+ offsetAngle: offsetAngle,
94
+ original: [a, b],
95
+ offset: [
96
+ translatePoint(a, distance, offsetAngle),
97
+ translatePoint(b, distance, offsetAngle)
98
+ ]
99
+ });
100
+ }
101
+ return offsetSegments;
102
+ }
103
+ /**
104
+ Join 2 line segments defined by 2 points each with a circular arc
105
+ */
106
+ function joinSegments(s1, s2, offset) {
107
+ // TODO: different join styles
108
+ return circularArc(s1, s2, offset)
109
+ .filter(function (x) { return x; });
110
+ }
111
+ function joinLineSegments(segments, offset) {
112
+ var joinedPoints = [];
113
+ var first = segments[0];
114
+ var last = segments[segments.length - 1];
115
+ if (first && last) {
116
+ joinedPoints.push(first.offset[0]);
117
+ for (let i = 1, len = segments.length; i < len; i++) {
118
+ let s1 = segments[i - 1], s2 = segments[i];
119
+ const pts = joinSegments(s1, s2, offset);
120
+ mergeArray(joinedPoints, pts);
121
+ }
122
+ joinedPoints.push(last.offset[1]);
123
+ }
124
+ return joinedPoints;
125
+ }
126
+ function segmentAsVector(s) {
127
+ return {
128
+ x: s[1].x - s[0].x,
129
+ y: s[1].y - s[0].y,
130
+ };
131
+ }
132
+ function getSignedAngle(s1, s2) {
133
+ const a = segmentAsVector(s1);
134
+ const b = segmentAsVector(s2);
135
+ return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
136
+ }
137
+ /**
138
+ Interpolates points between two offset segments in a circular form
139
+ */
140
+ function circularArc(s1, s2, distance) {
141
+ // if the segments are the same angle,
142
+ // there should be a single join point
143
+ if (s1.offsetAngle === s2.offsetAngle) {
144
+ return [s1.offset[1]];
145
+ }
146
+ const signedAngle = getSignedAngle(s1.offset, s2.offset);
147
+ // for inner angles, just find the offset segments intersection
148
+ if ((signedAngle * distance > 0) &&
149
+ (signedAngle * getSignedAngle(s1.offset, [s1.offset[0], s2.offset[1]]) > 0)) {
150
+ return [intersection(s1.offset[0], s1.offset[1], s2.offset[0], s2.offset[1])];
151
+ }
152
+ // draws a circular arc with R = offset distance, C = original meeting point
153
+ var points = [];
154
+ var center = s1.original[1];
155
+ // ensure angles go in the anti-clockwise direction
156
+ var rightOffset = distance > 0;
157
+ var startAngle = rightOffset ? s2.offsetAngle : s1.offsetAngle;
158
+ var endAngle = rightOffset ? s1.offsetAngle : s2.offsetAngle;
159
+ // and that the end angle is bigger than the start angle
160
+ if (endAngle < startAngle) {
161
+ endAngle += Math.PI * 2;
162
+ }
163
+ var step = Math.PI / 8;
164
+ for (var alpha = startAngle; alpha < endAngle; alpha += step) {
165
+ points.push(translatePoint(center, distance, alpha));
166
+ }
167
+ points.push(translatePoint(center, distance, endAngle));
168
+ return rightOffset ? points.reverse() : points;
169
+ }
170
+ function offsetPoints(pts, options) {
171
+ var offsetSegments = offsetPointLine(pts, options.offset);
172
+ return joinLineSegments(offsetSegments, options.offset);
173
+ }
174
+ export function polylineOffset(line, options) {
175
+ options = Object.assign({ offset: 0 }, options);
176
+ if (options.offset === 0) {
177
+ return line;
178
+ }
179
+ const pts = offsetPoints(line, options);
180
+ const result = [];
181
+ for (let i = 0, len = pts.length; i < len; i++) {
182
+ const pt = pts[i];
183
+ if (!pt) {
184
+ continue;
185
+ }
186
+ const { x, y, z } = pt;
187
+ result.push([x, y, z]);
188
+ }
189
+ return result;
190
+ }
191
+ //# sourceMappingURL=polylineoffset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polylineoffset.js","sourceRoot":"","sources":["../src/polylineoffset.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poly-extrude",
3
- "version": "0.20.6",
3
+ "version": "0.21.0",
4
4
  "description": "extrude polyline/polygon etc",
5
5
  "main": "dist/poly-extrude.js",
6
6
  "module": "dist/poly-extrude.mjs",
package/src/index.ts 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
10
  export {
10
11
  isClockwise, merge,
@@ -12,5 +13,6 @@ export {
12
13
  extrudeSlopes, expandLine, leftOnLine,
13
14
  cylinder, expandPaths, expandTubes, plane,
14
15
  extrudePolygonsOnPath,
15
- polygons
16
+ polygons,
17
+ polylineOffset
16
18
  };
@@ -0,0 +1,233 @@
1
+ import { PolylineType } from "./type";
2
+ import { mergeArray } from "./util";
3
+ //https://github.com/bbecquet/Leaflet.PolylineOffset/blob/master/leaflet.polylineoffset.js
4
+
5
+ /**
6
+ Find the coefficients (a,b) of a line of equation y = a.x + b,
7
+ or the constant x for vertical lines
8
+ Return null if there's no equation possible
9
+ */
10
+ type Point = {
11
+ x: number;
12
+ y: number;
13
+ z: number;
14
+ }
15
+
16
+ function lineEquation(pt1: Point, pt2: Point) {
17
+ if (pt1.x === pt2.x) {
18
+ return pt1.y === pt2.y ? null : { x: pt1.x };
19
+ }
20
+
21
+ var a = (pt2.y - pt1.y) / (pt2.x - pt1.x);
22
+ return {
23
+ a: a,
24
+ b: pt1.y - a * pt1.x,
25
+ };
26
+ }
27
+
28
+ function calZ(p1: Point, p2: Point, p: Point) {
29
+ const dx = p2.x - p1.x, dy = p2.y - p1.y;
30
+ const distance = Math.sqrt(dx * dx + dy * dy);
31
+ const dx1 = p.x - p1.x, dy1 = p.y - p1.y;
32
+ const dis = Math.sqrt(dx1 * dx1 + dy1 * dy1);
33
+ const percent = dis / distance;
34
+ const dz = p2.z - p1.z;
35
+ return p1.z + dz * percent;
36
+ }
37
+
38
+ /**
39
+ Return the intersection point of two lines defined by two points each
40
+ Return null when there's no unique intersection
41
+ */
42
+ function intersection(l1a: Point, l1b: Point, l2a: Point, l2b: Point) {
43
+ var line1 = lineEquation(l1a, l1b);
44
+ var line2 = lineEquation(l2a, l2b);
45
+
46
+ if (line1 === null || line2 === null) {
47
+ return null;
48
+ }
49
+
50
+ if (line1.hasOwnProperty('x')) {
51
+ if (line2.hasOwnProperty('x')) {
52
+ return null;
53
+ }
54
+ const p = {
55
+ x: line1.x,
56
+ y: line2.a * line1.x + line2.b,
57
+ z: 0
58
+ };
59
+ p.z = calZ(l1a, l1b, p);
60
+ return p;
61
+ }
62
+ if (line2.hasOwnProperty('x')) {
63
+ const p = {
64
+ x: line2.x,
65
+ y: line1.a * line2.x + line1.b,
66
+ z: 0
67
+ };
68
+ p.z = calZ(l1a, l1b, p);
69
+ return p;
70
+
71
+ }
72
+
73
+ if (line1.a === line2.a) {
74
+ return null;
75
+ }
76
+
77
+ var x = (line2.b - line1.b) / (line1.a - line2.a);
78
+ const p = {
79
+ x: x,
80
+ y: line1.a * x + line1.b,
81
+ z: 0
82
+ };
83
+ p.z = calZ(l1a, l1b, p);
84
+ return p;
85
+ }
86
+
87
+ function translatePoint(pt: Point, dist: number, heading: number) {
88
+ return {
89
+ x: pt.x + dist * Math.cos(heading),
90
+ y: pt.y + dist * Math.sin(heading),
91
+ z: pt.z || 0
92
+ };
93
+ }
94
+
95
+ function offsetPointLine(points, distance: number) {
96
+ var offsetSegments = [];
97
+ for (let i = 1, len = points.length; i < len; i++) {
98
+ let a = points[i - 1], b = points[i];
99
+ const [x1, y1, z1] = a;
100
+ const [x2, y2, z2] = b;
101
+ if (x1 === x2 && y1 === y2) {
102
+ continue;
103
+ }
104
+ a = {
105
+ x: x1,
106
+ y: y1,
107
+ z: z1 || 0
108
+ };
109
+ b = {
110
+ x: x2,
111
+ y: y2,
112
+ z: z2 || 0
113
+ }
114
+ var segmentAngle = Math.atan2(a.y - b.y, a.x - b.x);
115
+ var offsetAngle = segmentAngle - Math.PI / 2;
116
+
117
+ offsetSegments.push({
118
+ offsetAngle: offsetAngle,
119
+ original: [a, b],
120
+ offset: [
121
+ translatePoint(a, distance, offsetAngle),
122
+ translatePoint(b, distance, offsetAngle)
123
+ ]
124
+ });
125
+ }
126
+ return offsetSegments;
127
+
128
+
129
+ }
130
+
131
+ /**
132
+ Join 2 line segments defined by 2 points each with a circular arc
133
+ */
134
+ function joinSegments(s1, s2, offset) {
135
+ // TODO: different join styles
136
+ return circularArc(s1, s2, offset)
137
+ .filter(function (x) { return x; })
138
+ }
139
+
140
+ function joinLineSegments(segments, offset) {
141
+ var joinedPoints = [];
142
+ var first = segments[0];
143
+ var last = segments[segments.length - 1];
144
+
145
+ if (first && last) {
146
+ joinedPoints.push(first.offset[0]);
147
+ for (let i = 1, len = segments.length; i < len; i++) {
148
+ let s1 = segments[i - 1], s2 = segments[i];
149
+ const pts = joinSegments(s1, s2, offset);
150
+ mergeArray(joinedPoints, pts);
151
+ }
152
+ joinedPoints.push(last.offset[1]);
153
+ }
154
+
155
+ return joinedPoints;
156
+ }
157
+
158
+ function segmentAsVector(s) {
159
+ return {
160
+ x: s[1].x - s[0].x,
161
+ y: s[1].y - s[0].y,
162
+ };
163
+ }
164
+
165
+ function getSignedAngle(s1, s2) {
166
+ const a = segmentAsVector(s1);
167
+ const b = segmentAsVector(s2);
168
+ return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
169
+ }
170
+
171
+ /**
172
+ Interpolates points between two offset segments in a circular form
173
+ */
174
+ function circularArc(s1, s2, distance) {
175
+ // if the segments are the same angle,
176
+ // there should be a single join point
177
+ if (s1.offsetAngle === s2.offsetAngle) {
178
+ return [s1.offset[1]];
179
+ }
180
+
181
+ const signedAngle = getSignedAngle(s1.offset, s2.offset);
182
+ // for inner angles, just find the offset segments intersection
183
+ if ((signedAngle * distance > 0) &&
184
+ (signedAngle * getSignedAngle(s1.offset, [s1.offset[0], s2.offset[1]]) > 0)) {
185
+ return [intersection(s1.offset[0], s1.offset[1], s2.offset[0], s2.offset[1])];
186
+ }
187
+
188
+ // draws a circular arc with R = offset distance, C = original meeting point
189
+ var points = [];
190
+ var center = s1.original[1];
191
+ // ensure angles go in the anti-clockwise direction
192
+ var rightOffset = distance > 0;
193
+ var startAngle = rightOffset ? s2.offsetAngle : s1.offsetAngle;
194
+ var endAngle = rightOffset ? s1.offsetAngle : s2.offsetAngle;
195
+ // and that the end angle is bigger than the start angle
196
+ if (endAngle < startAngle) {
197
+ endAngle += Math.PI * 2;
198
+ }
199
+ var step = Math.PI / 8;
200
+ for (var alpha = startAngle; alpha < endAngle; alpha += step) {
201
+ points.push(translatePoint(center, distance, alpha));
202
+ }
203
+ points.push(translatePoint(center, distance, endAngle));
204
+
205
+ return rightOffset ? points.reverse() : points;
206
+ }
207
+
208
+
209
+ function offsetPoints(pts: PolylineType, options: polylineOffsetOptions) {
210
+ var offsetSegments = offsetPointLine(pts, options.offset);
211
+ return joinLineSegments(offsetSegments, options.offset);
212
+ }
213
+
214
+ type polylineOffsetOptions = {
215
+ offset: number
216
+ }
217
+ export function polylineOffset(line: PolylineType, options: polylineOffsetOptions): PolylineType {
218
+ options = Object.assign({ offset: 0 }, options);
219
+ if (options.offset === 0) {
220
+ return line;
221
+ }
222
+ const pts = offsetPoints(line, options);
223
+ const result = [];
224
+ for (let i = 0, len = pts.length; i < len; i++) {
225
+ const pt = pts[i];
226
+ if (!pt) {
227
+ continue;
228
+ }
229
+ const { x, y, z } = pt;
230
+ result.push([x, y, z]);
231
+ }
232
+ return result;
233
+ }