poly-extrude 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { extrudePolygons } from './src/polygon';
2
2
  import { extrudePolylines, expandLine } from './src/polyline';
3
3
  import { cylinder } from './src/cylinder';
4
- export { extrudePolygons, extrudePolylines, expandLine, cylinder };
4
+ import { expandPaths } from './src/path';
5
+ export { extrudePolygons, extrudePolylines, expandLine, cylinder, expandPaths };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poly-extrude",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "",
5
5
  "main": "dist/poly-extrude.js",
6
6
  "module": "dist/poly-extrude.mjs",
package/readme.md CHANGED
@@ -22,6 +22,8 @@ Extrude polygons/polylines. Born in [maptalks.three](https://github.com/maptalks
22
22
  ![](./gallery/brige.png)
23
23
  [spring](https://deyihu.github.io/poly-extrude/test/spring.html)<br>
24
24
  ![](./gallery/spring.png)
25
+ [expand paths](https://deyihu.github.io/poly-extrude/test/expand-paths-brige.html)<br>
26
+ ![](./gallery/expand-paths-brige.png)
25
27
 
26
28
  ## Install
27
29
 
@@ -45,7 +47,8 @@ pnpm i poly-extrude
45
47
  import {
46
48
  extrudePolygons,
47
49
  extrudePolylines,
48
- cylinder
50
+ cylinder,
51
+ expandPaths
49
52
  } from 'poly-extrude';
50
53
  const polygons = [
51
54
  //polygon
@@ -116,6 +119,34 @@ pnpm i poly-extrude
116
119
  indices
117
120
  } = result;
118
121
  //do something
122
+
123
+
124
+
125
+ const polylines = [
126
+ // polyline
127
+ [
128
+ [x, y],
129
+ [x, y], ...........
130
+ ],
131
+ //polyline
132
+ [
133
+ [x, y],
134
+ [x, y], ...........
135
+ ],
136
+ ];
137
+
138
+ const result = expandPaths(polylines, {
139
+ cornerRadius: 0.5,
140
+ lineWidth: 2
141
+ });
142
+ const {
143
+ positon,
144
+ normal,
145
+ uv,
146
+ indices
147
+ } = result;
148
+ //do something
149
+
119
150
  ```
120
151
 
121
152
  ### CDN
@@ -193,5 +224,32 @@ pnpm i poly-extrude
193
224
  indices
194
225
  } = result;
195
226
  //do something
227
+
228
+
229
+
230
+ const polylines = [
231
+ // polyline
232
+ [
233
+ [x, y],
234
+ [x, y], ...........
235
+ ],
236
+ //polyline
237
+ [
238
+ [x, y],
239
+ [x, y], ...........
240
+ ],
241
+ ];
242
+
243
+ const result = polyextrude.expandPaths(polylines, {
244
+ cornerRadius: 0.5,
245
+ lineWidth: 2
246
+ });
247
+ const {
248
+ positon,
249
+ normal,
250
+ uv,
251
+ indices
252
+ } = result;
253
+ //do something
196
254
  </script>
197
255
  ```
@@ -0,0 +1,415 @@
1
+
2
+ // code copy from https://github.com/mrdoob/three.js/blob/dev/src/extras/core/Curve.js
3
+ // import * as MathUtils from '../../math/MathUtils.js';
4
+ // import { Vector2 } from '../../math/Vector2.js';
5
+ // import { Vector3 } from '../../math/Vector3.js';
6
+ // import { Matrix4 } from '../../math/Matrix4.js';
7
+
8
+ /**
9
+ * Extensible curve object.
10
+ *
11
+ * Some common of curve methods:
12
+ * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget )
13
+ * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget )
14
+ * .getPoints(), .getSpacedPoints()
15
+ * .getLength()
16
+ * .updateArcLengths()
17
+ *
18
+ * This following curves inherit from THREE.Curve:
19
+ *
20
+ * -- 2D curves --
21
+ * THREE.ArcCurve
22
+ * THREE.CubicBezierCurve
23
+ * THREE.EllipseCurve
24
+ * THREE.LineCurve
25
+ * THREE.QuadraticBezierCurve
26
+ * THREE.SplineCurve
27
+ *
28
+ * -- 3D curves --
29
+ * THREE.CatmullRomCurve3
30
+ * THREE.CubicBezierCurve3
31
+ * THREE.LineCurve3
32
+ * THREE.QuadraticBezierCurve3
33
+ *
34
+ * A series of curves can be represented as a THREE.CurvePath.
35
+ *
36
+ **/
37
+
38
+ class Curve {
39
+
40
+ constructor() {
41
+
42
+ this.type = 'Curve';
43
+
44
+ this.arcLengthDivisions = 200;
45
+
46
+ }
47
+
48
+ // Virtual base class method to overwrite and implement in subclasses
49
+
50
+ getPoint() {
51
+
52
+ console.warn('THREE.Curve: .getPoint() not implemented.');
53
+ return null;
54
+
55
+ }
56
+
57
+ // Get point at relative position in curve according to arc length
58
+ // - u [0 .. 1]
59
+
60
+ getPointAt(u, optionalTarget) {
61
+
62
+ const t = this.getUtoTmapping(u);
63
+ return this.getPoint(t, optionalTarget);
64
+
65
+ }
66
+
67
+ // Get sequence of points using getPoint( t )
68
+
69
+ getPoints(divisions = 5) {
70
+
71
+ const points = [];
72
+
73
+ for (let d = 0; d <= divisions; d++) {
74
+
75
+ points.push(this.getPoint(d / divisions));
76
+
77
+ }
78
+
79
+ return points;
80
+
81
+ }
82
+
83
+ // // Get sequence of points using getPointAt( u )
84
+
85
+ // getSpacedPoints(divisions = 5) {
86
+
87
+ // const points = [];
88
+
89
+ // for (let d = 0; d <= divisions; d++) {
90
+
91
+ // points.push(this.getPointAt(d / divisions));
92
+
93
+ // }
94
+
95
+ // return points;
96
+
97
+ // }
98
+
99
+ // Get total curve arc length
100
+
101
+ getLength() {
102
+
103
+ const lengths = this.getLengths();
104
+ return lengths[lengths.length - 1];
105
+
106
+ }
107
+
108
+ // Get list of cumulative segment lengths
109
+
110
+ getLengths(divisions = this.arcLengthDivisions) {
111
+
112
+ if (this.cacheArcLengths &&
113
+ (this.cacheArcLengths.length === divisions + 1) &&
114
+ !this.needsUpdate) {
115
+
116
+ return this.cacheArcLengths;
117
+
118
+ }
119
+
120
+ this.needsUpdate = false;
121
+
122
+ const cache = [];
123
+ let current, last = this.getPoint(0);
124
+ let sum = 0;
125
+
126
+ cache.push(0);
127
+
128
+ for (let p = 1; p <= divisions; p++) {
129
+
130
+ current = this.getPoint(p / divisions);
131
+ sum += current.distanceTo(last);
132
+ cache.push(sum);
133
+ last = current;
134
+
135
+ }
136
+
137
+ this.cacheArcLengths = cache;
138
+
139
+ return cache; // { sums: cache, sum: sum }; Sum is in the last element.
140
+
141
+ }
142
+
143
+ // updateArcLengths() {
144
+
145
+ // this.needsUpdate = true;
146
+ // this.getLengths();
147
+
148
+ // }
149
+
150
+ // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
151
+
152
+ getUtoTmapping(u, distance) {
153
+
154
+ const arcLengths = this.getLengths();
155
+
156
+ let i = 0;
157
+ const il = arcLengths.length;
158
+
159
+ let targetArcLength; // The targeted u distance value to get
160
+
161
+ if (distance) {
162
+
163
+ targetArcLength = distance;
164
+
165
+ } else {
166
+
167
+ targetArcLength = u * arcLengths[il - 1];
168
+
169
+ }
170
+
171
+ // binary search for the index with largest value smaller than target u distance
172
+
173
+ let low = 0, high = il - 1, comparison;
174
+
175
+ while (low <= high) {
176
+
177
+ i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
178
+
179
+ comparison = arcLengths[i] - targetArcLength;
180
+
181
+ if (comparison < 0) {
182
+
183
+ low = i + 1;
184
+
185
+ } else if (comparison > 0) {
186
+
187
+ high = i - 1;
188
+
189
+ } else {
190
+
191
+ high = i;
192
+ break;
193
+
194
+ // DONE
195
+
196
+ }
197
+
198
+ }
199
+
200
+ i = high;
201
+
202
+ if (arcLengths[i] === targetArcLength) {
203
+
204
+ return i / (il - 1);
205
+
206
+ }
207
+
208
+ // we could get finer grain at lengths, or use simple interpolation between two points
209
+
210
+ const lengthBefore = arcLengths[i];
211
+ const lengthAfter = arcLengths[i + 1];
212
+
213
+ const segmentLength = lengthAfter - lengthBefore;
214
+
215
+ // determine where we are between the 'before' and 'after' points
216
+
217
+ const segmentFraction = (targetArcLength - lengthBefore) / segmentLength;
218
+
219
+ // add that fractional amount to t
220
+
221
+ const t = (i + segmentFraction) / (il - 1);
222
+
223
+ return t;
224
+
225
+ }
226
+
227
+ // Returns a unit vector tangent at t
228
+ // In case any sub curve does not implement its tangent derivation,
229
+ // 2 points a small delta apart will be used to find its gradient
230
+ // which seems to give a reasonable approximation
231
+
232
+ // getTangent(t, optionalTarget) {
233
+
234
+ // const delta = 0.0001;
235
+ // let t1 = t - delta;
236
+ // let t2 = t + delta;
237
+
238
+ // // Capping in case of danger
239
+
240
+ // if (t1 < 0) t1 = 0;
241
+ // if (t2 > 1) t2 = 1;
242
+
243
+ // const pt1 = this.getPoint(t1);
244
+ // const pt2 = this.getPoint(t2);
245
+
246
+ // const tangent = optionalTarget || ((pt1.isVector2) ? new Vector2() : new Vector3());
247
+
248
+ // tangent.copy(pt2).sub(pt1).normalize();
249
+
250
+ // return tangent;
251
+
252
+ // }
253
+
254
+ // getTangentAt(u, optionalTarget) {
255
+
256
+ // const t = this.getUtoTmapping(u);
257
+ // return this.getTangent(t, optionalTarget);
258
+
259
+ // }
260
+
261
+ // computeFrenetFrames(segments, closed) {
262
+
263
+ // // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
264
+
265
+ // const normal = new Vector3();
266
+
267
+ // const tangents = [];
268
+ // const normals = [];
269
+ // const binormals = [];
270
+
271
+ // const vec = new Vector3();
272
+ // const mat = new Matrix4();
273
+
274
+ // // compute the tangent vectors for each segment on the curve
275
+
276
+ // for (let i = 0; i <= segments; i++) {
277
+
278
+ // const u = i / segments;
279
+
280
+ // tangents[i] = this.getTangentAt(u, new Vector3());
281
+
282
+ // }
283
+
284
+ // // select an initial normal vector perpendicular to the first tangent vector,
285
+ // // and in the direction of the minimum tangent xyz component
286
+
287
+ // normals[0] = new Vector3();
288
+ // binormals[0] = new Vector3();
289
+ // let min = Number.MAX_VALUE;
290
+ // const tx = Math.abs(tangents[0].x);
291
+ // const ty = Math.abs(tangents[0].y);
292
+ // const tz = Math.abs(tangents[0].z);
293
+
294
+ // if (tx <= min) {
295
+
296
+ // min = tx;
297
+ // normal.set(1, 0, 0);
298
+
299
+ // }
300
+
301
+ // if (ty <= min) {
302
+
303
+ // min = ty;
304
+ // normal.set(0, 1, 0);
305
+
306
+ // }
307
+
308
+ // if (tz <= min) {
309
+
310
+ // normal.set(0, 0, 1);
311
+
312
+ // }
313
+
314
+ // vec.crossVectors(tangents[0], normal).normalize();
315
+
316
+ // normals[0].crossVectors(tangents[0], vec);
317
+ // binormals[0].crossVectors(tangents[0], normals[0]);
318
+
319
+ // // compute the slowly-varying normal and binormal vectors for each segment on the curve
320
+
321
+ // for (let i = 1; i <= segments; i++) {
322
+
323
+ // normals[i] = normals[i - 1].clone();
324
+
325
+ // binormals[i] = binormals[i - 1].clone();
326
+
327
+ // vec.crossVectors(tangents[i - 1], tangents[i]);
328
+
329
+ // if (vec.length() > Number.EPSILON) {
330
+
331
+ // vec.normalize();
332
+
333
+ // const theta = Math.acos(MathUtils.clamp(tangents[i - 1].dot(tangents[i]), - 1, 1)); // clamp for floating pt errors
334
+
335
+ // normals[i].applyMatrix4(mat.makeRotationAxis(vec, theta));
336
+
337
+ // }
338
+
339
+ // binormals[i].crossVectors(tangents[i], normals[i]);
340
+
341
+ // }
342
+
343
+ // // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
344
+
345
+ // if (closed === true) {
346
+
347
+ // let theta = Math.acos(MathUtils.clamp(normals[0].dot(normals[segments]), - 1, 1));
348
+ // theta /= segments;
349
+
350
+ // if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) {
351
+
352
+ // theta = - theta;
353
+
354
+ // }
355
+
356
+ // for (let i = 1; i <= segments; i++) {
357
+
358
+ // // twist a little...
359
+ // normals[i].applyMatrix4(mat.makeRotationAxis(tangents[i], theta * i));
360
+ // binormals[i].crossVectors(tangents[i], normals[i]);
361
+
362
+ // }
363
+
364
+ // }
365
+
366
+ // return {
367
+ // tangents: tangents,
368
+ // normals: normals,
369
+ // binormals: binormals
370
+ // };
371
+
372
+ // }
373
+
374
+ // clone() {
375
+
376
+ // return new this.constructor().copy(this);
377
+
378
+ // }
379
+
380
+ // copy(source) {
381
+
382
+ // this.arcLengthDivisions = source.arcLengthDivisions;
383
+
384
+ // return this;
385
+
386
+ // }
387
+
388
+ // toJSON() {
389
+
390
+ // const data = {
391
+ // metadata: {
392
+ // version: 4.6,
393
+ // type: 'Curve',
394
+ // generator: 'Curve.toJSON'
395
+ // }
396
+ // };
397
+
398
+ // data.arcLengthDivisions = this.arcLengthDivisions;
399
+ // data.type = this.type;
400
+
401
+ // return data;
402
+
403
+ // }
404
+
405
+ // fromJSON(json) {
406
+
407
+ // this.arcLengthDivisions = json.arcLengthDivisions;
408
+
409
+ // return this;
410
+
411
+ // }
412
+
413
+ }
414
+
415
+ export { Curve };
@@ -0,0 +1,80 @@
1
+ /**
2
+ * // code copy from https://github.com/mrdoob/three.js/blob/dev/src/extras/core/Interpolations.js
3
+ * Bezier Curves formulas obtained from
4
+ * https://en.wikipedia.org/wiki/B%C3%A9zier_curve
5
+ */
6
+
7
+ function CatmullRom(t, p0, p1, p2, p3) {
8
+
9
+ const v0 = (p2 - p0) * 0.5;
10
+ const v1 = (p3 - p1) * 0.5;
11
+ const t2 = t * t;
12
+ const t3 = t * t2;
13
+ return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
14
+
15
+ }
16
+
17
+ //
18
+
19
+ function QuadraticBezierP0(t, p) {
20
+
21
+ const k = 1 - t;
22
+ return k * k * p;
23
+
24
+ }
25
+
26
+ function QuadraticBezierP1(t, p) {
27
+
28
+ return 2 * (1 - t) * t * p;
29
+
30
+ }
31
+
32
+ function QuadraticBezierP2(t, p) {
33
+
34
+ return t * t * p;
35
+
36
+ }
37
+
38
+ function QuadraticBezier(t, p0, p1, p2) {
39
+
40
+ return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) +
41
+ QuadraticBezierP2(t, p2);
42
+
43
+ }
44
+
45
+ //
46
+
47
+ function CubicBezierP0(t, p) {
48
+
49
+ const k = 1 - t;
50
+ return k * k * k * p;
51
+
52
+ }
53
+
54
+ function CubicBezierP1(t, p) {
55
+
56
+ const k = 1 - t;
57
+ return 3 * k * k * t * p;
58
+
59
+ }
60
+
61
+ function CubicBezierP2(t, p) {
62
+
63
+ return 3 * (1 - t) * t * t * p;
64
+
65
+ }
66
+
67
+ function CubicBezierP3(t, p) {
68
+
69
+ return t * t * t * p;
70
+
71
+ }
72
+
73
+ function CubicBezier(t, p0, p1, p2, p3) {
74
+
75
+ return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) +
76
+ CubicBezierP3(t, p3);
77
+
78
+ }
79
+
80
+ export { CatmullRom, QuadraticBezier, CubicBezier };