poly-extrude 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * poly-extrude v0.0.7
2
+ * poly-extrude v0.1.0
3
3
  */
4
4
  var earcut$2 = {exports: {}};
5
5
 
@@ -32,10 +32,10 @@ function earcut(data, holeIndices, dim) {
32
32
 
33
33
 
34
34
  invSize = Math.max(maxX - minX, maxY - minY);
35
- invSize = invSize !== 0 ? 1 / invSize : 0;
35
+ invSize = invSize !== 0 ? 32767 / invSize : 0;
36
36
  }
37
37
 
38
- earcutLinked(outerNode, triangles, dim, minX, minY, invSize);
38
+ earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
39
39
  return triangles;
40
40
  } // create a circular doubly linked list from polygon points in the specified winding order
41
41
 
@@ -99,9 +99,9 @@ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
99
99
 
100
100
  if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
101
101
  // cut off the triangle
102
- triangles.push(prev.i / dim);
103
- triangles.push(ear.i / dim);
104
- triangles.push(next.i / dim);
102
+ triangles.push(prev.i / dim | 0);
103
+ triangles.push(ear.i / dim | 0);
104
+ triangles.push(next.i / dim | 0);
105
105
  removeNode(ear); // skipping the next vertex leads to less sliver triangles
106
106
 
107
107
  ear = next.next;
@@ -135,10 +135,21 @@ function isEar(ear) {
135
135
  if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
136
136
  // now make sure we don't have other points inside the potential ear
137
137
 
138
- var p = ear.next.next;
139
-
140
- while (p !== ear.prev) {
141
- if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
138
+ var ax = a.x,
139
+ bx = b.x,
140
+ cx = c.x,
141
+ ay = a.y,
142
+ by = b.y,
143
+ cy = c.y; // triangle bbox; min & max are calculated like this for speed
144
+
145
+ var x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx,
146
+ y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy,
147
+ x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx,
148
+ y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
149
+ var p = c.next;
150
+
151
+ while (p !== a) {
152
+ if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
142
153
  p = p.next;
143
154
  }
144
155
 
@@ -150,34 +161,40 @@ function isEarHashed(ear, minX, minY, invSize) {
150
161
  b = ear,
151
162
  c = ear.next;
152
163
  if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
153
- // triangle bbox; min & max are calculated like this for speed
154
164
 
155
- var minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x,
156
- minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y,
157
- maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x,
158
- maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y; // z-order range for the current triangle bbox;
165
+ var ax = a.x,
166
+ bx = b.x,
167
+ cx = c.x,
168
+ ay = a.y,
169
+ by = b.y,
170
+ cy = c.y; // triangle bbox; min & max are calculated like this for speed
171
+
172
+ var x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx,
173
+ y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy,
174
+ x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx,
175
+ y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy; // z-order range for the current triangle bbox;
159
176
 
160
- var minZ = zOrder(minTX, minTY, minX, minY, invSize),
161
- maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);
177
+ var minZ = zOrder(x0, y0, minX, minY, invSize),
178
+ maxZ = zOrder(x1, y1, minX, minY, invSize);
162
179
  var p = ear.prevZ,
163
180
  n = ear.nextZ; // look for points inside the triangle in both directions
164
181
 
165
182
  while (p && p.z >= minZ && n && n.z <= maxZ) {
166
- if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
183
+ if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
167
184
  p = p.prevZ;
168
- if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
185
+ if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
169
186
  n = n.nextZ;
170
187
  } // look for remaining points in decreasing z-order
171
188
 
172
189
 
173
190
  while (p && p.z >= minZ) {
174
- if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
191
+ if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
175
192
  p = p.prevZ;
176
193
  } // look for remaining points in increasing z-order
177
194
 
178
195
 
179
196
  while (n && n.z <= maxZ) {
180
- if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
197
+ if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
181
198
  n = n.nextZ;
182
199
  }
183
200
 
@@ -193,9 +210,9 @@ function cureLocalIntersections(start, triangles, dim) {
193
210
  b = p.next.next;
194
211
 
195
212
  if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
196
- triangles.push(a.i / dim);
197
- triangles.push(p.i / dim);
198
- triangles.push(b.i / dim); // remove two nodes involved
213
+ triangles.push(a.i / dim | 0);
214
+ triangles.push(p.i / dim | 0);
215
+ triangles.push(b.i / dim | 0); // remove two nodes involved
199
216
 
200
217
  removeNode(p);
201
218
  removeNode(p.next);
@@ -224,8 +241,8 @@ function splitEarcut(start, triangles, dim, minX, minY, invSize) {
224
241
  a = filterPoints(a, a.next);
225
242
  c = filterPoints(c, c.next); // run earcut on each half
226
243
 
227
- earcutLinked(a, triangles, dim, minX, minY, invSize);
228
- earcutLinked(c, triangles, dim, minX, minY, invSize);
244
+ earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
245
+ earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
229
246
  return;
230
247
  }
231
248
 
@@ -257,7 +274,6 @@ function eliminateHoles(data, holeIndices, outerNode, dim) {
257
274
 
258
275
  for (i = 0; i < queue.length; i++) {
259
276
  outerNode = eliminateHole(queue[i], outerNode);
260
- outerNode = filterPoints(outerNode, outerNode.next);
261
277
  }
262
278
 
263
279
  return outerNode;
@@ -277,10 +293,8 @@ function eliminateHole(hole, outerNode) {
277
293
 
278
294
  var bridgeReverse = splitPolygon(bridge, hole); // filter collinear points around the cuts
279
295
 
280
- var filteredBridge = filterPoints(bridge, bridge.next);
281
- filterPoints(bridgeReverse, bridgeReverse.next); // Check if input node was removed by the filtering
282
-
283
- return outerNode === bridge ? filteredBridge : outerNode;
296
+ filterPoints(bridgeReverse, bridgeReverse.next);
297
+ return filterPoints(bridge, bridge.next);
284
298
  } // David Eberly's algorithm for finding a bridge between hole and outer polygon
285
299
 
286
300
 
@@ -298,22 +312,15 @@ function findHoleBridge(hole, outerNode) {
298
312
 
299
313
  if (x <= hx && x > qx) {
300
314
  qx = x;
301
-
302
- if (x === hx) {
303
- if (hy === p.y) return p;
304
- if (hy === p.next.y) return p.next;
305
- }
306
-
307
315
  m = p.x < p.next.x ? p : p.next;
316
+ if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint
308
317
  }
309
318
  }
310
319
 
311
320
  p = p.next;
312
321
  } while (p !== outerNode);
313
322
 
314
- if (!m) return null;
315
- if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint
316
- // look for points inside the triangle of hole point, segment intersection and endpoint;
323
+ if (!m) return null; // look for points inside the triangle of hole point, segment intersection and endpoint;
317
324
  // if there are no points found, we have a valid connection;
318
325
  // otherwise choose the point of the minimum angle with the ray as connection point
319
326
 
@@ -350,7 +357,7 @@ function indexCurve(start, minX, minY, invSize) {
350
357
  var p = start;
351
358
 
352
359
  do {
353
- if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);
360
+ if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);
354
361
  p.prevZ = p.prev;
355
362
  p.nextZ = p.next;
356
363
  p = p.next;
@@ -422,8 +429,8 @@ function sortLinked(list) {
422
429
 
423
430
  function zOrder(x, y, minX, minY, invSize) {
424
431
  // coords are transformed into non-negative 15-bit integer range
425
- x = 32767 * (x - minX) * invSize;
426
- y = 32767 * (y - minY) * invSize;
432
+ x = (x - minX) * invSize | 0;
433
+ y = (y - minY) * invSize | 0;
427
434
  x = (x | x << 8) & 0x00FF00FF;
428
435
  x = (x | x << 4) & 0x0F0F0F0F;
429
436
  x = (x | x << 2) & 0x33333333;
@@ -450,7 +457,7 @@ function getLeftmost(start) {
450
457
 
451
458
 
452
459
  function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
453
- return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
460
+ return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
454
461
  } // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
455
462
 
456
463
 
@@ -583,7 +590,7 @@ function Node(i, x, y) {
583
590
  this.prev = null;
584
591
  this.next = null; // z-order curve value
585
592
 
586
- this.z = null; // previous and next nodes in z-order
593
+ this.z = 0; // previous and next nodes in z-order
587
594
 
588
595
  this.prevZ = null;
589
596
  this.nextZ = null; // indicates whether this is a steiner point
@@ -1217,7 +1224,6 @@ var TEMPV1 = {
1217
1224
  x: 0,
1218
1225
  y: 0
1219
1226
  };
1220
-
1221
1227
  function expandLine(line, options) {
1222
1228
  var preAngle = 0;
1223
1229
  var radius = options.lineWidth / 2;
@@ -1330,4 +1336,122 @@ function leftOnLine(p, p1, p2) {
1330
1336
  return (y1 - y2) * x + (x2 - x1) * y + x1 * y2 - x2 * y1 > 0;
1331
1337
  }
1332
1338
 
1333
- export { extrudePolygons, extrudePolylines };
1339
+ function cylinder(point, options) {
1340
+ if (options === void 0) {
1341
+ options = {};
1342
+ }
1343
+
1344
+ options = Object.assign({}, {
1345
+ radius: 1,
1346
+ height: 2,
1347
+ radialSegments: 6
1348
+ }, options);
1349
+ var radialSegments = Math.round(Math.max(4, options.radialSegments));
1350
+ var _options = options,
1351
+ radius = _options.radius,
1352
+ height = _options.height;
1353
+ var aRad = 360 / radialSegments / 360 * Math.PI * 2;
1354
+ var circlePointsLen = radialSegments + 1;
1355
+ var points = new Float32Array(circlePointsLen * 3 * 2);
1356
+ var centerx = point[0],
1357
+ centery = point[1];
1358
+ var idx = 0,
1359
+ uIdx = 0;
1360
+ var offset = circlePointsLen * 3,
1361
+ uOffset = circlePointsLen * 2;
1362
+ var indices = [],
1363
+ uvs = [];
1364
+
1365
+ for (var i = -1; i < radialSegments; i++) {
1366
+ var rad = aRad * i;
1367
+ var x = Math.cos(rad) * radius + centerx,
1368
+ y = Math.sin(rad) * radius + centery; // bottom vertices
1369
+
1370
+ points[idx] = x;
1371
+ points[idx + 1] = y;
1372
+ points[idx + 2] = 0; // top vertices
1373
+
1374
+ points[idx + offset] = x;
1375
+ points[idx + 1 + offset] = y;
1376
+ points[idx + 2 + offset] = height;
1377
+ var u = 0,
1378
+ v = 0;
1379
+ u = 0.5 + x / radius / 2;
1380
+ v = 0.5 + y / radius / 2;
1381
+ uvs[uIdx] = u;
1382
+ uvs[uIdx + 1] = v;
1383
+ uvs[uIdx + uOffset] = u;
1384
+ uvs[uIdx + 1 + uOffset] = v;
1385
+ idx += 3;
1386
+ uIdx += 2;
1387
+
1388
+ if (i > 1) {
1389
+ // bottom indices
1390
+ indices.push(0, i - 1, i);
1391
+ }
1392
+ }
1393
+
1394
+ idx -= 3;
1395
+ points[idx] = points[0];
1396
+ points[idx + 1] = points[1];
1397
+ points[idx + 2] = points[2];
1398
+ var pointsLen = points.length;
1399
+ points[pointsLen - 3] = points[0];
1400
+ points[pointsLen - 2] = points[1];
1401
+ points[pointsLen - 1] = height;
1402
+ var indicesLen = indices.length; // top indices
1403
+
1404
+ for (var _i = 0; _i < indicesLen; _i++) {
1405
+ var index = indices[_i];
1406
+ indices.push(index + circlePointsLen);
1407
+ }
1408
+
1409
+ var sidePoints = new Float32Array((circlePointsLen * 3 * 2 - 6) * 2);
1410
+ var pIndex = -1;
1411
+ idx = circlePointsLen * 2;
1412
+ uIdx = 0;
1413
+
1414
+ for (var _i2 = 0, len = points.length / 2; _i2 < len - 3; _i2 += 3) {
1415
+ var x1 = points[_i2],
1416
+ y1 = points[_i2 + 1],
1417
+ x2 = points[_i2 + 3],
1418
+ y2 = points[_i2 + 4];
1419
+ sidePoints[++pIndex] = x1;
1420
+ sidePoints[++pIndex] = y1;
1421
+ sidePoints[++pIndex] = height;
1422
+ sidePoints[++pIndex] = x2;
1423
+ sidePoints[++pIndex] = y2;
1424
+ sidePoints[++pIndex] = height;
1425
+ sidePoints[++pIndex] = x1;
1426
+ sidePoints[++pIndex] = y1;
1427
+ sidePoints[++pIndex] = 0;
1428
+ sidePoints[++pIndex] = x2;
1429
+ sidePoints[++pIndex] = y2;
1430
+ sidePoints[++pIndex] = 0;
1431
+ var a = idx + 2,
1432
+ b = idx + 3,
1433
+ c = idx,
1434
+ d = idx + 1; // indices.push(a, c, b, c, d, b);
1435
+
1436
+ indices.push(c, a, d, a, b, d);
1437
+ idx += 4;
1438
+ var u1 = uIdx / circlePointsLen,
1439
+ u2 = (uIdx + 1) / circlePointsLen;
1440
+ uvs.push(u1, height / radius / 2, u2, height / radius / 2, u1, 0, u2, 0);
1441
+ uIdx++;
1442
+ }
1443
+
1444
+ var position = new Float32Array(points.length + sidePoints.length);
1445
+ position.set(points, 0);
1446
+ position.set(sidePoints, points.length);
1447
+ var normal = generateNormal(indices, position);
1448
+ return {
1449
+ points: points,
1450
+ indices: new Uint32Array(indices),
1451
+ position: position,
1452
+ normal: normal,
1453
+ uv: new Float32Array(uvs)
1454
+ };
1455
+ }
1456
+
1457
+ export { cylinder, expandLine, extrudePolygons, extrudePolylines };
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  import { extrudePolygons } from './src/polygon';
2
- import { extrudePolylines } from './src/polyline';
3
- export { extrudePolygons, extrudePolylines };
2
+ import { extrudePolylines, expandLine } from './src/polyline';
3
+ import { cylinder } from './src/cylinder';
4
+ export { extrudePolygons, extrudePolylines, expandLine, cylinder };
package/package.json CHANGED
@@ -1,47 +1,47 @@
1
- {
2
- "name": "poly-extrude",
3
- "version": "0.0.7",
4
- "description": "",
5
- "main": "dist/poly-extrude.js",
6
- "module": "dist/poly-extrude.mjs",
7
- "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1",
9
- "lint": "eslint src/**/*.js",
10
- "build": "npm run lint && cross-env NODE_ENV=dev rollup -c"
11
- },
12
- "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/deyihu/poly-extrude.git"
15
- },
16
- "author": "",
17
- "license": "ISC",
18
- "bugs": {
19
- "url": "https://github.com/deyihu/poly-extrude/issues"
20
- },
21
- "homepage": "https://github.com/deyihu/poly-extrude#readme",
22
- "devDependencies": {
23
- "@babel/core": "^7.17.5",
24
- "@babel/preset-env": "^7.16.11",
25
- "@rollup/plugin-babel": "^5.3.0",
26
- "@rollup/plugin-commonjs": "^21.0.1",
27
- "@rollup/plugin-json": "^4.1.0",
28
- "@rollup/plugin-node-resolve": "^13.1.3",
29
- "cross-env": "^5.1.4",
30
- "eslint": "^6.2.2",
31
- "eslint-config-standard": "^14.1.0",
32
- "eslint-plugin-import": "^2.18.2",
33
- "eslint-plugin-node": "^10.0.0",
34
- "eslint-plugin-promise": "^4.2.1",
35
- "eslint-plugin-standard": "^4.0.1",
36
- "rollup": "^2.64.0",
37
- "rollup-plugin-terser": "^7.0.2"
38
- },
39
- "dependencies": {
40
- "earcut": "^2.2.3"
41
- },
42
- "files": [
43
- "dist/",
44
- "src/",
45
- "index.js"
46
- ]
47
- }
1
+ {
2
+ "name": "poly-extrude",
3
+ "version": "0.1.0",
4
+ "description": "",
5
+ "main": "dist/poly-extrude.js",
6
+ "module": "dist/poly-extrude.mjs",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1",
9
+ "lint": "eslint src/**/*.js",
10
+ "build": "npm run lint && cross-env NODE_ENV=dev rollup -c"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/deyihu/poly-extrude.git"
15
+ },
16
+ "author": "",
17
+ "license": "ISC",
18
+ "bugs": {
19
+ "url": "https://github.com/deyihu/poly-extrude/issues"
20
+ },
21
+ "homepage": "https://github.com/deyihu/poly-extrude#readme",
22
+ "devDependencies": {
23
+ "@babel/core": "^7.17.5",
24
+ "@babel/preset-env": "^7.16.11",
25
+ "@rollup/plugin-babel": "^5.3.0",
26
+ "@rollup/plugin-commonjs": "^21.0.1",
27
+ "@rollup/plugin-json": "^4.1.0",
28
+ "@rollup/plugin-node-resolve": "^13.1.3",
29
+ "cross-env": "^5.1.4",
30
+ "eslint": "^6.2.2",
31
+ "eslint-config-standard": "^14.1.0",
32
+ "eslint-plugin-import": "^2.18.2",
33
+ "eslint-plugin-node": "^10.0.0",
34
+ "eslint-plugin-promise": "^4.2.1",
35
+ "eslint-plugin-standard": "^4.0.1",
36
+ "rollup": "^2.64.0",
37
+ "rollup-plugin-terser": "^7.0.2"
38
+ },
39
+ "dependencies": {
40
+ "earcut": "^2.2.4"
41
+ },
42
+ "files": [
43
+ "dist/",
44
+ "src/",
45
+ "index.js"
46
+ ]
47
+ }
package/readme.md ADDED
@@ -0,0 +1,100 @@
1
+ # poly-extrude
2
+
3
+ Extrude polygons/polylines. Born in [maptalks.three](https://github.com/maptalks/maptalks.three) project<br>
4
+ [building](https://deyihu.github.io/poly-extrude/test/building.html)<br>
5
+ ![](./gallery/building.png)<br>
6
+ [buildings](https://deyihu.github.io/poly-extrude/test/buildings.html)<br>
7
+ ![](./gallery/buildings.png)<br>
8
+ [multi-polygon](https://deyihu.github.io/poly-extrude/test/multi-polygon.html)<br>
9
+ ![](./gallery/multi-polygon.png)<br>
10
+ [street](https://deyihu.github.io/poly-extrude/test/street.html)<br>
11
+ ![](./gallery/street.png)<br>
12
+ [line-uv](https://deyihu.github.io/poly-extrude/test/line-uv.html)<br>
13
+ ![](./gallery/line-uv.png)
14
+
15
+ ## install
16
+
17
+ ```sh
18
+ npm i poly-extrude
19
+
20
+ # or
21
+
22
+ yarn add poly-extrude
23
+
24
+ # or
25
+
26
+ pnpm i poly-extrude
27
+ ```
28
+
29
+ ## API
30
+
31
+ ### ESM
32
+
33
+ ```js
34
+ import {extrudePolygons,extrudePolylines} from 'poly-extrude';
35
+ const polygons=[
36
+ //polygon
37
+ [
38
+ //outring
39
+ [[x,y],[x,y],...........],
40
+ //holes
41
+ [[x,y],[x,y],...........],
42
+ ........
43
+
44
+ ],
45
+ //other polygons
46
+ ......
47
+ ]
48
+
49
+ const result = extrudePolygons(polygons,{depth:2});
50
+ const {positon,normal,uv,indices}=result;
51
+ //do something
52
+
53
+ const polylines=[
54
+ // polyline
55
+ [[x,y],[x,y],...........],
56
+ //polyline
57
+ [[x,y],[x,y],...........],
58
+ ];
59
+
60
+ const result = extrudePolylines(polylines,{depth:2,lineWidth:2});
61
+ const {positon,normal,uv,indices}=result;
62
+ //do something
63
+ ```
64
+
65
+ ### CDN
66
+
67
+ ```html
68
+ <script src="https://unpkg.com/poly-extrude/dist/poly-extrude.js"></script>
69
+
70
+ <script>
71
+ const polygons=[
72
+ //polygon
73
+ [
74
+ //outring
75
+ [[x,y],[x,y],...........],
76
+ //holes
77
+ [[x,y],[x,y],...........],
78
+ ........
79
+
80
+ ],
81
+ //other polygons
82
+ ......
83
+ ]
84
+
85
+ const result = polyextrude.extrudePolygons(polygons,{depth:2})
86
+ const {positon,normal,uv,indices}=result;
87
+ //do something
88
+
89
+ const polylines=[
90
+ // polyline
91
+ [[x,y],[x,y],...........],
92
+ //polyline
93
+ [[x,y],[x,y],...........],
94
+ ];
95
+
96
+ const result = polyextrude.extrudePolylines(polylines,{depth:2,lineWidth:2});
97
+ const {positon,normal,uv,indices}=result;
98
+ //do something
99
+ </script>
100
+ ```
@@ -0,0 +1,89 @@
1
+ import { generateNormal } from './util';
2
+
3
+ export function cylinder(point, options = {}) {
4
+ options = Object.assign({}, { radius: 1, height: 2, radialSegments: 6 }, options);
5
+ const radialSegments = Math.round(Math.max(4, options.radialSegments));
6
+ const { radius, height } = options;
7
+ const aRad = 360 / radialSegments / 360 * Math.PI * 2;
8
+ const circlePointsLen = (radialSegments + 1);
9
+ const points = new Float32Array(circlePointsLen * 3 * 2);
10
+ const [centerx, centery] = point;
11
+ let idx = 0, uIdx = 0;
12
+ const offset = circlePointsLen * 3, uOffset = circlePointsLen * 2;
13
+ const indices = [], uvs = [];
14
+ for (let i = -1; i < radialSegments; i++) {
15
+ const rad = aRad * i;
16
+ const x = Math.cos(rad) * radius + centerx, y = Math.sin(rad) * radius + centery;
17
+ // bottom vertices
18
+ points[idx] = x;
19
+ points[idx + 1] = y;
20
+ points[idx + 2] = 0;
21
+
22
+ // top vertices
23
+ points[idx + offset] = x;
24
+ points[idx + 1 + offset] = y;
25
+ points[idx + 2 + offset] = height;
26
+
27
+ let u = 0, v = 0;
28
+ u = 0.5 + x / radius / 2;
29
+ v = 0.5 + y / radius / 2;
30
+ uvs[uIdx] = u;
31
+ uvs[uIdx + 1] = v;
32
+ uvs[uIdx + uOffset] = u;
33
+ uvs[uIdx + 1 + uOffset] = v;
34
+
35
+ idx += 3;
36
+ uIdx += 2;
37
+ if (i > 1) {
38
+ // bottom indices
39
+ indices.push(0, i - 1, i);
40
+ }
41
+ }
42
+ idx -= 3;
43
+ points[idx] = points[0];
44
+ points[idx + 1] = points[1];
45
+ points[idx + 2] = points[2];
46
+ const pointsLen = points.length;
47
+ points[pointsLen - 3] = points[0];
48
+ points[pointsLen - 2] = points[1];
49
+ points[pointsLen - 1] = height;
50
+
51
+ const indicesLen = indices.length;
52
+ // top indices
53
+ for (let i = 0; i < indicesLen; i++) {
54
+ const index = indices[i];
55
+ indices.push(index + circlePointsLen);
56
+ }
57
+
58
+ const sidePoints = new Float32Array((circlePointsLen * 3 * 2 - 6) * 2);
59
+ let pIndex = -1;
60
+ idx = circlePointsLen * 2;
61
+ uIdx = 0;
62
+ for (let i = 0, len = points.length / 2; i < len - 3; i += 3) {
63
+ const x1 = points[i], y1 = points[i + 1], x2 = points[i + 3], y2 = points[i + 4];
64
+ sidePoints[++pIndex] = x1;
65
+ sidePoints[++pIndex] = y1;
66
+ sidePoints[++pIndex] = height;
67
+ sidePoints[++pIndex] = x2;
68
+ sidePoints[++pIndex] = y2;
69
+ sidePoints[++pIndex] = height;
70
+ sidePoints[++pIndex] = x1;
71
+ sidePoints[++pIndex] = y1;
72
+ sidePoints[++pIndex] = 0;
73
+ sidePoints[++pIndex] = x2;
74
+ sidePoints[++pIndex] = y2;
75
+ sidePoints[++pIndex] = 0;
76
+ const a = idx + 2, b = idx + 3, c = idx, d = idx + 1;
77
+ // indices.push(a, c, b, c, d, b);
78
+ indices.push(c, a, d, a, b, d);
79
+ idx += 4;
80
+ const u1 = uIdx / circlePointsLen, u2 = (uIdx + 1) / circlePointsLen;
81
+ uvs.push(u1, height / radius / 2, u2, height / radius / 2, u1, 0, u2, 0);
82
+ uIdx++;
83
+ }
84
+ const position = new Float32Array(points.length + sidePoints.length);
85
+ position.set(points, 0);
86
+ position.set(sidePoints, points.length);
87
+ const normal = generateNormal(indices, position);
88
+ return { points, indices: new Uint32Array(indices), position, normal, uv: new Float32Array(uvs) };
89
+ }
package/src/polyline.js CHANGED
@@ -121,7 +121,7 @@ function generateSides(result, options) {
121
121
 
122
122
  const TEMPV1 = { x: 0, y: 0 }, TEMPV2 = { x: 0, y: 0 };
123
123
 
124
- function expandLine(line, options) {
124
+ export function expandLine(line, options) {
125
125
  let preAngle = 0;
126
126
  const radius = options.lineWidth / 2;
127
127
  const points = [], leftPoints = [], rightPoints = [];