@jscad/modeling 2.9.3 → 2.9.6

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 (70) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/jscad-modeling.min.js +133 -136
  3. package/package.json +2 -2
  4. package/src/colors/colorize.d.ts +6 -5
  5. package/src/geometries/geom2/type.d.ts +3 -2
  6. package/src/geometries/geom3/applyTransforms.js +1 -2
  7. package/src/geometries/geom3/type.d.ts +3 -2
  8. package/src/geometries/path2/appendPoints.js +3 -12
  9. package/src/geometries/path2/appendPoints.test.js +16 -0
  10. package/src/geometries/path2/concat.js +9 -8
  11. package/src/geometries/path2/concat.test.js +13 -7
  12. package/src/geometries/path2/type.d.ts +3 -2
  13. package/src/geometries/poly3/measureBoundingSphere.d.ts +2 -2
  14. package/src/geometries/poly3/measureBoundingSphere.js +46 -8
  15. package/src/geometries/poly3/measureBoundingSphere.test.js +16 -26
  16. package/src/geometries/poly3/type.d.ts +3 -2
  17. package/src/geometries/types.d.ts +4 -2
  18. package/src/maths/mat4/fromRotation.js +9 -7
  19. package/src/maths/mat4/fromTaitBryanRotation.js +8 -6
  20. package/src/maths/mat4/fromXRotation.js +4 -2
  21. package/src/maths/mat4/fromYRotation.js +4 -2
  22. package/src/maths/mat4/fromZRotation.js +4 -2
  23. package/src/maths/mat4/isMirroring.js +11 -11
  24. package/src/maths/mat4/rotate.js +9 -5
  25. package/src/maths/mat4/rotateX.js +4 -2
  26. package/src/maths/mat4/rotateY.js +4 -2
  27. package/src/maths/mat4/rotateZ.js +4 -2
  28. package/src/maths/mat4/translate.test.js +2 -3
  29. package/src/maths/utils/index.d.ts +1 -0
  30. package/src/maths/utils/index.js +2 -0
  31. package/src/{utils → maths/utils}/trigonometry.d.ts +0 -0
  32. package/src/{utils → maths/utils}/trigonometry.js +1 -1
  33. package/src/{utils → maths/utils}/trigonometry.test.js +0 -0
  34. package/src/maths/vec2/distance.js +1 -1
  35. package/src/maths/vec2/fromAngleRadians.js +4 -2
  36. package/src/maths/vec2/length.js +1 -1
  37. package/src/maths/vec2/length.test.js +0 -10
  38. package/src/maths/vec3/angle.js +2 -2
  39. package/src/maths/vec3/angle.test.js +0 -12
  40. package/src/maths/vec3/distance.js +1 -1
  41. package/src/maths/vec3/length.js +1 -1
  42. package/src/maths/vec3/length.test.js +0 -10
  43. package/src/operations/booleans/intersectGeom2.test.js +69 -0
  44. package/src/operations/booleans/{intersect.test.js → intersectGeom3.test.js} +3 -71
  45. package/src/operations/booleans/subtractGeom2.test.js +72 -0
  46. package/src/operations/booleans/{subtract.test.js → subtractGeom3.test.js} +3 -74
  47. package/src/operations/booleans/trees/PolygonTreeNode.js +2 -2
  48. package/src/operations/booleans/unionGeom2.test.js +166 -0
  49. package/src/operations/booleans/{union.test.js → unionGeom3.test.js} +3 -168
  50. package/src/operations/extrusions/extrudeFromSlices.js +3 -2
  51. package/src/operations/extrusions/extrudeRotate.test.js +42 -42
  52. package/src/operations/extrusions/project.test.js +2 -2
  53. package/src/operations/extrusions/slice/repair.js +62 -0
  54. package/src/operations/modifiers/insertTjunctions.js +34 -35
  55. package/src/operations/modifiers/reTesselateCoplanarPolygons.js +32 -31
  56. package/src/primitives/circle.test.js +7 -0
  57. package/src/primitives/cylinderElliptic.js +4 -2
  58. package/src/primitives/cylinderElliptic.test.js +7 -1
  59. package/src/primitives/ellipse.js +1 -1
  60. package/src/primitives/ellipse.test.js +7 -0
  61. package/src/primitives/ellipsoid.js +1 -1
  62. package/src/primitives/geodesicSphere.js +3 -2
  63. package/src/primitives/roundedCuboid.js +4 -2
  64. package/src/primitives/roundedCylinder.js +1 -1
  65. package/src/primitives/torus.test.js +7 -3
  66. package/src/utils/index.d.ts +0 -1
  67. package/src/utils/index.js +1 -3
  68. package/src/maths/mat4/constants.d.ts +0 -1
  69. package/src/maths/mat4/constants.js +0 -5
  70. package/src/operations/extrusions/slice/repairSlice.js +0 -47
@@ -49,16 +49,16 @@ module.exports={bezier:require("./bezier")};
49
49
  },{"./bezier":13}],17:[function(require,module,exports){
50
50
  const mat4=require("../../maths/mat4"),vec2=require("../../maths/vec2"),applyTransforms=r=>mat4.isIdentity(r.transforms)?r:(r.sides=r.sides.map(s=>{return[vec2.transform(vec2.create(),s[0],r.transforms),vec2.transform(vec2.create(),s[1],r.transforms)]}),r.transforms=mat4.create(),r);module.exports=applyTransforms;
51
51
 
52
- },{"../../maths/mat4":140,"../../maths/vec2":186}],18:[function(require,module,exports){
52
+ },{"../../maths/mat4":139,"../../maths/vec2":186}],18:[function(require,module,exports){
53
53
  const clone=e=>Object.assign({},e);module.exports=clone;
54
54
 
55
55
  },{}],19:[function(require,module,exports){
56
56
  const mat4=require("../../maths/mat4"),create=e=>(void 0===e&&(e=[]),{sides:e,transforms:mat4.create()});module.exports=create;
57
57
 
58
- },{"../../maths/mat4":140}],20:[function(require,module,exports){
58
+ },{"../../maths/mat4":139}],20:[function(require,module,exports){
59
59
  const mat4=require("../../maths/mat4"),vec2=require("../../maths/vec2"),create=require("./create"),fromCompactBinary=e=>{if(0!==e[0])throw new Error("invalid compact binary data");const r=create();r.transforms=mat4.clone(e.slice(1,17));for(let t=21;t<e.length;t+=4){const a=vec2.fromValues(e[t+0],e[t+1]),o=vec2.fromValues(e[t+2],e[t+3]);r.sides.push([a,o])}return e[17]>=0&&(r.color=[e[17],e[18],e[19],e[20]]),r};module.exports=fromCompactBinary;
60
60
 
61
- },{"../../maths/mat4":140,"../../maths/vec2":186,"./create":19}],21:[function(require,module,exports){
61
+ },{"../../maths/mat4":139,"../../maths/vec2":186,"./create":19}],21:[function(require,module,exports){
62
62
  const vec2=require("../../maths/vec2"),create=require("./create"),fromPoints=e=>{if(!Array.isArray(e))throw new Error("the given points must be an array");let r=e.length;if(r<3)throw new Error("the given points must define a closed geometry with three or more points");vec2.equals(e[0],e[r-1])&&--r;const t=[];let o=e[r-1];for(let n=0;n<r;n++){const r=e[n];t.push([vec2.clone(o),vec2.clone(r)]),o=r}return create(t)};module.exports=fromPoints;
63
63
 
64
64
  },{"../../maths/vec2":186,"./create":19}],22:[function(require,module,exports){
@@ -88,22 +88,22 @@ const vec2=require("../../maths/vec2"),toSides=require("./toSides"),toString=e=>
88
88
  },{"../../maths/vec2":186,"./toSides":28}],30:[function(require,module,exports){
89
89
  const mat4=require("../../maths/mat4"),transform=(t,r)=>{const s=mat4.multiply(mat4.create(),t,r.transforms);return Object.assign({},r,{transforms:s})};module.exports=transform;
90
90
 
91
- },{"../../maths/mat4":140}],31:[function(require,module,exports){
91
+ },{"../../maths/mat4":139}],31:[function(require,module,exports){
92
92
  const vec2=require("../../maths/vec2"),isA=require("./isA"),toOutlines=require("./toOutlines"),validate=e=>{if(!isA(e))throw new Error("invalid geom2 structure");if(toOutlines(e),e.sides.forEach(e=>{if(vec2.equals(e[0],e[1]))throw new Error(`geom2 self-edge ${e[0]}`)}),!e.transforms.every(Number.isFinite))throw new Error(`geom2 invalid transforms ${e.transforms}`)};module.exports=validate;
93
93
 
94
94
  },{"../../maths/vec2":186,"./isA":23,"./toOutlines":26}],32:[function(require,module,exports){
95
95
  const mat4=require("../../maths/mat4"),poly3=require("../poly3"),applyTransforms=r=>mat4.isIdentity(r.transforms)?r:(r.polygons=r.polygons.map(s=>poly3.transform(r.transforms,s)),r.transforms=mat4.create(),r);module.exports=applyTransforms;
96
96
 
97
- },{"../../maths/mat4":140,"../poly3":75}],33:[function(require,module,exports){
97
+ },{"../../maths/mat4":139,"../poly3":75}],33:[function(require,module,exports){
98
98
  const clone=e=>Object.assign({},e);module.exports=clone;
99
99
 
100
100
  },{}],34:[function(require,module,exports){
101
101
  const mat4=require("../../maths/mat4"),create=e=>(void 0===e&&(e=[]),{polygons:e,transforms:mat4.create()});module.exports=create;
102
102
 
103
- },{"../../maths/mat4":140}],35:[function(require,module,exports){
103
+ },{"../../maths/mat4":139}],35:[function(require,module,exports){
104
104
  const vec3=require("../../maths/vec3"),mat4=require("../../maths/mat4"),poly3=require("../poly3"),create=require("./create"),fromCompactBinary=e=>{if(1!==e[0])throw new Error("invalid compact binary data");const r=create();r.transforms=mat4.clone(e.slice(1,17));const o=e[21];let t=22,a=e.length-3*o;for(;a<e.length;){const o=e[t];t++;const c=[];for(let r=0;r<o;r++)c.push(vec3.fromValues(e[a],e[a+1],e[a+2])),a+=3;r.polygons.push(poly3.create(c))}return e[17]>=0&&(r.color=[e[17],e[18],e[19],e[20]]),r};module.exports=fromCompactBinary;
105
105
 
106
- },{"../../maths/mat4":140,"../../maths/vec3":217,"../poly3":75,"./create":34}],36:[function(require,module,exports){
106
+ },{"../../maths/mat4":139,"../../maths/vec3":217,"../poly3":75,"./create":34}],36:[function(require,module,exports){
107
107
  const poly3=require("../poly3"),create=require("./create"),fromPoints=r=>{if(!Array.isArray(r))throw new Error("the given points must be an array");const e=r.map((r,e)=>{return poly3.create(r)});return create(e)};module.exports=fromPoints;
108
108
 
109
109
  },{"../poly3":75,"./create":34}],37:[function(require,module,exports){
@@ -130,7 +130,7 @@ const poly3=require("../poly3"),toPolygons=require("./toPolygons"),toString=o=>{
130
130
  },{"../poly3":75,"./toPolygons":42}],44:[function(require,module,exports){
131
131
  const mat4=require("../../maths/mat4"),transform=(t,r)=>{const s=mat4.multiply(mat4.create(),t,r.transforms);return Object.assign({},r,{transforms:s})};module.exports=transform;
132
132
 
133
- },{"../../maths/mat4":140}],45:[function(require,module,exports){
133
+ },{"../../maths/mat4":139}],45:[function(require,module,exports){
134
134
  const poly3=require("../poly3"),isA=require("./isA"),validate=e=>{if(!isA(e))throw new Error("invalid geom3 structure");if(e.polygons.forEach(poly3.validate),validateManifold(e),!e.transforms.every(Number.isFinite))throw new Error(`geom3 invalid transforms ${e.transforms}`)},validateManifold=e=>{const o=new Map;e.polygons.forEach(({vertices:e})=>{e.forEach((r,n)=>{const t=`${`${r}`}/${`${e[(n+1)%e.length]}`}`,i=o.has(t)?o.get(t):0;o.set(t,i+1)})});const r=[];if(o.forEach((e,n)=>{const t=n.split("/").reverse().join("/");e!==o.get(t)&&r.push(n.replace("/"," -> "))}),r.length>0)throw new Error(`non-manifold edges ${r.length}\n${r.join("\n")}`)};module.exports=validate;
135
135
 
136
136
  },{"../poly3":75,"./isA":39}],46:[function(require,module,exports){
@@ -143,30 +143,30 @@ const vec2=require("../../maths/vec2"),fromPoints=require("./fromPoints"),toPoin
143
143
  const vec2=require("../../maths/vec2"),vec3=require("../../maths/vec2"),appendPoints=require("./appendPoints"),toPoints=require("./toPoints"),appendBezier=(e,t)=>{let{controlPoints:o,segments:r}=Object.assign({},{segments:16},e);if(!Array.isArray(o))throw new Error("controlPoints must be an array of one or more points");if(o.length<1)throw new Error("controlPoints must be an array of one or more points");if(r<4)throw new Error("segments must be four or more");if(t.isClosed)throw new Error("the given geometry cannot be closed");const n=toPoints(t);if(n.length<1)throw new Error("the given path must contain one or more points (as the starting point for the bezier curve)");if(null===(o=o.slice())[0]){if(o.length<2)throw new Error("a null control point must be passed with one more control points");let e=n[n.length-2];if("lastBezierControlPoint"in t&&(e=t.lastBezierControlPoint),!Array.isArray(e))throw new Error("the given path must contain TWO or more points if given a null control point");const r=vec2.scale(vec2.create(),n[n.length-1],2);vec2.subtract(r,r,e),o[0]=r}o.unshift(n[n.length-1]);const s=o.length-1,i=[];let c=1;for(let e=0;e<=s;++e)e>0&&(c*=e),i.push(c);const a=[];for(let e=0;e<=s;++e){const t=i[s]/(i[e]*i[s-e]);a.push(t)}const l=vec2.create(),h=vec2.create(),p=vec3.create(),u=e=>{let t=1,r=Math.pow(1-e,s);const n=1!==e?1/(1-e):1,i=vec2.create();for(let c=0;c<=s;++c){c===s&&(r=1);const h=a[c]*t*r,p=vec2.scale(l,o[c],h);vec2.add(i,i,p),t*=e,r*=n}return i},v=[],f=[],m=s+1;for(let e=0;e<m;++e){const t=e/(m-1),o=u(t);v.push(o),f.push(t)}let g=1;const w=2*Math.PI/r,P=Math.sin(w);for(;g<v.length-1;){const e=vec2.subtract(l,v[g],v[g-1]);vec2.normalize(e,e);const t=vec2.subtract(h,v[g+1],v[g]);vec2.normalize(t,t);const o=vec2.cross(p,e,t);if(Math.abs(o[2])>P){const e=f[g-1],t=f[g+1],o=e+1*(t-e)/3,r=e+2*(t-e)/3,n=u(o),s=u(r);v.splice(g,1,n,s),f.splice(g,1,o,r),--g<1&&(g=1)}else++g}v.shift();const b=appendPoints(v,t);return b.lastBezierControlPoint=o[o.length-2],b};module.exports=appendBezier;
144
144
 
145
145
  },{"../../maths/vec2":186,"./appendPoints":49,"./toPoints":62}],49:[function(require,module,exports){
146
- const fromPoints=require("./fromPoints"),toPoints=require("./toPoints"),appendPoints=(o,t)=>{if(t.isClosed)throw new Error("cannot append points to a closed path");let n=toPoints(t);return n=n.concat(o),fromPoints({},n)};module.exports=appendPoints;
146
+ const concat=require("./concat"),create=require("./create"),appendPoints=(e,c)=>concat(c,create(e));module.exports=appendPoints;
147
147
 
148
- },{"./fromPoints":57,"./toPoints":62}],50:[function(require,module,exports){
148
+ },{"./concat":53,"./create":54}],50:[function(require,module,exports){
149
149
  const mat4=require("../../maths/mat4"),vec2=require("../../maths/vec2"),applyTransforms=r=>mat4.isIdentity(r.transforms)?r:(r.points=r.points.map(s=>vec2.transform(vec2.create(),s,r.transforms)),r.transforms=mat4.create(),r);module.exports=applyTransforms;
150
150
 
151
- },{"../../maths/mat4":140,"../../maths/vec2":186}],51:[function(require,module,exports){
151
+ },{"../../maths/mat4":139,"../../maths/vec2":186}],51:[function(require,module,exports){
152
152
  const clone=e=>Object.assign({},e);module.exports=clone;
153
153
 
154
154
  },{}],52:[function(require,module,exports){
155
155
  const{EPS:EPS}=require("../../maths/constants"),vec2=require("../../maths/vec2"),clone=require("./clone"),close=e=>{if(e.isClosed)return e;const t=clone(e);if(t.isClosed=!0,t.points.length>1){const e=t.points,n=e[0];let o=e[e.length-1];for(;vec2.distance(n,o)<EPS*EPS&&(e.pop(),1!==e.length);)o=e[e.length-1]}return t};module.exports=close;
156
156
 
157
157
  },{"../../maths/constants":90,"../../maths/vec2":186,"./clone":51}],53:[function(require,module,exports){
158
- const fromPoints=require("./fromPoints"),toPoints=require("./toPoints"),{equals:equals}=require("../../maths/vec2"),concat=(...o)=>{let t=!1;for(const e of o){if(t)throw new Error("Cannot concatenate to a closed path");t=e.isClosed}let e=[];return o.forEach(o=>{const t=toPoints(o);e.length>0&&t.length>0&&equals(t[0],e[e.length-1])&&t.shift(),e=e.concat(t)}),fromPoints({closed:t},e)};module.exports=concat;
158
+ const fromPoints=require("./fromPoints"),toPoints=require("./toPoints"),{equals:equals}=require("../../maths/vec2"),concat=(...t)=>{let o=!1,e=[];return t.forEach((t,n)=>{const s=toPoints(t).slice();if(e.length>0&&s.length>0&&equals(s[0],e[e.length-1])&&s.shift(),s.length>0&&o)throw new Error(`Cannot concatenate to a closed path; check the ${n}th path`);o=t.isClosed,e=e.concat(s)}),fromPoints({closed:o},e)};module.exports=concat;
159
159
 
160
160
  },{"../../maths/vec2":186,"./fromPoints":57,"./toPoints":62}],54:[function(require,module,exports){
161
161
  const mat4=require("../../maths/mat4"),create=e=>(void 0===e&&(e=[]),{points:e,isClosed:!1,transforms:mat4.create()});module.exports=create;
162
162
 
163
- },{"../../maths/mat4":140}],55:[function(require,module,exports){
163
+ },{"../../maths/mat4":139}],55:[function(require,module,exports){
164
164
  const vec2=require("../../maths/vec2"),toPoints=require("./toPoints"),equals=(e,t)=>{if(e.isClosed!==t.isClosed)return!1;if(e.points.length!==t.points.length)return!1;const o=toPoints(e),s=toPoints(t),i=o.length;let r=0;do{let t=!1;for(let e=0;e<i;e++)if(!vec2.equals(o[e],s[(e+r)%i])){t=!0;break}if(!1===t)return!0;if(!e.isClosed)return!1}while(++r<i);return!1};module.exports=equals;
165
165
 
166
166
  },{"../../maths/vec2":186,"./toPoints":62}],56:[function(require,module,exports){
167
167
  const mat4=require("../../maths/mat4"),vec2=require("../../maths/vec2"),create=require("./create"),fromCompactBinary=r=>{if(2!==r[0])throw new Error("invalid compact binary data");const e=create();e.transforms=mat4.clone(r.slice(1,17)),e.isClosed=!!r[17];for(let t=22;t<r.length;t+=2){const o=vec2.fromValues(r[t],r[t+1]);e.points.push(o)}return r[18]>=0&&(e.color=[r[18],r[19],r[20],r[21]]),e};module.exports=fromCompactBinary;
168
168
 
169
- },{"../../maths/mat4":140,"../../maths/vec2":186,"./create":54}],57:[function(require,module,exports){
169
+ },{"../../maths/mat4":139,"../../maths/vec2":186,"./create":54}],57:[function(require,module,exports){
170
170
  const{EPS:EPS}=require("../../maths/constants"),vec2=require("../../maths/vec2"),close=require("./close"),create=require("./create"),fromPoints=(e,t)=>{let{closed:s}=Object.assign({},{closed:!1},e),o=create();if(o.points=t.map(e=>vec2.clone(e)),o.points.length>1){const e=o.points[0],t=o.points[o.points.length-1];vec2.distance(e,t)<EPS*EPS&&(s=!0)}return!0===s&&(o=close(o)),o};module.exports=fromPoints;
171
171
 
172
172
  },{"../../maths/constants":90,"../../maths/vec2":186,"./close":52,"./create":54}],58:[function(require,module,exports){
@@ -190,7 +190,7 @@ const vec2=require("../../maths/vec2"),toPoints=require("./toPoints"),toString=t
190
190
  },{"../../maths/vec2":186,"./toPoints":62}],64:[function(require,module,exports){
191
191
  const mat4=require("../../maths/mat4"),transform=(t,r)=>{const s=mat4.multiply(mat4.create(),t,r.transforms);return Object.assign({},r,{transforms:s})};module.exports=transform;
192
192
 
193
- },{"../../maths/mat4":140}],65:[function(require,module,exports){
193
+ },{"../../maths/mat4":139}],65:[function(require,module,exports){
194
194
  const vec2=require("../../maths/vec2"),isA=require("./isA"),validate=r=>{if(!isA(r))throw new Error("invalid path2 structure");if(r.points.length>1)for(let i=0;i<r.points.length;i++)if(vec2.equals(r.points[i],r.points[(i+1)%r.points.length]))throw new Error(`path2 duplicate points ${r.points[i]}`);if(r.points.forEach(r=>{if(!r.every(Number.isFinite))throw new Error(`path2 invalid point ${r}`)}),!r.transforms.every(Number.isFinite))throw new Error(`path2 invalid transforms ${r.transforms}`)};module.exports=validate;
195
195
 
196
196
  },{"../../maths/vec2":186,"./isA":59}],66:[function(require,module,exports){
@@ -208,7 +208,7 @@ module.exports={arePointsInside:require("./arePointsInside"),create:require("./c
208
208
  },{"./arePointsInside":66,"./create":67,"./flip":68,"./measureArea":70}],70:[function(require,module,exports){
209
209
  const area=require("../../maths/utils/area"),measureArea=e=>area(e.vertices);module.exports=measureArea;
210
210
 
211
- },{"../../maths/utils/area":164}],71:[function(require,module,exports){
211
+ },{"../../maths/utils/area":163}],71:[function(require,module,exports){
212
212
  const create=require("./create"),vec3=require("../../maths/vec3"),clone=(...e)=>{let c,r;return 1===e.length?(c=create(),r=e[0]):(c=e[0],r=e[1]),c.vertices=r.vertices.map(e=>vec3.clone(e)),c};module.exports=clone;
213
213
 
214
214
  },{"../../maths/vec3":217,"./create":72}],72:[function(require,module,exports){
@@ -226,28 +226,28 @@ module.exports={clone:require("./clone"),create:require("./create"),fromPoints:r
226
226
  },{"./clone":71,"./create":72,"./fromPoints":73,"./fromPointsAndPlane":74,"./invert":76,"./isA":77,"./isConvex":78,"./measureArea":79,"./measureBoundingBox":80,"./measureBoundingSphere":81,"./measureSignedVolume":82,"./plane":83,"./toPoints":84,"./toString":85,"./transform":86,"./validate":87}],76:[function(require,module,exports){
227
227
  const plane=require("../../maths/plane"),create=require("./create"),invert=e=>{const r=e.vertices.slice().reverse(),a=create(r);return e.plane&&(a.plane=plane.flip(plane.create(),e.plane)),a};module.exports=invert;
228
228
 
229
- },{"../../maths/plane":159,"./create":72}],77:[function(require,module,exports){
229
+ },{"../../maths/plane":158,"./create":72}],77:[function(require,module,exports){
230
230
  const isA=e=>!!(e&&"object"==typeof e&&"vertices"in e&&Array.isArray(e.vertices));module.exports=isA;
231
231
 
232
232
  },{}],78:[function(require,module,exports){
233
233
  const plane=require("../../maths/plane"),vec3=require("../../maths/vec3"),isConvex=e=>areVerticesConvex(e.vertices),areVerticesConvex=e=>{const t=e.length;if(t>2){const r=plane.fromPoints(plane.create(),...e);let c=e[t-2],n=e[t-1];for(let o=0;o<t;o++){const t=e[o];if(!isConvexPoint(c,n,t,r))return!1;c=n,n=t}}return!0},isConvexPoint=(e,t,r,c)=>{const n=vec3.cross(vec3.create(),vec3.subtract(vec3.create(),t,e),vec3.subtract(vec3.create(),r,t));return vec3.dot(n,c)>=0};module.exports=isConvex;
234
234
 
235
- },{"../../maths/plane":159,"../../maths/vec3":217}],79:[function(require,module,exports){
235
+ },{"../../maths/plane":158,"../../maths/vec3":217}],79:[function(require,module,exports){
236
236
  const plane=require("./plane"),measureArea=e=>{const r=e.vertices.length;if(r<3)return 0;const a=e.vertices,t=plane(e),s=Math.abs(t[0]),n=Math.abs(t[1]),c=Math.abs(t[2]);if(s+n+c===0)return 0;let l=3;s>n&&s>c?l=1:n>c&&(l=2);let o=0,u=0,f=1,i=2;switch(l){case 1:for(f=1;f<r;f++)u=f-1,i=(f+1)%r,o+=a[f][1]*(a[i][2]-a[u][2]);o+=a[0][1]*(a[1][2]-a[r-1][2]),o/=2*t[0];break;case 2:for(f=1;f<r;f++)u=f-1,i=(f+1)%r,o+=a[f][2]*(a[i][0]-a[u][0]);o+=a[0][2]*(a[1][0]-a[r-1][0]),o/=2*t[1];break;case 3:default:for(f=1;f<r;f++)u=f-1,i=(f+1)%r,o+=a[f][0]*(a[i][1]-a[u][1]);o+=a[0][0]*(a[1][1]-a[r-1][1]),o/=2*t[2]}return o};module.exports=measureArea;
237
237
 
238
238
  },{"./plane":83}],80:[function(require,module,exports){
239
239
  const vec3=require("../../maths/vec3"),measureBoundingBox=e=>{const c=e.vertices,n=c.length,o=0===n?vec3.create():vec3.clone(c[0]),r=vec3.clone(o);for(let e=1;e<n;e++)vec3.min(o,o,c[e]),vec3.max(r,r,c[e]);return[o,r]};module.exports=measureBoundingBox;
240
240
 
241
241
  },{"../../maths/vec3":217}],81:[function(require,module,exports){
242
- const vec3=require("../../maths/vec3"),measureBoundingBox=require("./measureBoundingBox"),measureBoundingSphere=e=>{const n=measureBoundingBox(e),r=n[0];return vec3.add(r,n[0],n[1]),vec3.scale(r,r,.5),[r,vec3.distance(r,n[1])]};module.exports=measureBoundingSphere;
242
+ const vec3=require("../../maths/vec3"),vec4=require("../../maths/vec4"),cache=new WeakMap,measureBoundingSphere=e=>{let r=cache.get(e);if(r)return r;const t=e.vertices,c=vec4.create();if(0===t.length)return c[0]=0,c[1]=0,c[2]=0,c[3]=0,c;let a=t[0],n=a,s=a,h=a,u=a,o=a;t.forEach(e=>{a[0]>e[0]&&(a=e),n[1]>e[1]&&(n=e),s[2]>e[2]&&(s=e),h[0]<e[0]&&(h=e),u[1]<e[1]&&(u=e),o[2]<e[2]&&(o=e)}),c[0]=.5*(a[0]+h[0]),c[1]=.5*(n[1]+u[1]),c[2]=.5*(s[2]+o[2]);const i=c[0]-h[0],v=c[1]-u[1],m=c[2]-o[2];return c[3]=Math.sqrt(i*i+v*v+m*m),cache.set(e,c),c};module.exports=measureBoundingSphere;
243
243
 
244
- },{"../../maths/vec3":217,"./measureBoundingBox":80}],82:[function(require,module,exports){
244
+ },{"../../maths/vec3":217,"../../maths/vec4":243}],82:[function(require,module,exports){
245
245
  const vec3=require("../../maths/vec3"),measureSignedVolume=e=>{let r=0;const t=e.vertices,c=vec3.create();for(let e=0;e<t.length-2;e++)vec3.cross(c,t[e+1],t[e+2]),r+=vec3.dot(t[0],c);return r/=6};module.exports=measureSignedVolume;
246
246
 
247
247
  },{"../../maths/vec3":217}],83:[function(require,module,exports){
248
248
  const mplane=require("../../maths/plane/"),plane=e=>(e.plane||(e.plane=mplane.fromPoints(mplane.create(),...e.vertices)),e.plane);module.exports=plane;
249
249
 
250
- },{"../../maths/plane/":159}],84:[function(require,module,exports){
250
+ },{"../../maths/plane/":158}],84:[function(require,module,exports){
251
251
  const toPoints=o=>o.vertices;module.exports=toPoints;
252
252
 
253
253
  },{}],85:[function(require,module,exports){
@@ -256,22 +256,22 @@ const vec3=require("../../maths/vec3/"),toString=e=>{let t="poly3: vertices: [";
256
256
  },{"../../maths/vec3/":217}],86:[function(require,module,exports){
257
257
  const mat4=require("../../maths/mat4"),vec3=require("../../maths/vec3"),create=require("./create"),transform=(e,r)=>{const t=r.vertices.map(r=>vec3.transform(vec3.create(),r,e));return mat4.isMirroring(e)&&t.reverse(),create(t)};module.exports=transform;
258
258
 
259
- },{"../../maths/mat4":140,"../../maths/vec3":217,"./create":72}],87:[function(require,module,exports){
259
+ },{"../../maths/mat4":139,"../../maths/vec3":217,"./create":72}],87:[function(require,module,exports){
260
260
  const signedDistanceToPoint=require("../../maths/plane/signedDistanceToPoint"),{NEPS:NEPS}=require("../../maths/constants"),vec3=require("../../maths/vec3"),isA=require("./isA"),isConvex=require("./isConvex"),measureArea=require("./measureArea"),plane=require("./plane"),validate=e=>{if(!isA(e))throw new Error("invalid poly3 structure");if(e.vertices.length<3)throw new Error(`poly3 not enough vertices ${e.vertices.length}`);if(measureArea(e)<=0)throw new Error("poly3 area must be greater than zero");for(let r=0;r<e.vertices.length;r++)if(vec3.equals(e.vertices[r],e.vertices[(r+1)%e.vertices.length]))throw new Error(`poly3 duplicate vertex ${e.vertices[r]}`);if(!isConvex(e))throw new Error("poly3 must be convex");if(e.vertices.forEach(e=>{if(!e.every(Number.isFinite))throw new Error(`poly3 invalid vertex ${e}`)}),e.vertices.length>3){const r=plane(e);e.vertices.forEach(e=>{const t=Math.abs(signedDistanceToPoint(r,e));if(t>NEPS)throw new Error(`poly3 must be coplanar: vertex ${e} distance ${t}`)})}};module.exports=validate;
261
261
 
262
- },{"../../maths/constants":90,"../../maths/plane/signedDistanceToPoint":161,"../../maths/vec3":217,"./isA":77,"./isConvex":78,"./measureArea":79,"./plane":83}],88:[function(require,module,exports){
262
+ },{"../../maths/constants":90,"../../maths/plane/signedDistanceToPoint":160,"../../maths/vec3":217,"./isA":77,"./isConvex":78,"./measureArea":79,"./plane":83}],88:[function(require,module,exports){
263
263
  module.exports={colors:require("./colors"),curves:require("./curves"),geometries:require("./geometries"),maths:require("./maths"),measurements:require("./measurements"),primitives:require("./primitives"),text:require("./text"),utils:require("./utils"),booleans:require("./operations/booleans"),expansions:require("./operations/expansions"),extrusions:require("./operations/extrusions"),hulls:require("./operations/hulls"),modifiers:require("./operations/modifiers"),transforms:require("./operations/transforms")};
264
264
 
265
265
  },{"./colors":8,"./curves":16,"./geometries":46,"./maths":91,"./measurements":247,"./operations/booleans":261,"./operations/expansions":290,"./operations/extrusions":312,"./operations/hulls":334,"./operations/modifiers":345,"./operations/transforms":355,"./primitives":371,"./text":385,"./utils":393}],89:[function(require,module,exports){
266
266
  const mat4=require("./mat4"),vec2=require("./vec2"),vec3=require("./vec3"),OrthoNormalBasis=function(e,t){arguments.length<2&&(t=vec3.orthogonal(vec3.create(),e)),this.v=vec3.normalize(vec3.create(),vec3.cross(vec3.create(),e,t)),this.u=vec3.cross(vec3.create(),this.v,e),this.plane=e,this.planeorigin=vec3.scale(vec3.create(),e,e[3])};OrthoNormalBasis.GetCartesian=function(e,t){const i=e+"/"+t;let s,n;if("X/Y"===i)s=[0,0,1],n=[1,0,0];else if("Y/-X"===i)s=[0,0,1],n=[0,1,0];else if("-X/-Y"===i)s=[0,0,1],n=[-1,0,0];else if("-Y/X"===i)s=[0,0,1],n=[0,-1,0];else if("-X/Y"===i)s=[0,0,-1],n=[-1,0,0];else if("-Y/-X"===i)s=[0,0,-1],n=[0,-1,0];else if("X/-Y"===i)s=[0,0,-1],n=[1,0,0];else if("Y/X"===i)s=[0,0,-1],n=[0,1,0];else if("X/Z"===i)s=[0,-1,0],n=[1,0,0];else if("Z/-X"===i)s=[0,-1,0],n=[0,0,1];else if("-X/-Z"===i)s=[0,-1,0],n=[-1,0,0];else if("-Z/X"===i)s=[0,-1,0],n=[0,0,-1];else if("-X/Z"===i)s=[0,1,0],n=[-1,0,0];else if("-Z/-X"===i)s=[0,1,0],n=[0,0,-1];else if("X/-Z"===i)s=[0,1,0],n=[1,0,0];else if("Z/X"===i)s=[0,1,0],n=[0,0,1];else if("Y/Z"===i)s=[1,0,0],n=[0,1,0];else if("Z/-Y"===i)s=[1,0,0],n=[0,0,1];else if("-Y/-Z"===i)s=[1,0,0],n=[0,-1,0];else if("-Z/Y"===i)s=[1,0,0],n=[0,0,-1];else if("-Y/Z"===i)s=[-1,0,0],n=[0,-1,0];else if("-Z/-Y"===i)s=[-1,0,0],n=[0,0,-1];else if("Y/-Z"===i)s=[-1,0,0],n=[0,1,0];else{if("Z/Y"!==i)throw new Error("OrthoNormalBasis.GetCartesian: invalid combination of axis identifiers. Should pass two string arguments from [X,Y,Z,-X,-Y,-Z], being two different axes.");s=[-1,0,0],n=[0,0,1]}return new OrthoNormalBasis(new Plane(new Vector3D(s),0),new Vector3D(n))},OrthoNormalBasis.Z0Plane=function(){const e=new Plane(new Vector3D([0,0,1]),0);return new OrthoNormalBasis(e,new Vector3D([1,0,0]))},OrthoNormalBasis.prototype={getProjectionMatrix:function(){return mat4.fromValues(this.u[0],this.v[0],this.plane[0],0,this.u[1],this.v[1],this.plane[1],0,this.u[2],this.v[2],this.plane[2],0,0,0,-this.plane[3],1)},getInverseProjectionMatrix:function(){const e=vec3.scale(vec3.create(),this.plane,this.plane[3]);return mat4.fromValues(this.u[0],this.u[1],this.u[2],0,this.v[0],this.v[1],this.v[2],0,this.plane[0],this.plane[1],this.plane[2],0,e[0],e[1],e[2],1)},to2D:function(e){return vec2.fromValues(vec3.dot(e,this.u),vec3.dot(e,this.v))},to3D:function(e){const t=vec3.scale(vec3.create(),this.u,e[0]),i=vec3.scale(vec3.create(),this.v,e[1]),s=vec3.add(t,t,this.planeorigin);return vec3.add(i,i,s)},line3Dto2D:function(e){const t=e.point,i=e.direction.plus(t),s=this.to2D(t),n=this.to2D(i);return Line2D.fromPoints(s,n)},line2Dto3D:function(e){const t=e.origin(),i=e.direction().plus(t),s=this.to3D(t),n=this.to3D(i);return Line3D.fromPoints(s,n)},transform:function(e){const t=this.plane.transform(e),i=this.u.transform(e),s=new Vector3D(0,0,0).transform(e),n=i.minus(s);return new OrthoNormalBasis(t,n)}},module.exports=OrthoNormalBasis;
267
267
 
268
- },{"./mat4":140,"./vec2":186,"./vec3":217}],90:[function(require,module,exports){
268
+ },{"./mat4":139,"./vec2":186,"./vec3":217}],90:[function(require,module,exports){
269
269
  const spatialResolution=1e5,EPS=1e-5,NEPS=1e-13;module.exports={EPS:EPS,NEPS:NEPS,spatialResolution:1e5};
270
270
 
271
271
  },{}],91:[function(require,module,exports){
272
272
  module.exports={constants:require("./constants"),line2:require("./line2"),line3:require("./line3"),mat4:require("./mat4"),plane:require("./plane"),utils:require("./utils"),vec2:require("./vec2"),vec3:require("./vec3"),vec4:require("./vec4")};
273
273
 
274
- },{"./constants":90,"./line2":101,"./line3":118,"./mat4":140,"./plane":159,"./utils":165,"./vec2":186,"./vec3":217,"./vec4":243}],92:[function(require,module,exports){
274
+ },{"./constants":90,"./line2":101,"./line3":118,"./mat4":139,"./plane":158,"./utils":164,"./vec2":186,"./vec3":217,"./vec4":243}],92:[function(require,module,exports){
275
275
  const create=require("./create"),clone=e=>{const r=create();return r[0]=e[0],r[1]=e[1],r[2]=e[2],r};module.exports=clone;
276
276
 
277
277
  },{"./create":95}],93:[function(require,module,exports){
@@ -304,7 +304,7 @@ module.exports={clone:require("./clone"),closestPoint:require("./closestPoint"),
304
304
  },{"./clone":92,"./closestPoint":93,"./copy":94,"./create":95,"./direction":96,"./distanceToPoint":97,"./equals":98,"./fromPoints":99,"./fromValues":100,"./intersectPointOfLines":102,"./origin":103,"./reverse":104,"./toString":105,"./transform":106,"./xAtY":107}],102:[function(require,module,exports){
305
305
  const vec2=require("../vec2"),{solve2Linear:solve2Linear}=require("../utils"),intersectToLine=(e,r)=>{const n=solve2Linear(e[0],e[1],r[0],r[1],e[2],r[2]);return vec2.clone(n)};module.exports=intersectToLine;
306
306
 
307
- },{"../utils":165,"../vec2":186}],103:[function(require,module,exports){
307
+ },{"../utils":164,"../vec2":186}],103:[function(require,module,exports){
308
308
  const vec2=require("../vec2"),origin=e=>vec2.scale(vec2.create(),e,e[2]);module.exports=origin;
309
309
 
310
310
  },{"../vec2":186}],104:[function(require,module,exports){
@@ -343,7 +343,7 @@ const vec3=require("../vec3"),equals=(e,s)=>!!vec3.equals(e[1],s[1])&&!!vec3.equ
343
343
  },{"../vec3":217}],115:[function(require,module,exports){
344
344
  const vec3=require("../vec3"),{solve2Linear:solve2Linear}=require("../utils"),{EPS:EPS}=require("../constants"),fromPointAndDirection=require("./fromPointAndDirection"),fromPlanes=(e,r,o)=>{let n=vec3.cross(vec3.create(),r,o),s=vec3.length(n);if(s<EPS)throw new Error("parallel planes do not intersect");s=1/s,n=vec3.scale(n,n,s);const t=Math.abs(n[0]),a=Math.abs(n[1]),i=Math.abs(n[2]);let l,c;return t>=a&&t>=i?(c=solve2Linear(r[1],r[2],o[1],o[2],r[3],o[3]),l=vec3.fromValues(0,c[0],c[1])):a>=t&&a>=i?(c=solve2Linear(r[0],r[2],o[0],o[2],r[3],o[3]),l=vec3.fromValues(c[0],0,c[1])):(c=solve2Linear(r[0],r[1],o[0],o[1],r[3],o[3]),l=vec3.fromValues(c[0],c[1],0)),fromPointAndDirection(e,l,n)};module.exports=fromPlanes;
345
345
 
346
- },{"../constants":90,"../utils":165,"../vec3":217,"./fromPointAndDirection":116}],116:[function(require,module,exports){
346
+ },{"../constants":90,"../utils":164,"../vec3":217,"./fromPointAndDirection":116}],116:[function(require,module,exports){
347
347
  const vec3=require("../vec3"),fromPointAndDirection=(e,c,o)=>{const r=vec3.normalize(vec3.create(),o);return vec3.copy(e[0],c),vec3.copy(e[1],r),e};module.exports=fromPointAndDirection;
348
348
 
349
349
  },{"../vec3":217}],117:[function(require,module,exports){
@@ -373,136 +373,136 @@ const add=(d,o,a)=>(d[0]=o[0]+a[0],d[1]=o[1]+a[1],d[2]=o[2]+a[2],d[3]=o[3]+a[3],
373
373
  },{}],125:[function(require,module,exports){
374
374
  const create=require("./create"),clone=e=>{const r=create();return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r};module.exports=clone;
375
375
 
376
- },{"./create":128}],126:[function(require,module,exports){
377
- const EPSILON=1e-6;module.exports={EPSILON:1e-6};
378
-
379
- },{}],127:[function(require,module,exports){
376
+ },{"./create":127}],126:[function(require,module,exports){
380
377
  const copy=(o,c)=>(o[0]=c[0],o[1]=c[1],o[2]=c[2],o[3]=c[3],o[4]=c[4],o[5]=c[5],o[6]=c[6],o[7]=c[7],o[8]=c[8],o[9]=c[9],o[10]=c[10],o[11]=c[11],o[12]=c[12],o[13]=c[13],o[14]=c[14],o[15]=c[15],o);module.exports=copy;
381
378
 
382
- },{}],128:[function(require,module,exports){
379
+ },{}],127:[function(require,module,exports){
383
380
  const create=()=>[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];module.exports=create;
384
381
 
385
- },{}],129:[function(require,module,exports){
382
+ },{}],128:[function(require,module,exports){
386
383
  const equals=(e,s)=>e[0]===s[0]&&e[1]===s[1]&&e[2]===s[2]&&e[3]===s[3]&&e[4]===s[4]&&e[5]===s[5]&&e[6]===s[6]&&e[7]===s[7]&&e[8]===s[8]&&e[9]===s[9]&&e[10]===s[10]&&e[11]===s[11]&&e[12]===s[12]&&e[13]===s[13]&&e[14]===s[14]&&e[15]===s[15];module.exports=equals;
387
384
 
388
- },{}],130:[function(require,module,exports){
389
- const identity=require("./identity"),{EPSILON:EPSILON}=require("./constants"),fromRotation=(t,o,e)=>{let[i,n,r]=e,a=Math.hypot(i,n,r);if(Math.abs(a)<EPSILON)return identity(t);i*=a=1/a,n*=a,r*=a;const s=Math.sin(o),h=Math.cos(o),u=1-h;return t[0]=i*i*u+h,t[1]=n*i*u+r*s,t[2]=r*i*u-n*s,t[3]=0,t[4]=i*n*u-r*s,t[5]=n*n*u+h,t[6]=r*n*u+i*s,t[7]=0,t[8]=i*r*u+n*s,t[9]=n*r*u-i*s,t[10]=r*r*u+h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t};module.exports=fromRotation;
385
+ },{}],129:[function(require,module,exports){
386
+ const{EPS:EPS}=require("../constants"),{sin:sin,cos:cos}=require("../utils/trigonometry"),identity=require("./identity"),fromRotation=(t,o,i)=>{let[n,r,s]=i;const e=n*n+r*r+s*s;if(Math.abs(e)<EPS)return identity(t);const c=1/Math.sqrt(e);n*=c,r*=c,s*=c;const u=sin(o),a=cos(o),d=1-a;return t[0]=n*n*d+a,t[1]=r*n*d+s*u,t[2]=s*n*d-r*u,t[3]=0,t[4]=n*r*d-s*u,t[5]=r*r*d+a,t[6]=s*r*d+n*u,t[7]=0,t[8]=n*s*d+r*u,t[9]=r*s*d-n*u,t[10]=s*s*d+a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t};module.exports=fromRotation;
390
387
 
391
- },{"./constants":126,"./identity":139}],131:[function(require,module,exports){
388
+ },{"../constants":90,"../utils/trigonometry":168,"./identity":138}],130:[function(require,module,exports){
392
389
  const fromScaling=(o,c)=>(o[0]=c[0],o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=c[1],o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c[2],o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o);module.exports=fromScaling;
393
390
 
394
- },{}],132:[function(require,module,exports){
395
- const fromTaitBryanRotation=(t,o,a,n)=>{const s=Math.sin(o),i=Math.cos(o),r=Math.sin(a),h=Math.cos(a),M=Math.sin(n),c=Math.cos(n);return t[0]=h*i,t[1]=h*s,t[2]=-r,t[3]=0,t[4]=M*r*i-c*s,t[5]=c*i+M*r*s,t[6]=M*h,t[7]=0,t[8]=M*s+c*r*i,t[9]=c*r*s-M*i,t[10]=c*h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t};module.exports=fromTaitBryanRotation;
391
+ },{}],131:[function(require,module,exports){
392
+ const{sin:sin,cos:cos}=require("../utils/trigonometry"),fromTaitBryanRotation=(o,s,n,t)=>{const i=sin(s),r=cos(s),c=sin(n),a=cos(n),e=sin(t),m=cos(t);return o[0]=a*r,o[1]=a*i,o[2]=-c,o[3]=0,o[4]=e*c*r-m*i,o[5]=m*r+e*c*i,o[6]=e*a,o[7]=0,o[8]=e*i+m*c*r,o[9]=m*c*i-e*r,o[10]=m*a,o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o};module.exports=fromTaitBryanRotation;
396
393
 
397
- },{}],133:[function(require,module,exports){
394
+ },{"../utils/trigonometry":168}],132:[function(require,module,exports){
398
395
  const fromTranslation=(o,n)=>(o[0]=1,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=1,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=1,o[11]=0,o[12]=n[0],o[13]=n[1],o[14]=n[2],o[15]=1,o);module.exports=fromTranslation;
399
396
 
400
- },{}],134:[function(require,module,exports){
397
+ },{}],133:[function(require,module,exports){
401
398
  const create=require("./create"),fromValues=(e,r,t,o,a,c,s,u,l,m,n,f,V,d,i,p)=>{const q=create();return q[0]=e,q[1]=r,q[2]=t,q[3]=o,q[4]=a,q[5]=c,q[6]=s,q[7]=u,q[8]=l,q[9]=m,q[10]=n,q[11]=f,q[12]=V,q[13]=d,q[14]=i,q[15]=p,q};module.exports=fromValues;
402
399
 
403
- },{"./create":128}],135:[function(require,module,exports){
400
+ },{"./create":127}],134:[function(require,module,exports){
404
401
  const vec3=require("../vec3"),fromRotation=require("./fromRotation"),fromVectorRotation=(o,e,t)=>{const r=vec3.normalize(vec3.create(),e),c=vec3.normalize(vec3.create(),t),n=vec3.cross(vec3.create(),c,r),a=vec3.dot(c,r);if(-1===a)return fromRotation(o,Math.PI,vec3.orthogonal(n,r));const i=1/(1+a);return o[0]=n[0]*n[0]*i+a,o[1]=n[1]*n[0]*i-n[2],o[2]=n[2]*n[0]*i+n[1],o[3]=0,o[4]=n[0]*n[1]*i+n[2],o[5]=n[1]*n[1]*i+a,o[6]=n[2]*n[1]*i-n[0],o[7]=0,o[8]=n[0]*n[2]*i-n[1],o[9]=n[1]*n[2]*i+n[0],o[10]=n[2]*n[2]*i+a,o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o};module.exports=fromVectorRotation;
405
402
 
406
- },{"../vec3":217,"./fromRotation":130}],136:[function(require,module,exports){
407
- const fromXRotation=(o,t)=>{const n=Math.sin(t),r=Math.cos(t);return o[0]=1,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=r,o[6]=n,o[7]=0,o[8]=0,o[9]=-n,o[10]=r,o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o};module.exports=fromXRotation;
403
+ },{"../vec3":217,"./fromRotation":129}],135:[function(require,module,exports){
404
+ const{sin:sin,cos:cos}=require("../utils/trigonometry"),fromXRotation=(o,t)=>{const s=sin(t),n=cos(t);return o[0]=1,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=n,o[6]=s,o[7]=0,o[8]=0,o[9]=-s,o[10]=n,o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o};module.exports=fromXRotation;
408
405
 
409
- },{}],137:[function(require,module,exports){
410
- const fromYRotation=(o,t)=>{const n=Math.sin(t),r=Math.cos(t);return o[0]=r,o[1]=0,o[2]=-n,o[3]=0,o[4]=0,o[5]=1,o[6]=0,o[7]=0,o[8]=n,o[9]=0,o[10]=r,o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o};module.exports=fromYRotation;
406
+ },{"../utils/trigonometry":168}],136:[function(require,module,exports){
407
+ const{sin:sin,cos:cos}=require("../utils/trigonometry"),fromYRotation=(o,t)=>{const s=sin(t),n=cos(t);return o[0]=n,o[1]=0,o[2]=-s,o[3]=0,o[4]=0,o[5]=1,o[6]=0,o[7]=0,o[8]=s,o[9]=0,o[10]=n,o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o};module.exports=fromYRotation;
411
408
 
412
- },{}],138:[function(require,module,exports){
413
- const fromZRotation=(o,t)=>{const n=Math.sin(t),r=Math.cos(t);return o[0]=r,o[1]=n,o[2]=0,o[3]=0,o[4]=-n,o[5]=r,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=1,o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o};module.exports=fromZRotation;
409
+ },{"../utils/trigonometry":168}],137:[function(require,module,exports){
410
+ const{sin:sin,cos:cos}=require("../utils/trigonometry"),fromZRotation=(o,t)=>{const s=sin(t),n=cos(t);return o[0]=n,o[1]=s,o[2]=0,o[3]=0,o[4]=-s,o[5]=n,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=1,o[11]=0,o[12]=0,o[13]=0,o[14]=0,o[15]=1,o};module.exports=fromZRotation;
414
411
 
415
- },{}],139:[function(require,module,exports){
412
+ },{"../utils/trigonometry":168}],138:[function(require,module,exports){
416
413
  const identity=t=>(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t);module.exports=identity;
417
414
 
418
- },{}],140:[function(require,module,exports){
415
+ },{}],139:[function(require,module,exports){
419
416
  module.exports={add:require("./add"),clone:require("./clone"),copy:require("./copy"),create:require("./create"),invert:require("./invert"),equals:require("./equals"),fromRotation:require("./fromRotation"),fromScaling:require("./fromScaling"),fromTaitBryanRotation:require("./fromTaitBryanRotation"),fromTranslation:require("./fromTranslation"),fromValues:require("./fromValues"),fromVectorRotation:require("./fromVectorRotation"),fromXRotation:require("./fromXRotation"),fromYRotation:require("./fromYRotation"),fromZRotation:require("./fromZRotation"),identity:require("./identity"),isIdentity:require("./isIdentity"),isOnlyTransformScale:require("./isOnlyTransformScale"),isMirroring:require("./isMirroring"),mirrorByPlane:require("./mirrorByPlane"),multiply:require("./multiply"),rotate:require("./rotate"),rotateX:require("./rotateX"),rotateY:require("./rotateY"),rotateZ:require("./rotateZ"),scale:require("./scale"),subtract:require("./subtract"),toString:require("./toString"),translate:require("./translate")};
420
417
 
421
- },{"./add":124,"./clone":125,"./copy":127,"./create":128,"./equals":129,"./fromRotation":130,"./fromScaling":131,"./fromTaitBryanRotation":132,"./fromTranslation":133,"./fromValues":134,"./fromVectorRotation":135,"./fromXRotation":136,"./fromYRotation":137,"./fromZRotation":138,"./identity":139,"./invert":141,"./isIdentity":142,"./isMirroring":143,"./isOnlyTransformScale":144,"./mirrorByPlane":145,"./multiply":146,"./rotate":147,"./rotateX":148,"./rotateY":149,"./rotateZ":150,"./scale":151,"./subtract":152,"./toString":153,"./translate":154}],141:[function(require,module,exports){
418
+ },{"./add":124,"./clone":125,"./copy":126,"./create":127,"./equals":128,"./fromRotation":129,"./fromScaling":130,"./fromTaitBryanRotation":131,"./fromTranslation":132,"./fromValues":133,"./fromVectorRotation":134,"./fromXRotation":135,"./fromYRotation":136,"./fromZRotation":137,"./identity":138,"./invert":140,"./isIdentity":141,"./isMirroring":142,"./isOnlyTransformScale":143,"./mirrorByPlane":144,"./multiply":145,"./rotate":146,"./rotateX":147,"./rotateY":148,"./rotateZ":149,"./scale":150,"./subtract":151,"./toString":152,"./translate":153}],140:[function(require,module,exports){
422
419
  const invert=(t,e)=>{const n=e[0],r=e[1],l=e[2],o=e[3],s=e[4],u=e[5],c=e[6],i=e[7],v=e[8],d=e[9],m=e[10],p=e[11],x=e[12],a=e[13],b=e[14],f=e[15],g=n*u-r*s,h=n*c-l*s,j=n*i-o*s,k=r*c-l*u,q=r*i-o*u,w=l*i-o*c,y=v*a-d*x,z=v*b-m*x,A=v*f-p*x,B=d*b-m*a,C=d*f-p*a,D=m*f-p*b;let E=g*D-h*C+j*B+k*A-q*z+w*y;return E?(E=1/E,t[0]=(u*D-c*C+i*B)*E,t[1]=(l*C-r*D-o*B)*E,t[2]=(a*w-b*q+f*k)*E,t[3]=(m*q-d*w-p*k)*E,t[4]=(c*A-s*D-i*z)*E,t[5]=(n*D-l*A+o*z)*E,t[6]=(b*j-x*w-f*h)*E,t[7]=(v*w-m*j+p*h)*E,t[8]=(s*C-u*A+i*y)*E,t[9]=(r*A-n*C-o*y)*E,t[10]=(x*q-a*j+f*g)*E,t[11]=(d*j-v*q-p*g)*E,t[12]=(u*z-s*B-c*y)*E,t[13]=(n*B-r*z+l*y)*E,t[14]=(a*h-x*k-b*g)*E,t[15]=(v*k-d*h+m*g)*E,t):null};module.exports=invert;
423
420
 
424
- },{}],142:[function(require,module,exports){
421
+ },{}],141:[function(require,module,exports){
425
422
  const isIdentity=t=>1===t[0]&&0===t[1]&&0===t[2]&&0===t[3]&&0===t[4]&&1===t[5]&&0===t[6]&&0===t[7]&&0===t[8]&&0===t[9]&&1===t[10]&&0===t[11]&&0===t[12]&&0===t[13]&&0===t[14]&&1===t[15];module.exports=isIdentity;
426
423
 
427
- },{}],143:[function(require,module,exports){
428
- const cross=require("../vec3/cross"),dot=require("../vec3/dot"),fromValues=require("../vec3/fromValues"),isMirroring=r=>{const e=fromValues(r[0],r[4],r[8]),o=fromValues(r[1],r[5],r[9]),s=fromValues(r[2],r[6],r[10]);return dot(cross(e,e,o),s)<0};module.exports=isMirroring;
424
+ },{}],142:[function(require,module,exports){
425
+ const isMirroring=r=>{const i=r[4]*r[9]-r[8]*r[5],o=r[8]*r[1]-r[0]*r[9],n=r[0]*r[5]-r[4]*r[1];return i*r[2]+o*r[6]+n*r[10]<0};module.exports=isMirroring;
429
426
 
430
- },{"../vec3/cross":209,"../vec3/dot":212,"../vec3/fromValues":215}],144:[function(require,module,exports){
427
+ },{}],143:[function(require,module,exports){
431
428
  const isOnlyTransformScale=s=>isZero(s[1])&&isZero(s[2])&&isZero(s[3])&&isZero(s[4])&&isZero(s[6])&&isZero(s[7])&&isZero(s[8])&&isZero(s[9])&&isZero(s[11])&&1===s[15],isZero=s=>Math.abs(s)<Number.EPSILON;module.exports=isOnlyTransformScale;
432
429
 
433
- },{}],145:[function(require,module,exports){
430
+ },{}],144:[function(require,module,exports){
434
431
  const mirrorByPlane=(r,o)=>{const[e,n,t,l]=o;return r[0]=1-2*e*e,r[1]=-2*n*e,r[2]=-2*t*e,r[3]=0,r[4]=-2*e*n,r[5]=1-2*n*n,r[6]=-2*t*n,r[7]=0,r[8]=-2*e*t,r[9]=-2*n*t,r[10]=1-2*t*t,r[11]=0,r[12]=2*e*l,r[13]=2*n*l,r[14]=2*t*l,r[15]=1,r};module.exports=mirrorByPlane;
435
432
 
436
- },{}],146:[function(require,module,exports){
433
+ },{}],145:[function(require,module,exports){
437
434
  const multiply=(t,l,e)=>{const o=l[0],u=l[1],m=l[2],n=l[3],p=l[4],r=l[5],s=l[6],c=l[7],i=l[8],y=l[9],d=l[10],x=l[11],a=l[12],b=l[13],f=l[14],g=l[15];let h=e[0],j=e[1],k=e[2],q=e[3];return t[0]=h*o+j*p+k*i+q*a,t[1]=h*u+j*r+k*y+q*b,t[2]=h*m+j*s+k*d+q*f,t[3]=h*n+j*c+k*x+q*g,h=e[4],j=e[5],k=e[6],q=e[7],t[4]=h*o+j*p+k*i+q*a,t[5]=h*u+j*r+k*y+q*b,t[6]=h*m+j*s+k*d+q*f,t[7]=h*n+j*c+k*x+q*g,h=e[8],j=e[9],k=e[10],q=e[11],t[8]=h*o+j*p+k*i+q*a,t[9]=h*u+j*r+k*y+q*b,t[10]=h*m+j*s+k*d+q*f,t[11]=h*n+j*c+k*x+q*g,h=e[12],j=e[13],k=e[14],q=e[15],t[12]=h*o+j*p+k*i+q*a,t[13]=h*u+j*r+k*y+q*b,t[14]=h*m+j*s+k*d+q*f,t[15]=h*n+j*c+k*x+q*g,t};module.exports=multiply;
438
435
 
439
- },{}],147:[function(require,module,exports){
440
- const copy=require("./copy"),rotate=(t,o,e,r)=>{let[a,c,s]=r,h=Math.hypot(a,c,s);if(Math.abs(h)<1e-6)return copy(t,o);a*=h=1/h,c*=h,s*=h;const n=Math.sin(e),p=Math.cos(e),u=1-p,y=o[0],M=o[1],i=o[2],l=o[3],b=o[4],d=o[5],f=o[6],m=o[7],q=o[8],x=o[9],g=o[10],j=o[11],k=a*a*u+p,v=c*a*u+s*n,w=s*a*u-c*n,z=a*c*u-s*n,A=c*c*u+p,B=s*c*u+a*n,C=a*s*u+c*n,D=c*s*u-a*n,E=s*s*u+p;return t[0]=y*k+b*v+q*w,t[1]=M*k+d*v+x*w,t[2]=i*k+f*v+g*w,t[3]=l*k+m*v+j*w,t[4]=y*z+b*A+q*B,t[5]=M*z+d*A+x*B,t[6]=i*z+f*A+g*B,t[7]=l*z+m*A+j*B,t[8]=y*C+b*D+q*E,t[9]=M*C+d*D+x*E,t[10]=i*C+f*D+g*E,t[11]=l*C+m*D+j*E,o!==t&&(t[12]=o[12],t[13]=o[13],t[14]=o[14],t[15]=o[15]),t};module.exports=rotate;
436
+ },{}],146:[function(require,module,exports){
437
+ const{EPS:EPS}=require("../constants"),{sin:sin,cos:cos}=require("../utils/trigonometry"),copy=require("./copy"),rotate=(t,o,r,s)=>{let[e,n,c]=s;const i=e*e+n*n+c*c;if(Math.abs(i)<EPS)return copy(t,o);const u=1/Math.sqrt(i);e*=u,n*=u,c*=u;const a=sin(r),p=cos(r),q=1-p,y=o[0],l=o[1],E=o[2],P=o[3],S=o[4],h=o[5],m=o[6],M=o[7],b=o[8],d=o[9],f=o[10],g=o[11],x=e*e*q+p,j=n*e*q+c*a,k=c*e*q-n*a,v=e*n*q-c*a,w=n*n*q+p,z=c*n*q+e*a,A=e*c*q+n*a,B=n*c*q-e*a,C=c*c*q+p;return t[0]=y*x+S*j+b*k,t[1]=l*x+h*j+d*k,t[2]=E*x+m*j+f*k,t[3]=P*x+M*j+g*k,t[4]=y*v+S*w+b*z,t[5]=l*v+h*w+d*z,t[6]=E*v+m*w+f*z,t[7]=P*v+M*w+g*z,t[8]=y*A+S*B+b*C,t[9]=l*A+h*B+d*C,t[10]=E*A+m*B+f*C,t[11]=P*A+M*B+g*C,o!==t&&(t[12]=o[12],t[13]=o[13],t[14]=o[14],t[15]=o[15]),t};module.exports=rotate;
441
438
 
442
- },{"./copy":127}],148:[function(require,module,exports){
443
- const rotateX=(t,o,e)=>{const r=Math.sin(e),s=Math.cos(e),a=o[4],n=o[5],c=o[6],h=o[7],u=o[8],M=o[9],X=o[10],d=o[11];return o!==t&&(t[0]=o[0],t[1]=o[1],t[2]=o[2],t[3]=o[3],t[12]=o[12],t[13]=o[13],t[14]=o[14],t[15]=o[15]),t[4]=a*s+u*r,t[5]=n*s+M*r,t[6]=c*s+X*r,t[7]=h*s+d*r,t[8]=u*s-a*r,t[9]=M*s-n*r,t[10]=X*s-c*r,t[11]=d*s-h*r,t};module.exports=rotateX;
439
+ },{"../constants":90,"../utils/trigonometry":168,"./copy":126}],147:[function(require,module,exports){
440
+ const{sin:sin,cos:cos}=require("../utils/trigonometry"),rotateX=(o,t,s)=>{const r=sin(s),e=cos(s),n=t[4],i=t[5],c=t[6],u=t[7],a=t[8],l=t[9],m=t[10],X=t[11];return t!==o&&(o[0]=t[0],o[1]=t[1],o[2]=t[2],o[3]=t[3],o[12]=t[12],o[13]=t[13],o[14]=t[14],o[15]=t[15]),o[4]=n*e+a*r,o[5]=i*e+l*r,o[6]=c*e+m*r,o[7]=u*e+X*r,o[8]=a*e-n*r,o[9]=l*e-i*r,o[10]=m*e-c*r,o[11]=X*e-u*r,o};module.exports=rotateX;
444
441
 
445
- },{}],149:[function(require,module,exports){
446
- const rotateY=(t,o,e)=>{const r=Math.sin(e),s=Math.cos(e),a=o[0],n=o[1],c=o[2],h=o[3],u=o[8],M=o[9],Y=o[10],d=o[11];return o!==t&&(t[4]=o[4],t[5]=o[5],t[6]=o[6],t[7]=o[7],t[12]=o[12],t[13]=o[13],t[14]=o[14],t[15]=o[15]),t[0]=a*s-u*r,t[1]=n*s-M*r,t[2]=c*s-Y*r,t[3]=h*s-d*r,t[8]=a*r+u*s,t[9]=n*r+M*s,t[10]=c*r+Y*s,t[11]=h*r+d*s,t};module.exports=rotateY;
442
+ },{"../utils/trigonometry":168}],148:[function(require,module,exports){
443
+ const{sin:sin,cos:cos}=require("../utils/trigonometry"),rotateY=(o,t,s)=>{const r=sin(s),e=cos(s),n=t[0],i=t[1],c=t[2],u=t[3],a=t[8],l=t[9],m=t[10],Y=t[11];return t!==o&&(o[4]=t[4],o[5]=t[5],o[6]=t[6],o[7]=t[7],o[12]=t[12],o[13]=t[13],o[14]=t[14],o[15]=t[15]),o[0]=n*e-a*r,o[1]=i*e-l*r,o[2]=c*e-m*r,o[3]=u*e-Y*r,o[8]=n*r+a*e,o[9]=i*r+l*e,o[10]=c*r+m*e,o[11]=u*r+Y*e,o};module.exports=rotateY;
447
444
 
448
- },{}],150:[function(require,module,exports){
449
- const rotateZ=(t,o,e)=>{const r=Math.sin(e),s=Math.cos(e),a=o[0],n=o[1],c=o[2],h=o[3],u=o[4],M=o[5],Z=o[6],d=o[7];return o!==t&&(t[8]=o[8],t[9]=o[9],t[10]=o[10],t[11]=o[11],t[12]=o[12],t[13]=o[13],t[14]=o[14],t[15]=o[15]),t[0]=a*s+u*r,t[1]=n*s+M*r,t[2]=c*s+Z*r,t[3]=h*s+d*r,t[4]=u*s-a*r,t[5]=M*s-n*r,t[6]=Z*s-c*r,t[7]=d*s-h*r,t};module.exports=rotateZ;
445
+ },{"../utils/trigonometry":168}],149:[function(require,module,exports){
446
+ const{sin:sin,cos:cos}=require("../utils/trigonometry"),rotateZ=(o,t,s)=>{const r=sin(s),e=cos(s),n=t[0],i=t[1],c=t[2],u=t[3],a=t[4],l=t[5],m=t[6],Z=t[7];return t!==o&&(o[8]=t[8],o[9]=t[9],o[10]=t[10],o[11]=t[11],o[12]=t[12],o[13]=t[13],o[14]=t[14],o[15]=t[15]),o[0]=n*e+a*r,o[1]=i*e+l*r,o[2]=c*e+m*r,o[3]=u*e+Z*r,o[4]=a*e-n*r,o[5]=l*e-i*r,o[6]=m*e-c*r,o[7]=Z*e-u*r,o};module.exports=rotateZ;
450
447
 
451
- },{}],151:[function(require,module,exports){
448
+ },{"../utils/trigonometry":168}],150:[function(require,module,exports){
452
449
  const scale=(e,s,c)=>{const o=c[0],t=c[1],l=c[2];return e[0]=s[0]*o,e[1]=s[1]*o,e[2]=s[2]*o,e[3]=s[3]*o,e[4]=s[4]*t,e[5]=s[5]*t,e[6]=s[6]*t,e[7]=s[7]*t,e[8]=s[8]*l,e[9]=s[9]*l,e[10]=s[10]*l,e[11]=s[11]*l,e[12]=s[12],e[13]=s[13],e[14]=s[14],e[15]=s[15],e};module.exports=scale;
453
450
 
454
- },{}],152:[function(require,module,exports){
451
+ },{}],151:[function(require,module,exports){
455
452
  const subtract=(t,s,c)=>(t[0]=s[0]-c[0],t[1]=s[1]-c[1],t[2]=s[2]-c[2],t[3]=s[3]-c[3],t[4]=s[4]-c[4],t[5]=s[5]-c[5],t[6]=s[6]-c[6],t[7]=s[7]-c[7],t[8]=s[8]-c[8],t[9]=s[9]-c[9],t[10]=s[10]-c[10],t[11]=s[11]-c[11],t[12]=s[12]-c[12],t[13]=s[13]-c[13],t[14]=s[14]-c[14],t[15]=s[15]-c[15],t);module.exports=subtract;
456
453
 
457
- },{}],153:[function(require,module,exports){
454
+ },{}],152:[function(require,module,exports){
458
455
  const toString=t=>t.map(t=>t.toFixed(7)).toString();module.exports=toString;
459
456
 
460
- },{}],154:[function(require,module,exports){
457
+ },{}],153:[function(require,module,exports){
461
458
  const translate=(t,e,n)=>{const r=n[0],s=n[1],a=n[2];let l,o,c,u,d,m,p,x,b,f,g,h;return e===t?(t[12]=e[0]*r+e[4]*s+e[8]*a+e[12],t[13]=e[1]*r+e[5]*s+e[9]*a+e[13],t[14]=e[2]*r+e[6]*s+e[10]*a+e[14],t[15]=e[3]*r+e[7]*s+e[11]*a+e[15]):(l=e[0],o=e[1],c=e[2],u=e[3],d=e[4],m=e[5],p=e[6],x=e[7],b=e[8],f=e[9],g=e[10],h=e[11],t[0]=l,t[1]=o,t[2]=c,t[3]=u,t[4]=d,t[5]=m,t[6]=p,t[7]=x,t[8]=b,t[9]=f,t[10]=g,t[11]=h,t[12]=l*r+d*s+b*a+e[12],t[13]=o*r+m*s+f*a+e[13],t[14]=c*r+p*s+g*a+e[14],t[15]=u*r+x*s+h*a+e[15]),t};module.exports=translate;
462
459
 
463
- },{}],155:[function(require,module,exports){
460
+ },{}],154:[function(require,module,exports){
464
461
  const flip=(l,o)=>(l[0]=-o[0],l[1]=-o[1],l[2]=-o[2],l[3]=-o[3],l);module.exports=flip;
465
462
 
466
- },{}],156:[function(require,module,exports){
463
+ },{}],155:[function(require,module,exports){
467
464
  const vec3=require("../vec3"),fromNormalAndPoint=(e,o,r)=>{const c=vec3.normalize(vec3.create(),o),n=vec3.dot(r,c);return e[0]=c[0],e[1]=c[1],e[2]=c[2],e[3]=n,e};module.exports=fromNormalAndPoint;
468
465
 
469
- },{"../vec3":217}],157:[function(require,module,exports){
466
+ },{"../vec3":217}],156:[function(require,module,exports){
470
467
  const vec3=require("../vec3"),fromPoints=(e,...c)=>{const r=c.length,t=vec3.create(),o=vec3.create(),v=e=>{const v=c[e],n=c[(e+1)%r],s=c[(e+2)%r];return vec3.subtract(t,n,v),vec3.subtract(o,s,v),vec3.cross(t,t,o),vec3.normalize(t,t),t};return e[0]=0,e[1]=0,e[2]=0,3===r?vec3.copy(e,v(0)):(c.forEach((c,r)=>{vec3.add(e,e,v(r))}),vec3.normalize(e,e)),e[3]=vec3.dot(e,c[0]),e};module.exports=fromPoints;
471
468
 
472
- },{"../vec3":217}],158:[function(require,module,exports){
469
+ },{"../vec3":217}],157:[function(require,module,exports){
473
470
  const{EPS:EPS}=require("../constants"),vec3=require("../vec3"),fromPointsRandom=(e,c,o,t)=>{let r=vec3.subtract(vec3.create(),o,c),v=vec3.subtract(vec3.create(),t,c);vec3.length(r)<EPS&&(r=vec3.orthogonal(r,v)),vec3.length(v)<EPS&&(v=vec3.orthogonal(v,r));let n=vec3.cross(vec3.create(),r,v);vec3.length(n)<EPS&&(v=vec3.orthogonal(v,r),n=vec3.cross(n,r,v)),n=vec3.normalize(n,n);const s=vec3.dot(n,c);return e[0]=n[0],e[1]=n[1],e[2]=n[2],e[3]=s,e};module.exports=fromPointsRandom;
474
471
 
475
- },{"../constants":90,"../vec3":217}],159:[function(require,module,exports){
472
+ },{"../constants":90,"../vec3":217}],158:[function(require,module,exports){
476
473
  module.exports={clone:require("../vec4/clone"),copy:require("../vec4/copy"),create:require("../vec4/create"),equals:require("../vec4/equals"),flip:require("./flip"),fromNormalAndPoint:require("./fromNormalAndPoint"),fromValues:require("../vec4/fromValues"),fromPoints:require("./fromPoints"),fromPointsRandom:require("./fromPointsRandom"),projectionOfPoint:require("./projectionOfPoint"),signedDistanceToPoint:require("./signedDistanceToPoint"),toString:require("../vec4/toString"),transform:require("./transform")};
477
474
 
478
- },{"../vec4/clone":236,"../vec4/copy":237,"../vec4/create":238,"../vec4/equals":240,"../vec4/fromValues":242,"../vec4/toString":244,"./flip":155,"./fromNormalAndPoint":156,"./fromPoints":157,"./fromPointsRandom":158,"./projectionOfPoint":160,"./signedDistanceToPoint":161,"./transform":162}],160:[function(require,module,exports){
475
+ },{"../vec4/clone":236,"../vec4/copy":237,"../vec4/create":238,"../vec4/equals":240,"../vec4/fromValues":242,"../vec4/toString":244,"./flip":154,"./fromNormalAndPoint":155,"./fromPoints":156,"./fromPointsRandom":157,"./projectionOfPoint":159,"./signedDistanceToPoint":160,"./transform":161}],159:[function(require,module,exports){
479
476
  const vec3=require("../vec3"),projectionOfPoint=(e,o)=>{const r=o[0]*e[0]+o[1]*e[1]+o[2]*e[2]-e[3],t=o[0]-r*e[0],c=o[1]-r*e[1],n=o[2]-r*e[2];return vec3.fromValues(t,c,n)};module.exports=projectionOfPoint;
480
477
 
481
- },{"../vec3":217}],161:[function(require,module,exports){
478
+ },{"../vec3":217}],160:[function(require,module,exports){
482
479
  const vec3=require("../vec3"),signedDistanceToPoint=(e,o)=>vec3.dot(e,o)-e[3];module.exports=signedDistanceToPoint;
483
480
 
484
- },{"../vec3":217}],162:[function(require,module,exports){
481
+ },{"../vec3":217}],161:[function(require,module,exports){
485
482
  const mat4=require("../mat4"),vec3=require("../vec3"),fromPoints=require("./fromPoints"),flip=require("./flip"),transform=(e,r,c)=>{const t=mat4.isMirroring(c),o=vec3.orthogonal(vec3.create(),r),a=vec3.cross(o,r,o),v=vec3.cross(vec3.create(),r,a);let s=vec3.fromScalar(vec3.create(),r[3]);vec3.multiply(s,s,r);let i=vec3.add(vec3.create(),s,a),m=vec3.add(vec3.create(),s,v);return s=vec3.transform(s,s,c),i=vec3.transform(i,i,c),m=vec3.transform(m,m,c),fromPoints(e,s,i,m),t&&flip(e,e),e};module.exports=transform;
486
483
 
487
- },{"../mat4":140,"../vec3":217,"./flip":155,"./fromPoints":157}],163:[function(require,module,exports){
484
+ },{"../mat4":139,"../vec3":217,"./flip":154,"./fromPoints":156}],162:[function(require,module,exports){
488
485
  const{NEPS:NEPS}=require("../constants"),aboutEqualNormals=(a,s)=>Math.abs(a[0]-s[0])<=NEPS&&Math.abs(a[1]-s[1])<=NEPS&&Math.abs(a[2]-s[2])<=NEPS;module.exports=aboutEqualNormals;
489
486
 
490
- },{"../constants":90}],164:[function(require,module,exports){
487
+ },{"../constants":90}],163:[function(require,module,exports){
491
488
  const area=e=>{let t=0;for(let r=0;r<e.length;r++){const l=(r+1)%e.length;t+=e[r][0]*e[l][1],t-=e[l][0]*e[r][1]}return t/2};module.exports=area;
492
489
 
493
- },{}],165:[function(require,module,exports){
494
- module.exports={aboutEqualNormals:require("./aboutEqualNormals"),area:require("./area"),interpolateBetween2DPointsForY:require("./interpolateBetween2DPointsForY"),intersect:require("./intersect"),solve2Linear:require("./solve2Linear")};
490
+ },{}],164:[function(require,module,exports){
491
+ module.exports={aboutEqualNormals:require("./aboutEqualNormals"),area:require("./area"),cos:require("./trigonometry").cos,interpolateBetween2DPointsForY:require("./interpolateBetween2DPointsForY"),intersect:require("./intersect"),sin:require("./trigonometry").sin,solve2Linear:require("./solve2Linear")};
495
492
 
496
- },{"./aboutEqualNormals":163,"./area":164,"./interpolateBetween2DPointsForY":166,"./intersect":167,"./solve2Linear":168}],166:[function(require,module,exports){
493
+ },{"./aboutEqualNormals":162,"./area":163,"./interpolateBetween2DPointsForY":165,"./intersect":166,"./solve2Linear":167,"./trigonometry":168}],165:[function(require,module,exports){
497
494
  const interpolateBetween2DPointsForY=(e,t,o)=>{let n,r=o-e[1],i=t[1]-e[1];return i<0&&(r=-r,i=-i),n=r<=0?0:r>=i?1:i<1e-10?.5:r/i,e[0]+n*(t[0]-e[0])};module.exports=interpolateBetween2DPointsForY;
498
495
 
499
- },{}],167:[function(require,module,exports){
496
+ },{}],166:[function(require,module,exports){
500
497
  const intersect=(t,e,r,n)=>{if(t[0]===e[0]&&t[1]===e[1]||r[0]===n[0]&&r[1]===n[1])return;const s=(n[1]-r[1])*(e[0]-t[0])-(n[0]-r[0])*(e[1]-t[1]);if(Math.abs(s)<Number.MIN_VALUE)return;const o=((n[0]-r[0])*(t[1]-r[1])-(n[1]-r[1])*(t[0]-r[0]))/s,c=((e[0]-t[0])*(t[1]-r[1])-(e[1]-t[1])*(t[0]-r[0]))/s;return o<0||o>1||c<0||c>1?void 0:[t[0]+o*(e[0]-t[0]),t[1]+o*(e[1]-t[1])]};module.exports=intersect;
501
498
 
502
- },{}],168:[function(require,module,exports){
499
+ },{}],167:[function(require,module,exports){
503
500
  const solve2Linear=(e,o,n,r,s,t)=>{const l=1/(e*r-o*n);let a=s*r-o*t,c=-s*n+e*t;return[a*=l,c*=l]};module.exports=solve2Linear;
504
501
 
505
- },{}],169:[function(require,module,exports){
502
+ },{}],168:[function(require,module,exports){
503
+ const{NEPS:NEPS}=require("../constants"),rezero=s=>Math.abs(s)<NEPS?0:s,sin=s=>rezero(Math.sin(s)),cos=s=>rezero(Math.cos(s));module.exports={sin:sin,cos:cos};
504
+
505
+ },{"../constants":90}],169:[function(require,module,exports){
506
506
  const abs=(a,s)=>(a[0]=Math.abs(s[0]),a[1]=Math.abs(s[1]),a);module.exports=abs;
507
507
 
508
508
  },{}],170:[function(require,module,exports){
@@ -530,7 +530,7 @@ const create=()=>[0,0];module.exports=create;
530
530
  const cross=(s,o,c)=>(s[0]=0,s[1]=0,s[2]=o[0]*c[1]-o[1]*c[0],s);module.exports=cross;
531
531
 
532
532
  },{}],178:[function(require,module,exports){
533
- const distance=(t,e)=>{const n=e[0]-t[0],o=e[1]-t[1];return Math.hypot(n,o)};module.exports=distance;
533
+ const distance=(t,s)=>{const e=s[0]-t[0],n=s[1]-t[1];return Math.sqrt(e*e+n*n)};module.exports=distance;
534
534
 
535
535
  },{}],179:[function(require,module,exports){
536
536
  const divide=(d,e,i)=>(d[0]=e[0]/i[0],d[1]=e[1]/i[1],d);module.exports=divide;
@@ -545,9 +545,9 @@ const equals=(e,s)=>e[0]===s[0]&&e[1]===s[1];module.exports=equals;
545
545
  const fromAngleRadians=require("./fromAngleRadians"),fromAngleDegrees=(e,r)=>fromAngleRadians(e,Math.PI*r/180);module.exports=fromAngleDegrees;
546
546
 
547
547
  },{"./fromAngleRadians":183}],183:[function(require,module,exports){
548
- const fromAngleRadians=(a,n)=>(a[0]=Math.cos(n),a[1]=Math.sin(n),a);module.exports=fromAngleRadians;
548
+ const{sin:sin,cos:cos}=require("../utils/trigonometry"),fromAngleRadians=(s,o)=>(s[0]=cos(o),s[1]=sin(o),s);module.exports=fromAngleRadians;
549
549
 
550
- },{}],184:[function(require,module,exports){
550
+ },{"../utils/trigonometry":168}],184:[function(require,module,exports){
551
551
  const fromScalar=(o,r)=>(o[0]=r,o[1]=r,o);module.exports=fromScalar;
552
552
 
553
553
  },{}],185:[function(require,module,exports){
@@ -557,7 +557,7 @@ const create=require("./create"),fromValues=(e,r)=>{const t=create();return t[0]
557
557
  module.exports={abs:require("./abs"),add:require("./add"),angle:require("./angle"),angleDegrees:require("./angleDegrees"),angleRadians:require("./angleRadians"),clone:require("./clone"),copy:require("./copy"),create:require("./create"),cross:require("./cross"),distance:require("./distance"),divide:require("./divide"),dot:require("./dot"),equals:require("./equals"),fromAngleDegrees:require("./fromAngleDegrees"),fromAngleRadians:require("./fromAngleRadians"),fromScalar:require("./fromScalar"),fromValues:require("./fromValues"),length:require("./length"),lerp:require("./lerp"),max:require("./max"),min:require("./min"),multiply:require("./multiply"),negate:require("./negate"),normal:require("./normal"),normalize:require("./normalize"),rotate:require("./rotate"),scale:require("./scale"),snap:require("./snap"),squaredDistance:require("./squaredDistance"),squaredLength:require("./squaredLength"),subtract:require("./subtract"),toString:require("./toString"),transform:require("./transform")};
558
558
 
559
559
  },{"./abs":169,"./add":170,"./angle":171,"./angleDegrees":172,"./angleRadians":173,"./clone":174,"./copy":175,"./create":176,"./cross":177,"./distance":178,"./divide":179,"./dot":180,"./equals":181,"./fromAngleDegrees":182,"./fromAngleRadians":183,"./fromScalar":184,"./fromValues":185,"./length":187,"./lerp":188,"./max":189,"./min":190,"./multiply":191,"./negate":192,"./normal":193,"./normalize":194,"./rotate":195,"./scale":196,"./snap":197,"./squaredDistance":198,"./squaredLength":199,"./subtract":200,"./toString":201,"./transform":202}],187:[function(require,module,exports){
560
- const length=t=>Math.hypot(t[0],t[1]);module.exports=length;
560
+ const length=t=>Math.sqrt(t[0]*t[0]+t[1]*t[1]);module.exports=length;
561
561
 
562
562
  },{}],188:[function(require,module,exports){
563
563
  const lerp=(e,r,o,t)=>{const l=r[0],n=r[1];return e[0]=l+t*(o[0]-l),e[1]=n+t*(o[1]-n),e};module.exports=lerp;
@@ -611,7 +611,7 @@ const abs=(a,s)=>(a[0]=Math.abs(s[0]),a[1]=Math.abs(s[1]),a[2]=Math.abs(s[2]),a)
611
611
  const add=(d,o,a)=>(d[0]=o[0]+a[0],d[1]=o[1]+a[1],d[2]=o[2]+a[2],d);module.exports=add;
612
612
 
613
613
  },{}],205:[function(require,module,exports){
614
- const dot=require("./dot"),angle=(t,o)=>{const a=t[0],e=t[1],h=t[2],n=o[0],r=o[1],M=o[2],d=Math.hypot(a,e,h)*Math.hypot(n,r,M),s=d&&dot(t,o)/d;return Math.acos(Math.min(Math.max(s,-1),1))};module.exports=angle;
614
+ const dot=require("./dot"),angle=(t,a)=>{const o=t[0],e=t[1],r=t[2],n=a[0],s=a[1],h=a[2],M=Math.sqrt(o*o+e*e+r*r)*Math.sqrt(n*n+s*s+h*h),d=M&&dot(t,a)/M;return Math.acos(Math.min(Math.max(d,-1),1))};module.exports=angle;
615
615
 
616
616
  },{"./dot":212}],206:[function(require,module,exports){
617
617
  const create=require("./create"),clone=e=>{const r=create();return r[0]=e[0],r[1]=e[1],r[2]=e[2],r};module.exports=clone;
@@ -626,7 +626,7 @@ const create=()=>[0,0,0];module.exports=create;
626
626
  const cross=(s,o,r)=>{const c=o[0],t=o[1],e=o[2],n=r[0],u=r[1],d=r[2];return s[0]=t*d-e*u,s[1]=e*n-c*d,s[2]=c*u-t*n,s};module.exports=cross;
627
627
 
628
628
  },{}],210:[function(require,module,exports){
629
- const distance=(t,e)=>{const n=e[0]-t[0],o=e[1]-t[1],s=e[2]-t[2];return Math.hypot(n,o,s)};module.exports=distance;
629
+ const distance=(t,s)=>{const e=s[0]-t[0],n=s[1]-t[1],c=s[2]-t[2];return Math.sqrt(e*e+n*n+c*c)};module.exports=distance;
630
630
 
631
631
  },{}],211:[function(require,module,exports){
632
632
  const divide=(d,e,i)=>(d[0]=e[0]/i[0],d[1]=e[1]/i[1],d[2]=e[2]/i[2],d);module.exports=divide;
@@ -650,7 +650,7 @@ const fromVector2=(o,r,e=0)=>(o[0]=r[0],o[1]=r[1],o[2]=e,o);module.exports=fromV
650
650
  module.exports={abs:require("./abs"),add:require("./add"),angle:require("./angle"),clone:require("./clone"),copy:require("./copy"),create:require("./create"),cross:require("./cross"),distance:require("./distance"),divide:require("./divide"),dot:require("./dot"),equals:require("./equals"),fromScalar:require("./fromScalar"),fromValues:require("./fromValues"),fromVec2:require("./fromVec2"),length:require("./length"),lerp:require("./lerp"),max:require("./max"),min:require("./min"),multiply:require("./multiply"),negate:require("./negate"),normalize:require("./normalize"),orthogonal:require("./orthogonal"),rotateX:require("./rotateX"),rotateY:require("./rotateY"),rotateZ:require("./rotateZ"),scale:require("./scale"),snap:require("./snap"),squaredDistance:require("./squaredDistance"),squaredLength:require("./squaredLength"),subtract:require("./subtract"),toString:require("./toString"),transform:require("./transform")};
651
651
 
652
652
  },{"./abs":203,"./add":204,"./angle":205,"./clone":206,"./copy":207,"./create":208,"./cross":209,"./distance":210,"./divide":211,"./dot":212,"./equals":213,"./fromScalar":214,"./fromValues":215,"./fromVec2":216,"./length":218,"./lerp":219,"./max":220,"./min":221,"./multiply":222,"./negate":223,"./normalize":224,"./orthogonal":225,"./rotateX":226,"./rotateY":227,"./rotateZ":228,"./scale":229,"./snap":230,"./squaredDistance":231,"./squaredLength":232,"./subtract":233,"./toString":234,"./transform":235}],218:[function(require,module,exports){
653
- const length=t=>{const e=t[0],n=t[1],o=t[2];return Math.hypot(e,n,o)};module.exports=length;
653
+ const length=t=>{const e=t[0],n=t[1],o=t[2];return Math.sqrt(e*e+n*n+o*o)};module.exports=length;
654
654
 
655
655
  },{}],219:[function(require,module,exports){
656
656
  const lerp=(e,l,o,p)=>(e[0]=l[0]+p*(o[0]-l[0]),e[1]=l[1]+p*(o[1]-l[1]),e[2]=l[2]+p*(o[2]-l[2]),e);module.exports=lerp;
@@ -820,8 +820,8 @@ const vec3=require("../../maths/vec3"),geom2=require("../../geometries/geom2"),g
820
820
  },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/vec3":217}],274:[function(require,module,exports){
821
821
  const plane=require("../../../maths/plane"),poly3=require("../../../geometries/poly3");class Node{constructor(e){this.plane=null,this.front=null,this.back=null,this.polygontreenodes=[],this.parent=e}invert(){const e=[this];let o;for(let n=0;n<e.length;n++){(o=e[n]).plane&&(o.plane=plane.flip(plane.create(),o.plane)),o.front&&e.push(o.front),o.back&&e.push(o.back);const t=o.front;o.front=o.back,o.back=t}}clipPolygons(e,o){let n,t={node:this,polygontreenodes:e};const l=[];do{if(n=t.node,e=t.polygontreenodes,n.plane){const t=n.plane,s=[],p=[],r=o?s:p,d=e.length;for(let o=0;o<d;o++){const n=e[o];n.isRemoved()||n.splitByPlane(t,r,s,p,s)}n.front&&p.length>0&&l.push({node:n.front,polygontreenodes:p});const h=s.length;if(n.back&&h>0)l.push({node:n.back,polygontreenodes:s});else for(let e=0;e<h;e++)s[e].remove()}t=l.pop()}while(void 0!==t)}clipTo(e,o){let n=this;const t=[];do{n.polygontreenodes.length>0&&e.rootnode.clipPolygons(n.polygontreenodes,o),n.front&&t.push(n.front),n.back&&t.push(n.back),n=t.pop()}while(void 0!==n)}addPolygonTreeNodes(e){let o={node:this,polygontreenodes:e};const n=[];do{const e=o.node,t=o.polygontreenodes;if(0===t.length){o=n.pop();continue}if(!e.plane){let o=0;const n=t[o=Math.floor(t.length/2)].getPolygon();e.plane=poly3.plane(n)}const l=[],s=[],p=t.length;for(let o=0;o<p;++o)t[o].splitByPlane(e.plane,e.polygontreenodes,s,l,s);if(l.length>0){e.front||(e.front=new Node(e)),p===l.length&&0===s.length?e.front.polygontreenodes=l:n.push({node:e.front,polygontreenodes:l})}if(s.length>0){e.back||(e.back=new Node(e)),p===s.length&&0===l.length?e.back.polygontreenodes=s:n.push({node:e.back,polygontreenodes:s})}o=n.pop()}while(void 0!==o)}}module.exports=Node;
822
822
 
823
- },{"../../../geometries/poly3":75,"../../../maths/plane":159}],275:[function(require,module,exports){
824
- const{EPS:EPS}=require("../../../maths/constants"),vec3=require("../../../maths/vec3"),poly3=require("../../../geometries/poly3"),splitPolygonByPlane=require("./splitPolygonByPlane");class PolygonTreeNode{constructor(e,t){this.parent=e,this.children=[],this.polygon=t,this.removed=!1}addPolygons(e){if(!this.isRootNode())throw new Error("Assertion failed");const t=this;e.forEach(e=>{t.addChild(e)})}remove(){if(!this.removed){this.removed=!0,this.polygon=null;const e=this.parent.children,t=e.indexOf(this);if(t<0)throw new Error("Assertion failed");e.splice(t,1),this.parent.recursivelyInvalidatePolygon()}}isRemoved(){return this.removed}isRootNode(){return!this.parent}invert(){if(!this.isRootNode())throw new Error("Assertion failed");this.invertSub()}getPolygon(){if(!this.polygon)throw new Error("Assertion failed");return this.polygon}getPolygons(e){let t=[this];const o=[t];let n,l,s,i;for(n=0;n<o.length;++n)for(l=0,s=(t=o[n]).length;l<s;l++)(i=t[l]).polygon?e.push(i.polygon):i.children.length>0&&o.push(i.children)}splitByPlane(e,t,o,n,l){if(this.children.length){const s=[this.children];let i,r,h,c,d;for(i=0;i<s.length;i++)for(d=s[i],r=0,h=d.length;r<h;r++)(c=d[r]).children.length>0?s.push(c.children):c._splitByPlane(e,t,o,n,l)}else this._splitByPlane(e,t,o,n,l)}_splitByPlane(e,t,o,n,l){const s=this.polygon;if(s){const i=poly3.measureBoundingSphere(s),r=i[1]+EPS,h=i[0],c=vec3.dot(e,h)-e[3];if(c>r)n.push(this);else if(c<-r)l.push(this);else{const i=splitPolygonByPlane(e,s);switch(i.type){case 0:t.push(this);break;case 1:o.push(this);break;case 2:n.push(this);break;case 3:l.push(this);break;case 4:if(i.front){const e=this.addChild(i.front);n.push(e)}if(i.back){const e=this.addChild(i.back);l.push(e)}}}}}addChild(e){const t=new PolygonTreeNode(this,e);return this.children.push(t),t}invertSub(){let e=[this];const t=[e];let o,n,l,s;for(o=0;o<t.length;o++)for(n=0,l=(e=t[o]).length;n<l;n++)(s=e[n]).polygon&&(s.polygon=poly3.invert(s.polygon)),s.children.length>0&&t.push(s.children)}recursivelyInvalidatePolygon(){this.polygon=null,this.parent&&this.parent.recursivelyInvalidatePolygon()}clear(){let e=[this];const t=[e];for(let o=0;o<t.length;++o){const n=(e=t[o]).length;for(let o=0;o<n;o++){const n=e[o];n.polygon&&(n.polygon=null),n.parent&&(n.parent=null),n.children.length>0&&t.push(n.children),n.children=[]}}}toString(){let e="",t=[this];const o=[t];let n,l,s,i;for(n=0;n<o.length;++n){t=o[n];const r=" ".repeat(n);for(l=0,s=t.length;l<s;l++)e+=`${r}PolygonTreeNode (${(i=t[l]).isRootNode()}): ${i.children.length}`,i.polygon?e+=`\n ${r}polygon: ${i.polygon.vertices}\n`:e+="\n",i.children.length>0&&o.push(i.children)}return e}}module.exports=PolygonTreeNode;
823
+ },{"../../../geometries/poly3":75,"../../../maths/plane":158}],275:[function(require,module,exports){
824
+ const{EPS:EPS}=require("../../../maths/constants"),vec3=require("../../../maths/vec3"),poly3=require("../../../geometries/poly3"),splitPolygonByPlane=require("./splitPolygonByPlane");class PolygonTreeNode{constructor(e,t){this.parent=e,this.children=[],this.polygon=t,this.removed=!1}addPolygons(e){if(!this.isRootNode())throw new Error("Assertion failed");const t=this;e.forEach(e=>{t.addChild(e)})}remove(){if(!this.removed){this.removed=!0,this.polygon=null;const e=this.parent.children,t=e.indexOf(this);if(t<0)throw new Error("Assertion failed");e.splice(t,1),this.parent.recursivelyInvalidatePolygon()}}isRemoved(){return this.removed}isRootNode(){return!this.parent}invert(){if(!this.isRootNode())throw new Error("Assertion failed");this.invertSub()}getPolygon(){if(!this.polygon)throw new Error("Assertion failed");return this.polygon}getPolygons(e){let t=[this];const o=[t];let n,l,s,i;for(n=0;n<o.length;++n)for(l=0,s=(t=o[n]).length;l<s;l++)(i=t[l]).polygon?e.push(i.polygon):i.children.length>0&&o.push(i.children)}splitByPlane(e,t,o,n,l){if(this.children.length){const s=[this.children];let i,r,h,c,d;for(i=0;i<s.length;i++)for(d=s[i],r=0,h=d.length;r<h;r++)(c=d[r]).children.length>0?s.push(c.children):c._splitByPlane(e,t,o,n,l)}else this._splitByPlane(e,t,o,n,l)}_splitByPlane(e,t,o,n,l){const s=this.polygon;if(s){const i=poly3.measureBoundingSphere(s),r=i[3]+EPS,h=i,c=vec3.dot(e,h)-e[3];if(c>r)n.push(this);else if(c<-r)l.push(this);else{const i=splitPolygonByPlane(e,s);switch(i.type){case 0:t.push(this);break;case 1:o.push(this);break;case 2:n.push(this);break;case 3:l.push(this);break;case 4:if(i.front){const e=this.addChild(i.front);n.push(e)}if(i.back){const e=this.addChild(i.back);l.push(e)}}}}}addChild(e){const t=new PolygonTreeNode(this,e);return this.children.push(t),t}invertSub(){let e=[this];const t=[e];let o,n,l,s;for(o=0;o<t.length;o++)for(n=0,l=(e=t[o]).length;n<l;n++)(s=e[n]).polygon&&(s.polygon=poly3.invert(s.polygon)),s.children.length>0&&t.push(s.children)}recursivelyInvalidatePolygon(){this.polygon=null,this.parent&&this.parent.recursivelyInvalidatePolygon()}clear(){let e=[this];const t=[e];for(let o=0;o<t.length;++o){const n=(e=t[o]).length;for(let o=0;o<n;o++){const n=e[o];n.polygon&&(n.polygon=null),n.parent&&(n.parent=null),n.children.length>0&&t.push(n.children),n.children=[]}}}toString(){let e="",t=[this];const o=[t];let n,l,s,i;for(n=0;n<o.length;++n){t=o[n];const r=" ".repeat(n);for(l=0,s=t.length;l<s;l++)e+=`${r}PolygonTreeNode (${(i=t[l]).isRootNode()}): ${i.children.length}`,i.polygon?e+=`\n ${r}polygon: ${i.polygon.vertices}\n`:e+="\n",i.children.length>0&&o.push(i.children)}return e}}module.exports=PolygonTreeNode;
825
825
 
826
826
  },{"../../../geometries/poly3":75,"../../../maths/constants":90,"../../../maths/vec3":217,"./splitPolygonByPlane":279}],276:[function(require,module,exports){
827
827
  const Node=require("./Node"),PolygonTreeNode=require("./PolygonTreeNode");class Tree{constructor(o){this.polygonTree=new PolygonTreeNode,this.rootnode=new Node(null),o&&this.addPolygons(o)}invert(){this.polygonTree.invert(),this.rootnode.invert()}clipTo(o,e=!1){this.rootnode.clipTo(o,e)}allPolygons(){const o=[];return this.polygonTree.getPolygons(o),o}addPolygons(o){const e=new Array(o.length);for(let r=0;r<o.length;r++)e[r]=this.polygonTree.addChild(o[r]);this.rootnode.addPolygonTreeNodes(e)}clear(){this.polygonTree.clear()}toString(){return"Tree: "+this.polygonTree.toString("")}}module.exports=Tree;
@@ -835,7 +835,7 @@ const vec3=require("../../../maths/vec3"),splitLineSegmentByPlane=(e,t,c)=>{cons
835
835
  },{"../../../maths/vec3":217}],279:[function(require,module,exports){
836
836
  const{EPS:EPS}=require("../../../maths/constants"),plane=require("../../../maths/plane"),vec3=require("../../../maths/vec3"),poly3=require("../../../geometries/poly3"),splitLineSegmentByPlane=require("./splitLineSegmentByPlane"),splitPolygonByPlane=(e,t)=>{const l={type:null,front:null,back:null},n=t.vertices,s=n.length,o=poly3.plane(t);if(plane.equals(o,e))l.type=0;else{let t=!1,p=!1;const i=[],c=-EPS;for(let l=0;l<s;l++){const s=vec3.dot(e,n[l])-e[3],o=s<c;i.push(o),s>EPS&&(t=!0),s<c&&(p=!0)}if(t||p)if(p)if(t){l.type=4;const t=[],p=[];let c=i[0];for(let l=0;l<s;l++){const o=n[l];let r=l+1;r>=s&&(r=0);const a=i[r];if(c===a)c?p.push(o):t.push(o);else{const l=n[r],s=splitLineSegmentByPlane(e,o,l);c?(p.push(o),p.push(s),t.push(s)):(t.push(o),t.push(s),p.push(s))}c=a}const r=EPS*EPS;if(p.length>=3){let e=p[p.length-1];for(let t=0;t<p.length;t++){const l=p[t];vec3.squaredDistance(l,e)<r&&(p.splice(t,1),t--),e=l}}if(t.length>=3){let e=t[t.length-1];for(let l=0;l<t.length;l++){const n=t[l];vec3.squaredDistance(n,e)<r&&(t.splice(l,1),l--),e=n}}t.length>=3&&(l.front=poly3.fromPointsAndPlane(t,o)),p.length>=3&&(l.back=poly3.fromPointsAndPlane(p,o))}else l.type=3;else l.type=2;else{const t=vec3.dot(e,o);l.type=t>=0?0:1}}return l};module.exports=splitPolygonByPlane;
837
837
 
838
- },{"../../../geometries/poly3":75,"../../../maths/constants":90,"../../../maths/plane":159,"../../../maths/vec3":217,"./splitLineSegmentByPlane":278}],280:[function(require,module,exports){
838
+ },{"../../../geometries/poly3":75,"../../../maths/constants":90,"../../../maths/plane":158,"../../../maths/vec3":217,"./splitLineSegmentByPlane":278}],280:[function(require,module,exports){
839
839
  const flatten=require("../../utils/flatten"),areAllShapesTheSameType=require("../../utils/areAllShapesTheSameType"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),unionGeom2=require("./unionGeom2"),unionGeom3=require("./unionGeom3"),union=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");if(!areAllShapesTheSameType(e))throw new Error("only unions of the same type are supported");const o=e[0];return geom2.isA(o)?unionGeom2(e):geom3.isA(o)?unionGeom3(e):o};module.exports=union;
840
840
 
841
841
  },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../utils/areAllShapesTheSameType":389,"../../utils/flatten":391,"./unionGeom2":281,"./unionGeom3":282}],281:[function(require,module,exports){
@@ -859,13 +859,13 @@ const geom3=require("../../geometries/geom3"),union=require("../booleans/union")
859
859
  },{"../../geometries/geom3":37,"../booleans/union":280,"./expandShell":288}],287:[function(require,module,exports){
860
860
  const area=require("../../maths/utils/area"),vec2=require("../../maths/vec2"),geom2=require("../../geometries/geom2"),path2=require("../../geometries/path2"),offsetFromPoints=require("./offsetFromPoints"),createGeometryFromClosedOffsets=e=>{let{external:t,internal:r}=e;area(t)<0?t=t.reverse():r=r.reverse();const o=path2.fromPoints({closed:!0},t),s=path2.fromPoints({closed:!0},r),n=geom2.toSides(geom2.fromPoints(path2.toPoints(o))),a=geom2.toSides(geom2.fromPoints(path2.toPoints(s)));return n.push(...a),geom2.create(n)},createGeometryFromExpandedOpenPath=(e,t,r,o)=>{const{points:s,external:n,internal:a}=e,c=Math.floor(t/2),m=[],i=[];if("round"===r&&c>0){const e=Math.PI/c,t=s[s.length-1],r=vec2.angle(vec2.subtract(vec2.create(),n[n.length-1],t)),d=s[0],l=vec2.angle(vec2.subtract(vec2.create(),a[0],d));for(let s=1;s<c;s++){let n=r+e*s,a=vec2.fromAngleRadians(vec2.create(),n);vec2.scale(a,a,o),vec2.add(a,a,t),m.push(a),n=l+e*s,a=vec2.fromAngleRadians(vec2.create(),n),vec2.scale(a,a,o),vec2.add(a,a,d),i.push(a)}}const d=[];return d.push(...n,...m,...a.reverse(),...i),geom2.fromPoints(d)},expandPath2=(e,t)=>{e=Object.assign({},{delta:1,corners:"edge",segments:16},e);const{delta:r,corners:o,segments:s}=e;if(r<=0)throw new Error("the given delta must be positive for paths");if("edge"!==o&&"chamfer"!==o&&"round"!==o)throw new Error('corners must be "edge", "chamfer", or "round"');const n=t.isClosed,a=path2.toPoints(t);if(0===a.length)throw new Error("the given geometry cannot be empty");const c={points:a,external:offsetFromPoints({delta:r,corners:o,segments:s,closed:n},a),internal:offsetFromPoints({delta:-r,corners:o,segments:s,closed:n},a)};return t.isClosed?createGeometryFromClosedOffsets(c):createGeometryFromExpandedOpenPath(c,s,o,r)};module.exports=expandPath2;
861
861
 
862
- },{"../../geometries/geom2":22,"../../geometries/path2":58,"../../maths/utils/area":164,"../../maths/vec2":186,"./offsetFromPoints":292}],288:[function(require,module,exports){
862
+ },{"../../geometries/geom2":22,"../../geometries/path2":58,"../../maths/utils/area":163,"../../maths/vec2":186,"./offsetFromPoints":292}],288:[function(require,module,exports){
863
863
  const{EPS:EPS}=require("../../maths/constants"),mat4=require("../../maths/mat4"),vec3=require("../../maths/vec3"),fnNumberSort=require("../../utils/fnNumberSort"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),sphere=require("../../primitives/sphere"),retessellate=require("../modifiers/retessellate"),unionGeom3Sub=require("../booleans/unionGeom3Sub"),extrudePolygon=require("./extrudePolygon"),mapPlaneToVertex=(e,t,o)=>{const n=t.toString();if(e.has(n)){e.get(n)[1].push(o)}else{const s=[t,[o]];e.set(n,s)}},mapPlaneToEdge=(e,t,o)=>{const n=t[0].toString(),s=t[1].toString(),r=n<s?`${n},${s}`:`${s},${n}`;if(e.has(r)){e.get(r)[1].push(o)}else{const n=[t,[o]];e.set(r,n)}},addUniqueAngle=(e,t)=>{e.findIndex(e=>e===t)<0&&e.push(t)},expandShell=(e,t)=>{const{delta:o,segments:n}=Object.assign({},{delta:1,segments:12},e);let s=geom3.create();const r=new Map,c=new Map,a=vec3.create(),l=vec3.create();return geom3.toPolygons(t).forEach((e,t)=>{const n=vec3.scale(vec3.create(),poly3.plane(e),2*o),a=poly3.transform(mat4.fromTranslation(mat4.create(),vec3.scale(vec3.create(),n,-.5)),e),l=extrudePolygon(n,a);s=unionGeom3Sub(s,l);const u=e.vertices;for(let t=0;t<u.length;t++){mapPlaneToVertex(r,u[t],poly3.plane(e));const o=(t+1)%u.length,n=[u[t],u[o]];mapPlaneToEdge(c,n,poly3.plane(e))}}),c.forEach(e=>{const t=e[0],r=e[1],c=t[0],u=t[1],i=vec3.subtract(vec3.create(),u,c);vec3.normalize(i,i);const m=r[0],h=vec3.cross(vec3.create(),m,i);let g=[];for(let e=0;e<n;e++)addUniqueAngle(g,e*Math.PI*2/n);for(let e=0,t=r.length;e<t;e++){const t=r[e],o=vec3.dot(h,t),n=vec3.dot(m,t);let s=Math.atan2(o,n);s<0&&(s+=2*Math.PI),addUniqueAngle(g,s),(s=Math.atan2(-o,-n))<0&&(s+=2*Math.PI),addUniqueAngle(g,s)}const p=(g=g.sort(fnNumberSort)).length;let v,d;const f=[],S=[],q=[];for(let e=-1;e<p;e++){const t=g[e<0?e+p:e],n=Math.sin(t),s=Math.cos(t);vec3.scale(a,m,s*o),vec3.scale(l,h,n*o),vec3.add(a,a,l);const r=vec3.add(vec3.create(),c,a),i=vec3.add(vec3.create(),u,a);let P=!1;if(e>=0&&vec3.distance(r,v)<EPS&&(P=!0),!P){if(e>=0){f.push(r),S.push(i);const e=[d,i,r,v],t=poly3.create(e);q.push(t)}v=r,d=i}}S.reverse(),q.push(poly3.create(f)),q.push(poly3.create(S));const P=geom3.create(q);s=unionGeom3Sub(s,P)}),r.forEach(e=>{const t=e[0],r=e[1],c=r[0];let u=null,i=0;for(let e=1;e<r.length;e++){const t=r[e],o=vec3.cross(a,c,t),n=vec3.length(o);n>.05&&n>i&&(i=n,u=t)}u||(u=vec3.orthogonal(a,c));const m=vec3.cross(a,c,u);vec3.normalize(m,m);const h=vec3.cross(l,m,c),g=sphere({center:[t[0],t[1],t[2]],radius:o,segments:n,axes:[c,m,h]});s=unionGeom3Sub(s,g)}),retessellate(s)};module.exports=expandShell;
864
864
 
865
- },{"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/constants":90,"../../maths/mat4":140,"../../maths/vec3":217,"../../primitives/sphere":379,"../../utils/fnNumberSort":392,"../booleans/unionGeom3Sub":283,"../modifiers/retessellate":349,"./extrudePolygon":289}],289:[function(require,module,exports){
865
+ },{"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/constants":90,"../../maths/mat4":139,"../../maths/vec3":217,"../../primitives/sphere":379,"../../utils/fnNumberSort":392,"../booleans/unionGeom3Sub":283,"../modifiers/retessellate":349,"./extrudePolygon":289}],289:[function(require,module,exports){
866
866
  const mat4=require("../../maths/mat4"),vec3=require("../../maths/vec3"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),extrudePolygon=(e,r)=>{vec3.dot(poly3.plane(r),e)>0&&(r=poly3.invert(r));const t=[r],o=poly3.transform(mat4.fromTranslation(mat4.create(),e),r),s=r.vertices.length;for(let e=0;e<s;e++){const c=e<s-1?e+1:0,i=poly3.create([r.vertices[e],o.vertices[e],o.vertices[c],r.vertices[c]]);t.push(i)}return t.push(poly3.invert(o)),geom3.create(t)};module.exports=extrudePolygon;
867
867
 
868
- },{"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/mat4":140,"../../maths/vec3":217}],290:[function(require,module,exports){
868
+ },{"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/mat4":139,"../../maths/vec3":217}],290:[function(require,module,exports){
869
869
  module.exports={expand:require("./expand"),offset:require("./offset")};
870
870
 
871
871
  },{"./expand":284,"./offset":291}],291:[function(require,module,exports){
@@ -874,7 +874,7 @@ const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geo
874
874
  },{"../../geometries/geom2":22,"../../geometries/path2":58,"../../utils/flatten":391,"./offsetGeom2":293,"./offsetPath2":294}],292:[function(require,module,exports){
875
875
  const{EPS:EPS}=require("../../maths/constants"),intersect=require("../../maths/utils/intersect"),line2=require("../../maths/line2"),vec2=require("../../maths/vec2"),area=require("../../maths/utils/area"),offsetFromPoints=(e,t)=>{let{delta:s,corners:c,closed:n,segments:a}=Object.assign({},{delta:1,corners:"edge",closed:!1,segments:16},e);if(Math.abs(s)<EPS)return t;let r=e.closed?area(t):1;0===r&&(r=1);const o=r>0&&s>=0||r<0&&s<0;s=Math.abs(s);let i=null,l=[];const u=[],v=vec2.create(),f=t.length;for(let e=0;e<f;e++){const c=(e+1)%f,a=t[e],r=t[c];o?vec2.subtract(v,a,r):vec2.subtract(v,r,a),vec2.normal(v,v),vec2.normalize(v,v),vec2.scale(v,v,s);const h=vec2.add(vec2.create(),a,v),d=vec2.add(vec2.create(),r,v),m=[h,d];if(null!=i&&(n||!n&&0!==c)){const e=intersect(i[0],i[1],m[0],m[1]);e?(l.pop(),m[0]=e):u.push({c:a,s0:i,s1:m})}i=[h,d],(0!==c||n)&&(l.push(m[0]),l.push(m[1]))}if(n&&null!=i){const e=l[0],s=l[1],c=intersect(i[0],i[1],e,s);if(c)l[0]=c,l.pop();else{const c=t[0],n=[e,s];u.push({c:c,s0:i,s1:n})}}if("edge"===c){const e=new Map;l.forEach((t,s)=>e.set(t,s));const t=line2.create(),s=line2.create();u.forEach(c=>{line2.fromPoints(t,c.s0[0],c.s0[1]),line2.fromPoints(s,c.s1[0],c.s1[1]);const n=line2.intersectPointOfLines(t,s);if(Number.isFinite(n[0])&&Number.isFinite(n[1])){const t=c.s0[1],s=e.get(t);l[s]=n,l[(s+1)%l.length]=void 0}else{const t=c.s1[0],s=e.get(t);l[s]=void 0}}),l=l.filter(e=>void 0!==e)}if("round"===c){let e=Math.floor(a/4);const t=vec2.create();u.forEach(c=>{let n=vec2.angle(vec2.subtract(t,c.s1[0],c.c));if(n-=vec2.angle(vec2.subtract(t,c.s0[1],c.c)),o&&n<0&&(n+=Math.PI)<0&&(n+=Math.PI),!o&&n>0&&(n-=Math.PI)>0&&(n-=Math.PI),0!==n){const r=n/(e=Math.floor(a*(Math.abs(n)/(2*Math.PI)))),o=vec2.angle(vec2.subtract(t,c.s0[1],c.c)),i=[];for(let t=1;t<e;t++){const e=o+r*t,n=vec2.fromAngleRadians(vec2.create(),e);vec2.scale(n,n,s),vec2.add(n,n,c.c),i.push(n)}if(i.length>0){const e=c.s0[1];let t=l.findIndex(t=>vec2.equals(e,t));t=(t+1)%l.length,l.splice(t,0,...i)}}else{const e=c.s1[0],t=l.findIndex(t=>vec2.equals(e,t));l.splice(t,1)}})}return l};module.exports=offsetFromPoints;
876
876
 
877
- },{"../../maths/constants":90,"../../maths/line2":101,"../../maths/utils/area":164,"../../maths/utils/intersect":167,"../../maths/vec2":186}],293:[function(require,module,exports){
877
+ },{"../../maths/constants":90,"../../maths/line2":101,"../../maths/utils/area":163,"../../maths/utils/intersect":166,"../../maths/vec2":186}],293:[function(require,module,exports){
878
878
  const geom2=require("../../geometries/geom2"),poly2=require("../../geometries/poly2"),offsetFromPoints=require("./offsetFromPoints"),offsetGeom2=(e,o)=>{const{delta:r,corners:s,segments:t}=Object.assign({},{delta:1,corners:"edge",segments:0},e);if("edge"!==s&&"chamfer"!==s&&"round"!==s)throw new Error('corners must be "edge", "chamfer", or "round"');const n=geom2.toOutlines(o),m=n.map(o=>{const m=n.reduce((e,r)=>e+poly2.arePointsInside(o,poly2.create(r)),0);return offsetFromPoints(e={delta:m%2==0?r:-r,corners:s,closed:!0,segments:t},o)}).reduce((e,o)=>e.concat(geom2.toSides(geom2.fromPoints(o))),[]);return geom2.create(m)};module.exports=offsetGeom2;
879
879
 
880
880
  },{"../../geometries/geom2":22,"../../geometries/poly2":69,"./offsetFromPoints":292}],294:[function(require,module,exports){
@@ -883,7 +883,7 @@ const path2=require("../../geometries/path2"),offsetFromPoints=require("./offset
883
883
  },{"../../geometries/path2":58,"./offsetFromPoints":292}],295:[function(require,module,exports){
884
884
  const{area:area}=require("../../../maths/utils"),{toOutlines:toOutlines}=require("../../../geometries/geom2"),{arePointsInside:arePointsInside}=require("../../../geometries/poly2"),assignHoles=e=>{const s=toOutlines(e),o=[],t=[];s.forEach((e,s)=>{const n=area(e);n<0?t.push(s):n>0&&o.push(s)});const n=[],r=[];return o.forEach((e,o)=>{const i=s[e];n[o]=[],t.forEach((e,t)=>{const a=s[e];arePointsInside([a[0]],{vertices:i})&&(n[o].push(e),r[t]||(r[t]=[]),r[t].push(o))})}),t.forEach((e,s)=>{if(r[s]&&r[s].length>1){const o=minIndex(r[s],e=>n[e].length);r[s].forEach((s,t)=>{t!==o&&(n[s]=n[s].filter(s=>s!==e))})}}),n.map((e,t)=>({solid:s[o[t]],holes:e.map(e=>s[e])}))},minIndex=(e,s)=>{let o,t;return e.forEach((e,n)=>{const r=s(e);(void 0===t||r<t)&&(o=n,t=r)}),o};module.exports=assignHoles;
885
885
 
886
- },{"../../../geometries/geom2":22,"../../../geometries/poly2":69,"../../../maths/utils":165}],296:[function(require,module,exports){
886
+ },{"../../../geometries/geom2":22,"../../../geometries/poly2":69,"../../../maths/utils":164}],296:[function(require,module,exports){
887
887
  const{filterPoints:filterPoints,linkedPolygon:linkedPolygon,locallyInside:locallyInside,splitPolygon:splitPolygon}=require("./linkedPolygon"),{area:area,pointInTriangle:pointInTriangle}=require("./triangle"),eliminateHoles=(e,t,n,l)=>{const i=[];for(let n=0,o=t.length;n<o;n++){const r=t[n]*l,x=n<o-1?t[n+1]*l:e.length,s=linkedPolygon(e,r,x,l,!1);s===s.next&&(s.steiner=!0),i.push(getLeftmost(s))}i.sort((e,t)=>e.x-t.x);for(let e=0;e<i.length;e++)n=eliminateHole(i[e],n),n=filterPoints(n,n.next);return n},eliminateHole=(e,t)=>{const n=findHoleBridge(e,t);if(!n)return t;const l=splitPolygon(n,e),i=filterPoints(n,n.next);return filterPoints(l,l.next),t===n?i:t},findHoleBridge=(e,t)=>{let n=t;const l=e.x,i=e.y;let o,r=-1/0;do{if(i<=n.y&&i>=n.next.y&&n.next.y!==n.y){const e=n.x+(i-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(e<=l&&e>r){if(r=e,e===l){if(i===n.y)return n;if(i===n.next.y)return n.next}o=n.x<n.next.x?n:n.next}}n=n.next}while(n!==t);if(!o)return null;if(l===r)return o;const x=o,s=o.x,y=o.y;let a=1/0;n=o;do{if(l>=n.x&&n.x>=s&&l!==n.x&&pointInTriangle(i<y?l:r,i,s,y,i<y?r:l,i,n.x,n.y)){const t=Math.abs(i-n.y)/(l-n.x);locallyInside(n,e)&&(t<a||t===a&&(n.x>o.x||n.x===o.x&&sectorContainsSector(o,n)))&&(o=n,a=t)}n=n.next}while(n!==x);return o},sectorContainsSector=(e,t)=>area(e.prev,e,t.prev)<0&&area(t.next,e,e.next)<0,getLeftmost=e=>{let t=e,n=e;do{(t.x<n.x||t.x===n.x&&t.y<n.y)&&(n=t),t=t.next}while(t!==e);return n};module.exports=eliminateHoles;
888
888
 
889
889
  },{"./linkedPolygon":300,"./triangle":302}],297:[function(require,module,exports){
@@ -901,19 +901,19 @@ const{Node:Node,insertNode:insertNode,removeNode:removeNode}=require("./linkedLi
901
901
  },{"./linkedList":298,"./triangle":302}],301:[function(require,module,exports){
902
902
  const geom2=require("../../../geometries/geom2"),plane=require("../../../maths/plane"),vec2=require("../../../maths/vec2"),vec3=require("../../../maths/vec3"),calculatePlane=require("../slice/calculatePlane"),assignHoles=require("./assignHoles");class PolygonHierarchy{constructor(e){this.plane=calculatePlane(e);const s=vec3.orthogonal(vec3.create(),this.plane),c=vec3.cross(vec3.create(),this.plane,s);this.v=vec3.normalize(c,c),this.u=vec3.cross(vec3.create(),this.v,this.plane),this.basisMap=new Map;const t=e.edges.map(e=>e.map(e=>this.to2D(e))),a=geom2.create(t);this.roots=assignHoles(a)}to2D(e){const s=vec2.fromValues(vec3.dot(e,this.u),vec3.dot(e,this.v));return this.basisMap.set(s,e),s}to3D(e){const s=this.basisMap.get(e);if(s)return s;{console.log("Warning: point not in original slice");const s=vec3.scale(vec3.create(),this.u,e[0]),c=vec3.scale(vec3.create(),this.v,e[1]),t=vec3.scale(vec3.create(),plane,plane[3]),a=vec3.add(s,s,t);return vec3.add(c,c,a)}}}module.exports=PolygonHierarchy;
903
903
 
904
- },{"../../../geometries/geom2":22,"../../../maths/plane":159,"../../../maths/vec2":186,"../../../maths/vec3":217,"../slice/calculatePlane":314,"./assignHoles":295}],302:[function(require,module,exports){
904
+ },{"../../../geometries/geom2":22,"../../../maths/plane":158,"../../../maths/vec2":186,"../../../maths/vec3":217,"../slice/calculatePlane":314,"./assignHoles":295}],302:[function(require,module,exports){
905
905
  const pointInTriangle=(n,a,e,r,i,o,t,x)=>(i-t)*(a-x)-(n-t)*(o-x)>=0&&(n-t)*(r-x)-(e-t)*(a-x)>=0&&(e-t)*(o-x)-(i-t)*(r-x)>=0,area=(n,a,e)=>(a.y-n.y)*(e.x-a.x)-(a.x-n.x)*(e.y-a.y);module.exports={area:area,pointInTriangle:pointInTriangle};
906
906
 
907
907
  },{}],303:[function(require,module,exports){
908
- const mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),slice=require("./slice"),repairSlice=require("./slice/repairSlice"),extrudeWalls=require("./extrudeWalls"),defaultCallback=(e,r,l)=>{let t=null;return geom2.isA(l)&&(t=slice.fromSides(geom2.toSides(l))),poly3.isA(l)&&(t=slice.fromPoints(poly3.toPoints(l))),0===e||1===e?slice.transform(mat4.fromTranslation(mat4.create(),[0,0,e]),t):null},extrudeFromSlices=(e,r)=>{const l={numberOfSlices:2,capStart:!0,capEnd:!0,close:!1,repair:!0,callback:defaultCallback},{numberOfSlices:t,capStart:o,capEnd:c,close:s,repair:i,callback:a}=Object.assign({},l,e);if(t<2)throw new Error("numberOfSlices must be 2 or more");i&&repairSlice(r);const n=t-1;let u=null,m=null,f=null,g=[];for(let e=0;e<t;e++){const l=a(e/n,e,r);if(l){if(!slice.isA(l))throw new Error("the callback function must return slice objects");if(0===slice.toEdges(l).length)throw new Error("the callback function must return slices with one or more edges");f&&(g=g.concat(extrudeWalls(f,l))),0===e&&(u=l),e===t-1&&(m=l),f=l}}if(c){const e=slice.toPolygons(m);g=g.concat(e)}if(o){const e=slice.toPolygons(u).map(poly3.invert);g=g.concat(e)}return o||c||s&&!slice.equals(m,u)&&(g=g.concat(extrudeWalls(m,u))),geom3.create(g)};module.exports=extrudeFromSlices;
908
+ const mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),slice=require("./slice"),repairSlice=require("./slice/repair"),extrudeWalls=require("./extrudeWalls"),defaultCallback=(e,r,l)=>{let t=null;return geom2.isA(l)&&(t=slice.fromSides(geom2.toSides(l))),poly3.isA(l)&&(t=slice.fromPoints(poly3.toPoints(l))),0===e||1===e?slice.transform(mat4.fromTranslation(mat4.create(),[0,0,e]),t):null},extrudeFromSlices=(e,r)=>{const l={numberOfSlices:2,capStart:!0,capEnd:!0,close:!1,repair:!0,callback:defaultCallback},{numberOfSlices:t,capStart:o,capEnd:c,close:s,repair:i,callback:a}=Object.assign({},l,e);if(t<2)throw new Error("numberOfSlices must be 2 or more");i&&(r=repairSlice(r));const n=t-1;let u=null,m=null,f=null,g=[];for(let e=0;e<t;e++){const l=a(e/n,e,r);if(l){if(!slice.isA(l))throw new Error("the callback function must return slice objects");if(0===slice.toEdges(l).length)throw new Error("the callback function must return slices with one or more edges");f&&(g=g.concat(extrudeWalls(f,l))),0===e&&(u=l),e===t-1&&(m=l),f=l}}if(c){const e=slice.toPolygons(m);g=g.concat(e)}if(o){const e=slice.toPolygons(u).map(poly3.invert);g=g.concat(e)}return o||c||s&&!slice.equals(m,u)&&(g=g.concat(extrudeWalls(m,u))),geom3.create(g)};module.exports=extrudeFromSlices;
909
909
 
910
- },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/mat4":140,"./extrudeWalls":311,"./slice":320,"./slice/repairSlice":322}],304:[function(require,module,exports){
910
+ },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/mat4":139,"./extrudeWalls":311,"./slice":320,"./slice/repair":322}],304:[function(require,module,exports){
911
911
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),path2=require("../../geometries/path2"),extrudeLinearGeom2=require("./extrudeLinearGeom2"),extrudeLinearPath2=require("./extrudeLinearPath2"),extrudeLinear=(e,...t)=>{const{height:r,twistAngle:i,twistSteps:n,repair:a}=Object.assign({},{height:1,twistAngle:0,twistSteps:1,repair:!0},e);if(0===(t=flatten(t)).length)throw new Error("wrong number of arguments");e={offset:[0,0,r],twistAngle:i,twistSteps:n,repair:a};const s=t.map(t=>path2.isA(t)?extrudeLinearPath2(e,t):geom2.isA(t)?extrudeLinearGeom2(e,t):t);return 1===s.length?s[0]:s};module.exports=extrudeLinear;
912
912
 
913
913
  },{"../../geometries/geom2":22,"../../geometries/path2":58,"../../utils/flatten":391,"./extrudeLinearGeom2":305,"./extrudeLinearPath2":306}],305:[function(require,module,exports){
914
914
  const mat4=require("../../maths/mat4"),vec3=require("../../maths/vec3"),geom2=require("../../geometries/geom2"),slice=require("./slice"),extrudeFromSlices=require("./extrudeFromSlices"),extrudeGeom2=(e,t)=>{let{offset:r,twistAngle:s,twistSteps:o,repair:i}=Object.assign({},{offset:[0,0,1],twistAngle:0,twistSteps:12,repair:!0},e);if(o<1)throw new Error("twistSteps must be 1 or more");0===s&&(o=1);const c=vec3.clone(r),m=geom2.toSides(t);if(0===m.length)throw new Error("the given geometry cannot be empty");const a=slice.fromSides(m);c[2]<0&&slice.reverse(a,a);const n=mat4.create();return extrudeFromSlices(e={numberOfSlices:o+1,capStart:!0,capEnd:!0,repair:i,callback:(e,t,r)=>{const i=t/o*s,m=vec3.scale(vec3.create(),c,t/o);return mat4.multiply(n,mat4.fromZRotation(n,i),mat4.fromTranslation(mat4.create(),m)),slice.transform(n,r)}},a)};module.exports=extrudeGeom2;
915
915
 
916
- },{"../../geometries/geom2":22,"../../maths/mat4":140,"../../maths/vec3":217,"./extrudeFromSlices":303,"./slice":320}],306:[function(require,module,exports){
916
+ },{"../../geometries/geom2":22,"../../maths/mat4":139,"../../maths/vec3":217,"./extrudeFromSlices":303,"./slice":320}],306:[function(require,module,exports){
917
917
  const geom2=require("../../geometries/geom2"),path2=require("../../geometries/path2"),extrudeLinearGeom2=require("./extrudeLinearGeom2"),extrudePath2=(e,r)=>{if(!r.isClosed)throw new Error("extruded path must be closed");const t=path2.toPoints(r),o=geom2.fromPoints(t);return extrudeLinearGeom2(e,o)};module.exports=extrudePath2;
918
918
 
919
919
  },{"../../geometries/geom2":22,"../../geometries/path2":58,"./extrudeLinearGeom2":305}],307:[function(require,module,exports){
@@ -922,13 +922,13 @@ const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geo
922
922
  },{"../../geometries/geom2":22,"../../geometries/path2":58,"../../utils/flatten":391,"./extrudeRectangularGeom2":308,"./extrudeRectangularPath2":309}],308:[function(require,module,exports){
923
923
  const{area:area}=require("../../maths/utils"),geom2=require("../../geometries/geom2"),path2=require("../../geometries/path2"),expand=require("../expansions/expand"),extrudeLinearGeom2=require("./extrudeLinearGeom2"),extrudeRectangularGeom2=(e,r)=>{const{size:t,height:o}=Object.assign({},{size:1,height:1},e);e.delta=t,e.offset=[0,0,o];const a=geom2.toOutlines(r);if(0===a.length)throw new Error("the given geometry cannot be empty");const n=a.map(r=>(area(r)<0&&r.reverse(),expand(e,path2.fromPoints({closed:!0},r)))).reduce((e,r)=>e.concat(geom2.toSides(r)),[]),i=geom2.create(n);return extrudeLinearGeom2(e,i)};module.exports=extrudeRectangularGeom2;
924
924
 
925
- },{"../../geometries/geom2":22,"../../geometries/path2":58,"../../maths/utils":165,"../expansions/expand":284,"./extrudeLinearGeom2":305}],309:[function(require,module,exports){
925
+ },{"../../geometries/geom2":22,"../../geometries/path2":58,"../../maths/utils":164,"../expansions/expand":284,"./extrudeLinearGeom2":305}],309:[function(require,module,exports){
926
926
  const path2=require("../../geometries/path2"),expand=require("../expansions/expand"),extrudeLinearGeom2=require("./extrudeLinearGeom2"),extrudeRectangularPath2=(e,t)=>{const{size:r,height:n}=Object.assign({},{size:1,height:1},e);if(e.delta=r,e.offset=[0,0,n],0===path2.toPoints(t).length)throw new Error("the given geometry cannot be empty");const a=expand(e,t);return extrudeLinearGeom2(e,a)};module.exports=extrudeRectangularPath2;
927
927
 
928
928
  },{"../../geometries/path2":58,"../expansions/expand":284,"./extrudeLinearGeom2":305}],310:[function(require,module,exports){
929
929
  const mat4=require("../../maths/mat4"),{mirrorX:mirrorX}=require("../transforms/mirror"),geom2=require("../../geometries/geom2"),slice=require("./slice"),extrudeFromSlices=require("./extrudeFromSlices"),extrudeRotate=(e,t)=>{const r={segments:12,startAngle:0,angle:2*Math.PI,overflow:"cap"};let{segments:a,startAngle:o,angle:s,overflow:m}=Object.assign({},r,e);if(a<3)throw new Error("segments must be greater then 3");o=Math.abs(o)>2*Math.PI?o%(2*Math.PI):o,s=Math.abs(s)>2*Math.PI?s%(2*Math.PI):s;let n=o+s;if((n=Math.abs(n)>2*Math.PI?n%(2*Math.PI):n)<o){const e=o;o=n,n=e}let l=n-o;if(l<=0&&(l=2*Math.PI),Math.abs(l)<2*Math.PI){const e=2*Math.PI/a;a=Math.floor(Math.abs(l)/e),Math.abs(l)>a*e&&a++}let h=geom2.toSides(t);if(0===h.length)throw new Error("the given geometry cannot be empty");const i=h.filter(e=>e[0][0]<0),c=h.filter(e=>e[0][0]>=0);i.length>0&&c.length>0&&"cap"===m&&(i.length>c.length?(h=h.map(e=>{let t=e[0],r=e[1];return[t=[Math.min(t[0],0),t[1]],r=[Math.min(r[0],0),r[1]]]}),t=geom2.reverse(geom2.create(h)),t=mirrorX(t)):c.length>=i.length&&(h=h.map(e=>{let t=e[0],r=e[1];return[t=[Math.max(t[0],0),t[1]],r=[Math.max(r[0],0),r[1]]]}),t=geom2.create(h)));const g=l/a,M=Math.abs(l)<2*Math.PI,u=slice.fromSides(geom2.toSides(t));slice.reverse(u,u);const f=mat4.create();return extrudeFromSlices(e={numberOfSlices:a+1,capStart:M,capEnd:M,close:!M,callback:(e,t,r)=>{let s=g*t+o;return l===2*Math.PI&&t===a&&(s=o),mat4.multiply(f,mat4.fromZRotation(f,s),mat4.fromXRotation(mat4.create(),Math.PI/2)),slice.transform(f,r)}},u)};module.exports=extrudeRotate;
930
930
 
931
- },{"../../geometries/geom2":22,"../../maths/mat4":140,"../transforms/mirror":356,"./extrudeFromSlices":303,"./slice":320}],311:[function(require,module,exports){
931
+ },{"../../geometries/geom2":22,"../../maths/mat4":139,"../transforms/mirror":356,"./extrudeFromSlices":303,"./slice":320}],311:[function(require,module,exports){
932
932
  const{EPS:EPS}=require("../../maths/constants"),vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),slice=require("./slice"),gcd=(e,t)=>e===t?e:e<t?gcd(t,e):1===t?1:0===t?e:gcd(t,e%t),lcm=(e,t)=>e*t/gcd(e,t),repartitionEdges=(e,t)=>{const r=e/t.length;if(1===r)return t;const s=vec3.fromValues(r,r,r),c=[];return t.forEach(e=>{const t=vec3.subtract(vec3.create(),e[1],e[0]);vec3.divide(t,t,s);let l=e[0];for(let e=1;e<=r;++e){const e=vec3.add(vec3.create(),l,t);c.push([l,e]),l=e}}),c},EPSAREA=EPS*EPS/2*Math.sin(Math.PI/3),extrudeWalls=(e,t)=>{let r=slice.toEdges(e),s=slice.toEdges(t);if(r.length!==s.length){const e=lcm(r.length,s.length);e!==r.length&&(r=repartitionEdges(e,r)),e!==s.length&&(s=repartitionEdges(e,s))}const c=[];return r.forEach((e,t)=>{const r=s[t],l=poly3.create([e[0],e[1],r[1]]),o=poly3.measureArea(l);Number.isFinite(o)&&o>EPSAREA&&c.push(l);const n=poly3.create([e[0],r[1],r[0]]),i=poly3.measureArea(n);Number.isFinite(i)&&i>EPSAREA&&c.push(n)}),c};module.exports=extrudeWalls;
933
933
 
934
934
  },{"../../geometries/poly3":75,"../../maths/constants":90,"../../maths/vec3":217,"./slice":320}],312:[function(require,module,exports){
@@ -937,10 +937,10 @@ module.exports={extrudeFromSlices:require("./extrudeFromSlices"),extrudeLinear:r
937
937
  },{"./extrudeFromSlices":303,"./extrudeLinear":304,"./extrudeRectangular":307,"./extrudeRotate":310,"./project":313,"./slice":320}],313:[function(require,module,exports){
938
938
  const flatten=require("../../utils/flatten"),aboutEqualNormals=require("../../maths/utils/aboutEqualNormals"),plane=require("../../maths/plane"),mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),measureEpsilon=require("../../measurements/measureEpsilon"),unionGeom2=require("../booleans/unionGeom2"),projectGeom3=(e,o)=>{const r=plane.fromNormalAndPoint(plane.create(),e.axis,e.origin);if(Number.isNaN(r[0])||Number.isNaN(r[1])||Number.isNaN(r[2])||Number.isNaN(r[3]))throw new Error("project: invalid axis or origin");const t=measureEpsilon(o),a=t*t*Math.sqrt(3)/4;if(0===t)return geom2.create();const n=geom3.toPolygons(o);let s=[];for(let e=0;e<n.length;e++){const o=n[e].vertices.map(e=>plane.projectionOfPoint(r,e)),t=poly3.create(o),i=poly3.plane(t);aboutEqualNormals(r,i)&&(poly3.measureArea(t)<a||s.push(t))}if(!aboutEqualNormals(r,[0,0,1])){const e=mat4.fromVectorRotation(mat4.create(),r,[0,0,1]);s=s.map(o=>poly3.transform(e,o))}const i=(s=s.sort((e,o)=>poly3.measureArea(o)-poly3.measureArea(e))).map(e=>geom2.fromPoints(e.vertices));return unionGeom2(i)},project=(e,...o)=>{const{axis:r,origin:t}=Object.assign({},{axis:[0,0,1],origin:[0,0,0]},e);if(0===(o=flatten(o)).length)throw new Error("wrong number of arguments");e={axis:r,origin:t};const a=o.map(o=>geom3.isA(o)?projectGeom3(e,o):o);return 1===a.length?a[0]:a};module.exports=project;
939
939
 
940
- },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/mat4":140,"../../maths/plane":159,"../../maths/utils/aboutEqualNormals":163,"../../measurements/measureEpsilon":258,"../../utils/flatten":391,"../booleans/unionGeom2":281}],314:[function(require,module,exports){
940
+ },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/mat4":139,"../../maths/plane":158,"../../maths/utils/aboutEqualNormals":162,"../../measurements/measureEpsilon":258,"../../utils/flatten":391,"../booleans/unionGeom2":281}],314:[function(require,module,exports){
941
941
  const plane=require("../../../maths/plane"),vec3=require("../../../maths/vec3"),calculatePlane=e=>{const c=e.edges;if(c.length<3)throw new Error("slices must have 3 or more edges to calculate a plane");const a=c.reduce((e,c)=>vec3.add(vec3.create(),e,c[0]),vec3.create());let t;vec3.scale(a,a,1/c.length);let l=0;c.forEach(e=>{if(!vec3.equals(e[0],e[1])){const c=vec3.squaredDistance(a,e[0]);c>l&&(t=e,l=c)}});const r=c.find(e=>vec3.equals(e[1],t[0]));return plane.fromPoints(plane.create(),r[0],t[0],t[1])};module.exports=calculatePlane;
942
942
 
943
- },{"../../../maths/plane":159,"../../../maths/vec3":217}],315:[function(require,module,exports){
943
+ },{"../../../maths/plane":158,"../../../maths/vec3":217}],315:[function(require,module,exports){
944
944
  const create=require("./create"),vec3=require("../../../maths/vec3"),clone=(...e)=>{let c,r;return 1===e.length?(c=create(),r=e[0]):(c=e[0],r=e[1]),c.edges=r.edges.map(e=>[vec3.clone(e[0]),vec3.clone(e[1])]),c};module.exports=clone;
945
945
 
946
946
  },{"../../../maths/vec3":217,"./create":316}],316:[function(require,module,exports){
@@ -962,9 +962,9 @@ module.exports={calculatePlane:require("./calculatePlane"),clone:require("./clon
962
962
  const isA=e=>!!(e&&"object"==typeof e&&"edges"in e&&Array.isArray(e.edges));module.exports=isA;
963
963
 
964
964
  },{}],322:[function(require,module,exports){
965
- const vec3=require("../../../maths/vec3"),repairSlice=e=>{if(!e.edges)return e;const t={},r={};e.edges.forEach(e=>{const c=e[0].toString(),o=e[1].toString();t[c]=e[0],t[o]=e[1],r[c]=(r[c]||0)+1,r[o]=(r[o]||0)-1});const c=Object.keys(r).filter(e=>r[e]<0),o=Object.keys(r).filter(e=>r[e]>0);return c.forEach(r=>{const c=t[r];let i,s=1/0;o.forEach(e=>{const r=t[e],o=Math.hypot(c[0]-r[0],c[1]-r[1]);o<s&&(s=o,i=r)}),console.warn(`repairSlice: repairing vertex gap ${c} to ${i} distance ${s}`),e.edges.forEach(e=>{e[0].toString()===r&&(e[0]=i),e[1].toString()===r&&(e[1]=i)})}),e.edges=e.edges.filter(e=>!vec3.equals(e[0],e[1])),e};module.exports=repairSlice;
965
+ const vec3=require("../../../maths/vec3"),create=require("./create"),repair=e=>{if(!e.edges)return e;let t=e.edges;const r=new Map,c=new Map;(t=t.filter(e=>!vec3.equals(e[0],e[1]))).forEach(e=>{const t=e[0].toString(),s=e[1].toString();r.set(t,e[0]),r.set(s,e[1]),c.set(t,(c.get(t)||0)+1),c.set(s,(c.get(s)||0)-1)});const s=[],a=[];return c.forEach((e,t)=>{e<0&&s.push(t),e>0&&a.push(t)}),s.forEach(e=>{const c=r.get(e);let s,n=1/0;a.forEach(e=>{const t=r.get(e),a=vec3.distance(c,t);a<n&&(n=a,s=t)}),console.warn(`slice.repair: repairing vertex gap ${c} to ${s} distance ${n}`),t=t.map(t=>t[0].toString()===e?[s,t[1]]:t[1].toString()===e?[t[0],s]:t)}),create(t)};module.exports=repair;
966
966
 
967
- },{"../../../maths/vec3":217}],323:[function(require,module,exports){
967
+ },{"../../../maths/vec3":217,"./create":316}],323:[function(require,module,exports){
968
968
  const create=require("./create"),reverse=(...e)=>{let r,t;return 1===e.length?(r=create(),t=e[0]):(r=e[0],t=e[1]),r.edges=t.edges.map(e=>[e[1],e[0]]),r};module.exports=reverse;
969
969
 
970
970
  },{"./create":316}],324:[function(require,module,exports){
@@ -1034,18 +1034,18 @@ const flatten=require("../../utils/flatten"),measureEpsilon=require("../../measu
1034
1034
  module.exports={generalize:require("./generalize"),snap:require("./snap")};
1035
1035
 
1036
1036
  },{"./generalize":344,"./snap":350}],346:[function(require,module,exports){
1037
- const constants=require("../../maths/constants"),vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),assert=!1,getTag=e=>`${e}`,addSide=(e,t,n,s,c,r)=>{const l=getTag(s),o=getTag(c);const i=`${l}/${o}`,g=`${o}/${l}`;if(e.has(g))return deleteSide(e,t,n,c,s,null),null;const a={vertex0:s,vertex1:c,polygonindex:r};return e.has(i)?e.get(i).push(a):e.set(i,[a]),l in t?t[l].push(i):t[l]=[i],o in n?n[o].push(i):n[o]=[i],i},deleteSide=(e,t,n,s,c,r)=>{const l=getTag(s),o=getTag(c),i=`${l}/${o}`;let g=-1;const a=e.get(i);for(let e=0;e<a.length;e++){const t=a[e];let n=getTag(t.vertex0);if(n===l&&((n=getTag(t.vertex1))===o&&(null===r||t.polygonindex===r))){g=e;break}}a.splice(g,1),0===a.length&&e.delete(i),g=t[l].indexOf(i),t[l].splice(g,1),0===t[l].length&&delete t[l],g=n[o].indexOf(i),n[o].splice(g,1),0===n[o].length&&delete n[o]},insertTjunctions=e=>{const t=new Map;for(let n=0;n<e.length;n++){const s=e[n],c=s.vertices.length;if(c>=3){let e=s.vertices[0],r=getTag(e);for(let l=0;l<c;l++){let o=l+1;o===c&&(o=0);const i=s.vertices[o],g=getTag(i),a=`${r}/${g}`,v=`${g}/${r}`;if(t.has(v)){const e=t.get(v);e.splice(-1,1),0===e.length&&t.delete(v)}else{const s={vertex0:e,vertex1:i,polygonindex:n};t.has(a)?t.get(a).push(s):t.set(a,[s])}e=i,r=g}}else console.warn("warning: invalid polygon found during insertTjunctions")}if(t.size>0){const n={},s={},c={};for(const[e,r]of t)c[e]=!0,r.forEach(t=>{const c=getTag(t.vertex0),r=getTag(t.vertex1);c in n?n[c].push(e):n[c]=[e],r in s?s[r].push(e):s[r]=[e]});const r=e.slice(0);for(;0!==t.size;){for(const e of t.keys())c[e]=!0;let e=!1;for(;;){const l=Object.keys(c);if(0===l.length)break;const o=l[0];let i=!0;if(t.has(o)){const l=t.get(o);0;const g=l[0];for(let l=0;l<2;l++){const o=0===l?g.vertex0:g.vertex1,a=0===l?g.vertex1:g.vertex0,v=getTag(o),d=getTag(a);let f=[];0===l?v in s&&(f=s[v]):v in n&&(f=n[v]);for(let g=0;g<f.length;g++){const v=f[g],u=t.get(v)[0],x=0===l?u.vertex0:u.vertex1,h=0===l?u.vertex1:u.vertex0,p=getTag(x);getTag(h);if(p===d){deleteSide(t,n,s,o,a,null),deleteSide(t,n,s,a,o,null),i=!1,l=2,e=!0;break}{const g=o,v=a,d=x,f=vec3.subtract(vec3.create(),d,g),h=vec3.dot(vec3.subtract(vec3.create(),v,g),f)/vec3.dot(f,f);if(h>0&&h<1){const o=vec3.scale(vec3.create(),f,h);if(vec3.add(o,o,g),vec3.squaredDistance(o,v)<constants.EPS*constants.EPS){const o=u.polygonindex,g=r[o],v=getTag(u.vertex1);let d=-1;for(let e=0;e<g.vertices.length;e++)if(getTag(g.vertices[e])===v){d=e;break}0;const f=g.vertices.slice(0);f.splice(d,0,a);const x=poly3.create(f);r[o]=x,deleteSide(t,n,s,u.vertex0,u.vertex1,o);const h=addSide(t,n,s,u.vertex0,a,o),p=addSide(t,n,s,a,u.vertex1,o);null!==h&&(c[h]=!0),null!==p&&(c[p]=!0),i=!1,l=2,e=!0;break}}}}}}i&&delete c[o]}if(!e)break}e=r}return t.clear(),e};module.exports=insertTjunctions;
1037
+ const constants=require("../../maths/constants"),vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),assert=!1,getTag=e=>`${e}`,addSide=(e,t,s,n,r,c)=>{const o=getTag(n),g=getTag(r);const l=`${o}/${g}`,a=`${g}/${o}`;if(e.has(a))return deleteSide(e,t,s,r,n,null),null;const i={vertex0:n,vertex1:r,polygonindex:c};return e.has(l)?e.get(l).push(i):e.set(l,[i]),t.has(o)?t.get(o).push(l):t.set(o,[l]),s.has(g)?s.get(g).push(l):s.set(g,[l]),l},deleteSide=(e,t,s,n,r,c)=>{const o=getTag(n),g=getTag(r),l=`${o}/${g}`;let a=-1;const i=e.get(l);for(let e=0;e<i.length;e++){const t=i[e];let s=getTag(t.vertex0);if(s===o&&((s=getTag(t.vertex1))===g&&(null===c||t.polygonindex===c))){a=e;break}}i.splice(a,1),0===i.length&&e.delete(l),a=t.get(o).indexOf(l),t.get(o).splice(a,1),0===t.get(o).length&&t.delete(o),a=s.get(g).indexOf(l),s.get(g).splice(a,1),0===s.get(g).length&&s.delete(g)},insertTjunctions=e=>{const t=new Map;for(let s=0;s<e.length;s++){const n=e[s],r=n.vertices.length;if(r>=3){let e=n.vertices[0],c=getTag(e);for(let o=0;o<r;o++){let g=o+1;g===r&&(g=0);const l=n.vertices[g],a=getTag(l),i=`${c}/${a}`,v=`${a}/${c}`;if(t.has(v)){const e=t.get(v);e.splice(-1,1),0===e.length&&t.delete(v)}else{const n={vertex0:e,vertex1:l,polygonindex:s};t.has(i)?t.get(i).push(n):t.set(i,[n])}e=l,c=a}}else console.warn("warning: invalid polygon found during insertTjunctions")}if(t.size>0){const s=new Map,n=new Map,r=new Map;for(const[e,c]of t)r.set(e,!0),c.forEach(t=>{const r=getTag(t.vertex0),c=getTag(t.vertex1);s.has(r)?s.get(r).push(e):s.set(r,[e]),n.has(c)?n.get(c).push(e):n.set(c,[e])});const c=e.slice(0);for(;0!==t.size;){for(const e of t.keys())r.set(e,!0);let e=!1;for(;;){const o=Array.from(r.keys());if(0===o.length)break;const g=o[0];let l=!0;if(t.has(g)){const o=t.get(g);0;const a=o[0];for(let o=0;o<2;o++){const g=0===o?a.vertex0:a.vertex1,i=0===o?a.vertex1:a.vertex0,v=getTag(g),d=getTag(i);let h=[];0===o?n.has(v)&&(h=n.get(v)):s.has(v)&&(h=s.get(v));for(let a=0;a<h.length;a++){const v=h[a],f=t.get(v)[0],u=0===o?f.vertex0:f.vertex1,x=0===o?f.vertex1:f.vertex0,p=getTag(u);getTag(x);if(p===d){deleteSide(t,s,n,g,i,null),deleteSide(t,s,n,i,g,null),l=!1,o=2,e=!0;break}{const a=g,v=i,d=u,h=vec3.subtract(vec3.create(),d,a),x=vec3.dot(vec3.subtract(vec3.create(),v,a),h)/vec3.dot(h,h);if(x>0&&x<1){const g=vec3.scale(vec3.create(),h,x);if(vec3.add(g,g,a),vec3.squaredDistance(g,v)<constants.EPS*constants.EPS){const g=f.polygonindex,a=c[g],v=getTag(f.vertex1);let d=-1;for(let e=0;e<a.vertices.length;e++)if(getTag(a.vertices[e])===v){d=e;break}0;const h=a.vertices.slice(0);h.splice(d,0,i);const u=poly3.create(h);c[g]=u,deleteSide(t,s,n,f.vertex0,f.vertex1,g);const x=addSide(t,s,n,f.vertex0,i,g),p=addSide(t,s,n,i,f.vertex1,g);null!==x&&r.set(x,!0),null!==p&&r.set(p,!0),l=!1,o=2,e=!0;break}}}}}}l&&r.delete(g)}if(!e)break}e=c}return t.clear(),e};module.exports=insertTjunctions;
1038
1038
 
1039
1039
  },{"../../geometries/poly3":75,"../../maths/constants":90,"../../maths/vec3":217}],347:[function(require,module,exports){
1040
1040
  const aboutEqualNormals=require("../../maths/utils/aboutEqualNormals"),vec3=require("../../maths/vec3"),poly3=require("../../geometries/poly3"),createEdges=e=>{const n=poly3.toPoints(e),t=[];for(let e=0;e<n.length;e++){const l=(e+1)%n.length,r={v1:n[e],v2:n[l]};t.push(r)}for(let e=0;e<t.length;e++){const l=(e+1)%n.length;t[e].next=t[l],t[l].prev=t[e]}return t},insertEdge=(e,n)=>{const t=`${n.v1}:${n.v2}`;e.set(t,n)},deleteEdge=(e,n)=>{const t=`${n.v1}:${n.v2}`;e.delete(t)},findOppositeEdge=(e,n)=>{const t=`${n.v2}:${n.v1}`;return e.get(t)},calculateAnglesBetween=(e,n,t)=>{let l=e.prev.v1,r=e.prev.v2,o=n.next.v2;const v=calculateAngle(l,r,o,t);return l=n.prev.v1,r=n.prev.v2,o=e.next.v2,[v,calculateAngle(l,r,o,t)]},v1=vec3.create(),v2=vec3.create(),calculateAngle=(e,n,t,l)=>{const r=vec3.subtract(v1,n,e),o=vec3.subtract(v2,t,n);return vec3.cross(r,r,o),vec3.dot(r,l)},createPolygonAnd=e=>{let n;const t=[];for(;e.next;){const n=e.next;t.push(e.v1),e.v1=null,e.v2=null,e.next=null,e.prev=null,e=n}return t.length>0&&(n=poly3.create(t)),n},mergeCoplanarPolygons=e=>{if(e.length<2)return e;const n=e[0].plane,t=e.slice(),l=new Map;for(;t.length>0;){const e=t.shift(),r=createEdges(e);for(let e=0;e<r.length;e++){const t=r[e],o=findOppositeEdge(l,t);if(o){const e=calculateAnglesBetween(t,o,n);if(e[0]>=0&&e[1]>=0){const n=o.next,r=t.next;t.prev.next=o.next,t.next.prev=o.prev,o.prev.next=t.next,o.next.prev=t.prev,t.v1=null,t.v2=null,t.next=null,t.prev=null,deleteEdge(l,o),o.v1=null,o.v2=null,o.next=null,o.prev=null;const v=(e,n,t)=>{const l={v1:t.v1,v2:n.v2,next:n.next,prev:t.prev};t.prev.next=l,n.next.prev=l,deleteEdge(e,n),n.v1=null,n.v2=null,n.next=null,n.prev=null,deleteEdge(e,t),t.v1=null,t.v2=null,t.next=null,t.prev=null};0===e[0]&&v(l,n,n.prev),0===e[1]&&v(l,r,r.prev)}}else t.next&&insertEdge(l,t)}}const r=[];return l.forEach(e=>{const n=createPolygonAnd(e);n&&r.push(n)}),l.clear(),r},coplanar=(e,n)=>Math.abs(e[3]-n[3])<1.5e-7&&aboutEqualNormals(e,n),mergePolygons=(e,n)=>{const t=[];n.forEach(e=>{const n=t.find(n=>coplanar(n[0],poly3.plane(e)));if(n){n[1].push(e)}else t.push([poly3.plane(e),[e]])});let l=[];return t.forEach(e=>{const n=e[1],t=mergeCoplanarPolygons(n);l=l.concat(t)}),l};module.exports=mergePolygons;
1041
1041
 
1042
- },{"../../geometries/poly3":75,"../../maths/utils/aboutEqualNormals":163,"../../maths/vec3":217}],348:[function(require,module,exports){
1043
- const{EPS:EPS}=require("../../maths/constants"),line2=require("../../maths/line2"),vec2=require("../../maths/vec2"),OrthoNormalBasis=require("../../maths/OrthoNormalBasis"),interpolateBetween2DPointsForY=require("../../maths/utils/interpolateBetween2DPointsForY"),{insertSorted:insertSorted,fnNumberSort:fnNumberSort}=require("../../utils"),poly3=require("../../geometries/poly3"),reTesselateCoplanarPolygons=t=>{if(t.length<2)return t;const e=[],o=t.length,n=poly3.plane(t[0]),l=new OrthoNormalBasis(n),i=[],r=[],s={},f={},p={},h=10/EPS;for(let e=0;e<o;e++){const o=t[e];let n=[],c=o.vertices.length,g=-1;if(c>0){let t,i;for(let r=0;r<c;r++){let s=l.to2D(o.vertices[r]);const c=Math.floor(s[1]*h);let a;c in p?a=p[c]:c+1 in p?a=p[c+1]:c-1 in p?a=p[c-1]:(a=s[1],p[c]=s[1]),s=vec2.fromValues(s[0],a),n.push(s);const u=s[1];(0===r||u<t)&&(t=u,g=r),(0===r||u>i)&&(i=u),u in f||(f[u]={}),f[u][e]=!0}t>=i?(n=[],c=0,g=-1):(t in s||(s[t]=[]),s[t].push(e))}n.reverse(),g=c-g-1,i.push(n),r.push(g)}const c=[];for(const t in f)c.push(t);c.sort(fnNumberSort);let g=[],a=[];for(let t=0;t<c.length;t++){const o=[],p=c[t],h=Number(p),u=f[p];for(let t=0;t<g.length;++t){const e=g[t],o=e.polygonindex;if(u[o]){const n=i[o],l=n.length;let r=e.leftvertexindex,s=e.rightvertexindex;for(;;){let t=r+1;if(t>=l&&(t=0),n[t][1]!==h)break;r=t}let f=s-1;if(f<0&&(f=l-1),n[f][1]===h&&(s=f),r!==e.leftvertexindex&&r===s)g.splice(t,1),--t;else{e.leftvertexindex=r,e.rightvertexindex=s,e.topleft=n[r],e.topright=n[s];let t=r+1;t>=l&&(t=0),e.bottomleft=n[t];let o=s-1;o<0&&(o=l-1),e.bottomright=n[o]}}}let m;if(t>=c.length-1)g=[],m=null;else{const e=.5*(h+(m=Number(c[t+1]))),o=s[p];for(const t in o){const n=o[t],l=i[n],s=l.length,f=r[n];let p=f;for(;;){let t=p+1;if(t>=s&&(t=0),l[t][1]!==h)break;if(t===f)break;p=t}let c=f;for(;;){let t=c-1;if(t<0&&(t=s-1),l[t][1]!==h)break;if(t===p)break;c=t}let a=p+1;a>=s&&(a=0);let u=c-1;u<0&&(u=s-1);const m={polygonindex:n,leftvertexindex:p,rightvertexindex:c,topleft:l[p],topright:l[c],bottomleft:l[a],bottomright:l[u]};insertSorted(g,m,(t,o)=>{const n=interpolateBetween2DPointsForY(t.topleft,t.bottomleft,e),l=interpolateBetween2DPointsForY(o.topleft,o.bottomleft,e);return n>l?1:n<l?-1:0})}}for(const t in g){const e=g[t];let n=interpolateBetween2DPointsForY(e.topleft,e.bottomleft,h);const l=vec2.fromValues(n,h);n=interpolateBetween2DPointsForY(e.topright,e.bottomright,h);const i=vec2.fromValues(n,h);n=interpolateBetween2DPointsForY(e.topleft,e.bottomleft,m);const r=vec2.fromValues(n,m);n=interpolateBetween2DPointsForY(e.topright,e.bottomright,m);const s=vec2.fromValues(n,m),f={topleft:l,topright:i,bottomleft:r,bottomright:s,leftline:line2.fromPoints(line2.create(),l,r),rightline:line2.fromPoints(line2.create(),s,i)};if(o.length>0){const t=o[o.length-1],e=vec2.distance(f.topleft,t.topright),n=vec2.distance(f.bottomleft,t.bottomright);e<EPS&&n<EPS&&(f.topleft=t.topleft,f.leftline=t.leftline,f.bottomleft=t.bottomleft,o.splice(o.length-1,1))}o.push(f)}if(t>0){const t={},i={};for(let e=0;e<o.length;e++){const n=o[e];for(let e=0;e<a.length;e++)if(!i[e]){const o=a[e];if(vec2.distance(o.bottomleft,n.topleft)<EPS&&vec2.distance(o.bottomright,n.topright)<EPS){i[e]=!0;const l=line2.direction(n.leftline),r=line2.direction(o.leftline),s=l[0]-r[0],f=line2.direction(n.rightline),p=line2.direction(o.rightline),h=f[0]-p[0],c=Math.abs(s)<EPS,g=Math.abs(h)<EPS,a=g||h>=0;(c||s>=0)&&a&&(n.outpolygon=o.outpolygon,n.leftlinecontinues=c,n.rightlinecontinues=g,t[e]=!0);break}}}for(let o=0;o<a.length;o++)if(!t[o]){const t=a[o];t.outpolygon.rightpoints.push(t.bottomright),vec2.distance(t.bottomright,t.bottomleft)>EPS&&t.outpolygon.leftpoints.push(t.bottomleft),t.outpolygon.leftpoints.reverse();const i=t.outpolygon.rightpoints.concat(t.outpolygon.leftpoints).map(t=>l.to3D(t)),r=poly3.fromPointsAndPlane(i,n);r.vertices.length&&e.push(r)}}for(let t=0;t<o.length;t++){const e=o[t];e.outpolygon?(e.leftlinecontinues||e.outpolygon.leftpoints.push(e.topleft),e.rightlinecontinues||e.outpolygon.rightpoints.push(e.topright)):(e.outpolygon={leftpoints:[],rightpoints:[]},e.outpolygon.leftpoints.push(e.topleft),vec2.distance(e.topleft,e.topright)>EPS&&e.outpolygon.rightpoints.push(e.topright))}a=o}return e};module.exports=reTesselateCoplanarPolygons;
1042
+ },{"../../geometries/poly3":75,"../../maths/utils/aboutEqualNormals":162,"../../maths/vec3":217}],348:[function(require,module,exports){
1043
+ const{EPS:EPS}=require("../../maths/constants"),line2=require("../../maths/line2"),vec2=require("../../maths/vec2"),OrthoNormalBasis=require("../../maths/OrthoNormalBasis"),interpolateBetween2DPointsForY=require("../../maths/utils/interpolateBetween2DPointsForY"),{insertSorted:insertSorted,fnNumberSort:fnNumberSort}=require("../../utils"),poly3=require("../../geometries/poly3"),reTesselateCoplanarPolygons=t=>{if(t.length<2)return t;const e=[],o=t.length,n=poly3.plane(t[0]),l=new OrthoNormalBasis(n),i=[],r=[],s=new Map,f=new Map,p=new Map,h=10/EPS;for(let e=0;e<o;e++){const o=t[e];let n=[],g=o.vertices.length,c=-1;if(g>0){let t,i;for(let r=0;r<g;r++){let s=l.to2D(o.vertices[r]);const g=Math.floor(s[1]*h);let a;p.has(g)?a=p.get(g):p.has(g+1)?a=p.get(g+1):p.has(g-1)?a=p.get(g-1):(a=s[1],p.set(g,s[1])),s=vec2.fromValues(s[0],a),n.push(s);const u=s[1];(0===r||u<t)&&(t=u,c=r),(0===r||u>i)&&(i=u);let m=f.get(u);m||(m={},f.set(u,m)),m[e]=!0}if(t>=i)n=[],g=0,c=-1;else{let o=s.get(t);o||(o=[],s.set(t,o)),o.push(e)}}n.reverse(),c=g-c-1,i.push(n),r.push(c)}const g=[];f.forEach((t,e)=>g.push(e)),g.sort(fnNumberSort);let c=[],a=[];for(let t=0;t<g.length;t++){const o=[],p=g[t],h=f.get(p);for(let t=0;t<c.length;++t){const e=c[t],o=e.polygonindex;if(h[o]){const n=i[o],l=n.length;let r=e.leftvertexindex,s=e.rightvertexindex;for(;;){let t=r+1;if(t>=l&&(t=0),n[t][1]!==p)break;r=t}let f=s-1;if(f<0&&(f=l-1),n[f][1]===p&&(s=f),r!==e.leftvertexindex&&r===s)c.splice(t,1),--t;else{e.leftvertexindex=r,e.rightvertexindex=s,e.topleft=n[r],e.topright=n[s];let t=r+1;t>=l&&(t=0),e.bottomleft=n[t];let o=s-1;o<0&&(o=l-1),e.bottomright=n[o]}}}let u;if(t>=g.length-1)c=[],u=null;else{const e=.5*(p+(u=Number(g[t+1]))),o=s.get(p);for(const t in o){const n=o[t],l=i[n],s=l.length,f=r[n];let h=f;for(;;){let t=h+1;if(t>=s&&(t=0),l[t][1]!==p)break;if(t===f)break;h=t}let g=f;for(;;){let t=g-1;if(t<0&&(t=s-1),l[t][1]!==p)break;if(t===h)break;g=t}let a=h+1;a>=s&&(a=0);let u=g-1;u<0&&(u=s-1);const m={polygonindex:n,leftvertexindex:h,rightvertexindex:g,topleft:l[h],topright:l[g],bottomleft:l[a],bottomright:l[u]};insertSorted(c,m,(t,o)=>{const n=interpolateBetween2DPointsForY(t.topleft,t.bottomleft,e),l=interpolateBetween2DPointsForY(o.topleft,o.bottomleft,e);return n>l?1:n<l?-1:0})}}for(const t in c){const e=c[t];let n=interpolateBetween2DPointsForY(e.topleft,e.bottomleft,p);const l=vec2.fromValues(n,p);n=interpolateBetween2DPointsForY(e.topright,e.bottomright,p);const i=vec2.fromValues(n,p);n=interpolateBetween2DPointsForY(e.topleft,e.bottomleft,u);const r=vec2.fromValues(n,u);n=interpolateBetween2DPointsForY(e.topright,e.bottomright,u);const s=vec2.fromValues(n,u),f={topleft:l,topright:i,bottomleft:r,bottomright:s,leftline:line2.fromPoints(line2.create(),l,r),rightline:line2.fromPoints(line2.create(),s,i)};if(o.length>0){const t=o[o.length-1],e=vec2.distance(f.topleft,t.topright),n=vec2.distance(f.bottomleft,t.bottomright);e<EPS&&n<EPS&&(f.topleft=t.topleft,f.leftline=t.leftline,f.bottomleft=t.bottomleft,o.splice(o.length-1,1))}o.push(f)}if(t>0){const t=new Set,i=new Set;for(let e=0;e<o.length;e++){const n=o[e];for(let e=0;e<a.length;e++)if(!i.has(e)){const o=a[e];if(vec2.distance(o.bottomleft,n.topleft)<EPS&&vec2.distance(o.bottomright,n.topright)<EPS){i.add(e);const l=line2.direction(n.leftline),r=line2.direction(o.leftline),s=l[0]-r[0],f=line2.direction(n.rightline),p=line2.direction(o.rightline),h=f[0]-p[0],g=Math.abs(s)<EPS,c=Math.abs(h)<EPS,a=c||h>=0;(g||s>=0)&&a&&(n.outpolygon=o.outpolygon,n.leftlinecontinues=g,n.rightlinecontinues=c,t.add(e));break}}}for(let o=0;o<a.length;o++)if(!t.has(o)){const t=a[o];t.outpolygon.rightpoints.push(t.bottomright),vec2.distance(t.bottomright,t.bottomleft)>EPS&&t.outpolygon.leftpoints.push(t.bottomleft),t.outpolygon.leftpoints.reverse();const i=t.outpolygon.rightpoints.concat(t.outpolygon.leftpoints).map(t=>l.to3D(t)),r=poly3.fromPointsAndPlane(i,n);r.vertices.length&&e.push(r)}}for(let t=0;t<o.length;t++){const e=o[t];e.outpolygon?(e.leftlinecontinues||e.outpolygon.leftpoints.push(e.topleft),e.rightlinecontinues||e.outpolygon.rightpoints.push(e.topright)):(e.outpolygon={leftpoints:[],rightpoints:[]},e.outpolygon.leftpoints.push(e.topleft),vec2.distance(e.topleft,e.topright)>EPS&&e.outpolygon.rightpoints.push(e.topright))}a=o}return e};module.exports=reTesselateCoplanarPolygons;
1044
1044
 
1045
- },{"../../geometries/poly3":75,"../../maths/OrthoNormalBasis":89,"../../maths/constants":90,"../../maths/line2":101,"../../maths/utils/interpolateBetween2DPointsForY":166,"../../maths/vec2":186,"../../utils":393}],349:[function(require,module,exports){
1045
+ },{"../../geometries/poly3":75,"../../maths/OrthoNormalBasis":89,"../../maths/constants":90,"../../maths/line2":101,"../../maths/utils/interpolateBetween2DPointsForY":165,"../../maths/vec2":186,"../../utils":393}],349:[function(require,module,exports){
1046
1046
  const geom3=require("../../geometries/geom3"),poly3=require("../../geometries/poly3"),aboutEqualNormals=require("../../maths/utils/aboutEqualNormals"),reTesselateCoplanarPolygons=require("./reTesselateCoplanarPolygons"),coplanar=(e,o)=>Math.abs(e[3]-o[3])<1.5e-7&&aboutEqualNormals(e,o),retessellate=e=>{if(e.isRetesselated)return e;const o=geom3.toPolygons(e),s=[];o.forEach(e=>{const o=s.find(o=>coplanar(o[0],poly3.plane(e)));if(o){o[1].push(e)}else s.push([poly3.plane(e),[e]])});let a=[];s.forEach(e=>{const o=e[1],s=reTesselateCoplanarPolygons(o);a=a.concat(s)});const l=geom3.create(a);return l.isRetesselated=!0,l};module.exports=retessellate;
1047
1047
 
1048
- },{"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/utils/aboutEqualNormals":163,"./reTesselateCoplanarPolygons":348}],350:[function(require,module,exports){
1048
+ },{"../../geometries/geom3":37,"../../geometries/poly3":75,"../../maths/utils/aboutEqualNormals":162,"./reTesselateCoplanarPolygons":348}],350:[function(require,module,exports){
1049
1049
  const flatten=require("../../utils/flatten"),vec2=require("../../maths/vec2"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),measureEpsilon=require("../../measurements/measureEpsilon"),snapPolygons=require("./snapPolygons"),snapPath2=e=>{const s=measureEpsilon(e),r=path2.toPoints(e).map(e=>vec2.snap(vec2.create(),e,s));return path2.create(r)},snapGeom2=e=>{const s=measureEpsilon(e);let r=geom2.toSides(e).map(e=>[vec2.snap(vec2.create(),e[0],s),vec2.snap(vec2.create(),e[1],s)]);return r=r.filter(e=>!vec2.equals(e[0],e[1])),geom2.create(r)},snapGeom3=e=>{const s=measureEpsilon(e),r=geom3.toPolygons(e),o=snapPolygons(s,r);return geom3.create(o)},snap=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const s=e.map(e=>path2.isA(e)?snapPath2(e):geom2.isA(e)?snapGeom2(e):geom3.isA(e)?snapGeom3(e):e);return 1===s.length?s[0]:s};module.exports=snap;
1050
1050
 
1051
1051
  },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/vec2":186,"../../measurements/measureEpsilon":258,"../../utils/flatten":391,"./snapPolygons":351}],351:[function(require,module,exports){
@@ -1066,19 +1066,19 @@ module.exports={align:require("./align"),center:require("./center").center,cente
1066
1066
  },{"./align":353,"./center":354,"./mirror":356,"./rotate":357,"./scale":358,"./transform":359,"./translate":360}],356:[function(require,module,exports){
1067
1067
  const flatten=require("../../utils/flatten"),mat4=require("../../maths/mat4"),plane=require("../../maths/plane"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),mirror=(r,...e)=>{const{origin:o,normal:m}=Object.assign({},{origin:[0,0,0],normal:[0,0,1]},r);if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const i=plane.fromNormalAndPoint(plane.create(),m,o);if(Number.isNaN(i[0]))throw new Error("the given origin and normal do not define a proper plane");const n=mat4.mirrorByPlane(mat4.create(),i),t=e.map(r=>path2.isA(r)?path2.transform(n,r):geom2.isA(r)?geom2.transform(n,r):geom3.isA(r)?geom3.transform(n,r):r);return 1===t.length?t[0]:t},mirrorX=(...r)=>mirror({normal:[1,0,0]},r),mirrorY=(...r)=>mirror({normal:[0,1,0]},r),mirrorZ=(...r)=>mirror({normal:[0,0,1]},r);module.exports={mirror:mirror,mirrorX:mirrorX,mirrorY:mirrorY,mirrorZ:mirrorZ};
1068
1068
 
1069
- },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/mat4":140,"../../maths/plane":159,"../../utils/flatten":391}],357:[function(require,module,exports){
1069
+ },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/mat4":139,"../../maths/plane":158,"../../utils/flatten":391}],357:[function(require,module,exports){
1070
1070
  const flatten=require("../../utils/flatten"),mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),rotate=(t,...e)=>{if(!Array.isArray(t))throw new Error("angles must be an array");if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");for(t=t.slice();t.length<3;)t.push(0);const r=t[2],o=t[1],a=t[0],m=mat4.fromTaitBryanRotation(mat4.create(),r,o,a),n=e.map(t=>path2.isA(t)?path2.transform(m,t):geom2.isA(t)?geom2.transform(m,t):geom3.isA(t)?geom3.transform(m,t):t);return 1===n.length?n[0]:n},rotateX=(t,...e)=>rotate([t,0,0],e),rotateY=(t,...e)=>rotate([0,t,0],e),rotateZ=(t,...e)=>rotate([0,0,t],e);module.exports={rotate:rotate,rotateX:rotateX,rotateY:rotateY,rotateZ:rotateZ};
1071
1071
 
1072
- },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/mat4":140,"../../utils/flatten":391}],358:[function(require,module,exports){
1072
+ },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/mat4":139,"../../utils/flatten":391}],358:[function(require,module,exports){
1073
1073
  const flatten=require("../../utils/flatten"),mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),scale=(e,...r)=>{if(!Array.isArray(e))throw new Error("factors must be an array");if(0===(r=flatten(r)).length)throw new Error("wrong number of arguments");for(e=e.slice();e.length<3;)e.push(1);if(e[0]<=0||e[1]<=0||e[2]<=0)throw new Error("factors must be positive");const a=mat4.fromScaling(mat4.create(),e),t=r.map(e=>path2.isA(e)?path2.transform(a,e):geom2.isA(e)?geom2.transform(a,e):geom3.isA(e)?geom3.transform(a,e):e);return 1===t.length?t[0]:t},scaleX=(e,...r)=>scale([e,1,1],r),scaleY=(e,...r)=>scale([1,e,1],r),scaleZ=(e,...r)=>scale([1,1,e],r);module.exports={scale:scale,scaleX:scaleX,scaleY:scaleY,scaleZ:scaleZ};
1074
1074
 
1075
- },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/mat4":140,"../../utils/flatten":391}],359:[function(require,module,exports){
1075
+ },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/mat4":139,"../../utils/flatten":391}],359:[function(require,module,exports){
1076
1076
  const flatten=require("../../utils/flatten"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),transform=(e,...r)=>{if(0===(r=flatten(r)).length)throw new Error("wrong number of arguments");const t=r.map(r=>path2.isA(r)?path2.transform(e,r):geom2.isA(r)?geom2.transform(e,r):geom3.isA(r)?geom3.transform(e,r):r);return 1===t.length?t[0]:t};module.exports=transform;
1077
1077
 
1078
1078
  },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../utils/flatten":391}],360:[function(require,module,exports){
1079
1079
  const flatten=require("../../utils/flatten"),mat4=require("../../maths/mat4"),geom2=require("../../geometries/geom2"),geom3=require("../../geometries/geom3"),path2=require("../../geometries/path2"),translate=(t,...e)=>{if(!Array.isArray(t))throw new Error("offset must be an array");if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");for(t=t.slice();t.length<3;)t.push(0);const r=mat4.fromTranslation(mat4.create(),t),a=e.map(t=>path2.isA(t)?path2.transform(r,t):geom2.isA(t)?geom2.transform(r,t):geom3.isA(t)?geom3.transform(r,t):t);return 1===a.length?a[0]:a},translateX=(t,...e)=>translate([t,0,0],e),translateY=(t,...e)=>translate([0,t,0],e),translateZ=(t,...e)=>translate([0,0,t],e);module.exports={translate:translate,translateX:translateX,translateY:translateY,translateZ:translateZ};
1080
1080
 
1081
- },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/mat4":140,"../../utils/flatten":391}],361:[function(require,module,exports){
1081
+ },{"../../geometries/geom2":22,"../../geometries/geom3":37,"../../geometries/path2":58,"../../maths/mat4":139,"../../utils/flatten":391}],361:[function(require,module,exports){
1082
1082
  const{EPS:EPS}=require("../maths/constants"),vec2=require("../maths/vec2"),path2=require("../geometries/path2"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),arc=e=>{const r={center:[0,0],radius:1,startAngle:0,endAngle:2*Math.PI,makeTangent:!1,segments:32};let{center:t,radius:s,startAngle:a,endAngle:n,makeTangent:o,segments:c}=Object.assign({},r,e);if(!isNumberArray(t,2))throw new Error("center must be an array of X and Y values");if(!isGT(s,0))throw new Error("radius must be greater than zero");if(!isGTE(a,0))throw new Error("startAngle must be positive");if(!isGTE(n,0))throw new Error("endAngle must be positive");if(!isGTE(c,4))throw new Error("segments must be four or more");a%=2*Math.PI,n%=2*Math.PI;let i=2*Math.PI;a<n&&(i=n-a),a>n&&(i=n+(2*Math.PI-a));const m=Math.acos((s*s+s*s-EPS*EPS)/(2*s*s)),h=vec2.clone(t);let l;const u=[];if(i<m)l=vec2.fromAngleRadians(vec2.create(),a),vec2.scale(l,l,s),vec2.add(l,l,h),u.push(l);else{const e=Math.max(1,Math.floor(c*(i/(2*Math.PI))))+1;let r=.5*e/i;r>.25&&(r=.25);const t=o?e+2:e;for(let n=0;n<=t;n++){let t=n;o&&((t=(n-1)*(e-2*r)/e+r)<0&&(t=0),t>e&&(t=e));const c=a+t*(i/e);l=vec2.fromAngleRadians(vec2.create(),c),vec2.scale(l,l,s),vec2.add(l,l,h),u.push(l)}}return path2.fromPoints({closed:!1},u)};module.exports=arc;
1083
1083
 
1084
1084
  },{"../geometries/path2":58,"../maths/constants":90,"../maths/vec2":186,"./commonChecks":363}],362:[function(require,module,exports){
@@ -1097,18 +1097,18 @@ const geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),
1097
1097
  const cylinderElliptic=require("./cylinderElliptic"),{isGT:isGT}=require("./commonChecks"),cylinder=e=>{const{center:i,height:r,radius:t,segments:s}=Object.assign({},{center:[0,0,0],height:2,radius:1,segments:32},e);if(!isGT(t,0))throw new Error("radius must be greater than zero");return cylinderElliptic({center:i,height:r,startRadius:[t,t],endRadius:[t,t],segments:s})};module.exports=cylinder;
1098
1098
 
1099
1099
  },{"./commonChecks":363,"./cylinderElliptic":367}],367:[function(require,module,exports){
1100
- const{EPS:EPS}=require("../maths/constants"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../utils/trigonometry"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),cylinderElliptic=e=>{const r={center:[0,0,0],height:2,startRadius:[1,1],startAngle:0,endRadius:[1,1],endAngle:2*Math.PI,segments:32};let{center:t,height:s,startRadius:a,startAngle:i,endRadius:o,endAngle:n,segments:u}=Object.assign({},r,e);if(!isNumberArray(t,3))throw new Error("center must be an array of X, Y and Z values");if(!isGT(s,0))throw new Error("height must be greater then zero");if(!isNumberArray(a,2))throw new Error("startRadius must be an array of X and Y values");if(!a.every(e=>e>=0))throw new Error("startRadius values must be positive");if(!isNumberArray(o,2))throw new Error("endRadius must be an array of X and Y values");if(!o.every(e=>e>=0))throw new Error("endRadius values must be positive");if(o.every(e=>0===e)&&a.every(e=>0===e))throw new Error("at least one radius must be positive");if(!isGTE(i,0))throw new Error("startAngle must be positive");if(!isGTE(n,0))throw new Error("endAngle must be positive");if(!isGTE(u,4))throw new Error("segments must be four or more");i%=2*Math.PI,n%=2*Math.PI;let c=2*Math.PI;i<n&&(c=n-i),i>n&&(c=n+(2*Math.PI-i));const h=Math.min(a[0],a[1],o[0],o[1]),l=Math.acos((h*h+h*h-EPS*EPS)/(2*h*h));if(c<l)throw new Error("startAngle and endAngle do not define a significant rotation");const m=Math.floor(u*(c/(2*Math.PI))),d=vec3.fromValues(0,0,-s/2),v=vec3.fromValues(0,0,s/2),f=vec3.subtract(vec3.create(),v,d),g=vec3.fromValues(1,0,0),p=vec3.fromValues(0,1,0),w=vec3.create(),E=vec3.create(),y=vec3.create(),b=(e,r,t)=>{const s=r*c+i;return vec3.scale(w,g,t[0]*cos(s)),vec3.scale(E,p,t[1]*sin(s)),vec3.add(w,w,E),vec3.scale(y,f,e),vec3.add(y,y,d),vec3.add(vec3.create(),w,y)},A=(...e)=>{const r=e.map(e=>vec3.add(vec3.create(),e,t));return poly3.create(r)},P=[];for(let e=0;e<m;e++){const r=e/m,t=(e+1)/m;o[0]===a[0]&&o[1]===a[1]?(P.push(A(d,b(0,t,o),b(0,r,o))),P.push(A(b(0,t,o),b(1,t,o),b(1,r,o),b(0,r,o))),P.push(A(v,b(1,r,o),b(1,t,o)))):(a[0]>0&&a[1]>0&&P.push(A(d,b(0,t,a),b(0,r,a))),(a[0]>0||a[1]>0)&&P.push(A(b(0,r,a),b(0,t,a),b(1,r,o))),o[0]>0&&o[1]>0&&P.push(A(v,b(1,r,o),b(1,t,o))),(o[0]>0||o[1]>0)&&P.push(A(b(1,r,o),b(0,t,a),b(1,t,o))))}return c<2*Math.PI&&(P.push(A(d,b(0,0,a),v)),P.push(A(b(0,0,a),b(1,0,o),v)),P.push(A(d,v,b(0,1,a))),P.push(A(b(0,1,a),v,b(1,1,o)))),geom3.create(P)};module.exports=cylinderElliptic;
1100
+ const{EPS:EPS}=require("../maths/constants"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),cylinderElliptic=e=>{const r={center:[0,0,0],height:2,startRadius:[1,1],startAngle:0,endRadius:[1,1],endAngle:2*Math.PI,segments:32};let{center:t,height:s,startRadius:a,startAngle:i,endRadius:o,endAngle:n,segments:u}=Object.assign({},r,e);if(!isNumberArray(t,3))throw new Error("center must be an array of X, Y and Z values");if(!isGT(s,0))throw new Error("height must be greater then zero");if(!isNumberArray(a,2))throw new Error("startRadius must be an array of X and Y values");if(!a.every(e=>e>=0))throw new Error("startRadius values must be positive");if(!isNumberArray(o,2))throw new Error("endRadius must be an array of X and Y values");if(!o.every(e=>e>=0))throw new Error("endRadius values must be positive");if(o.every(e=>0===e)&&a.every(e=>0===e))throw new Error("at least one radius must be positive");if(!isGTE(i,0))throw new Error("startAngle must be positive");if(!isGTE(n,0))throw new Error("endAngle must be positive");if(!isGTE(u,4))throw new Error("segments must be four or more");i%=2*Math.PI,n%=2*Math.PI;let c=2*Math.PI;i<n&&(c=n-i),i>n&&(c=n+(2*Math.PI-i));const h=Math.min(a[0],a[1],o[0],o[1]),l=Math.acos((h*h+h*h-EPS*EPS)/(2*h*h));if(c<l)throw new Error("startAngle and endAngle do not define a significant rotation");const m=Math.floor(u*(c/(2*Math.PI))),d=vec3.fromValues(0,0,-s/2),v=vec3.fromValues(0,0,s/2),f=vec3.subtract(vec3.create(),v,d),g=vec3.fromValues(1,0,0),p=vec3.fromValues(0,1,0),w=vec3.create(),E=vec3.create(),y=vec3.create(),b=(e,r,t)=>{const s=r*c+i;return vec3.scale(w,g,t[0]*cos(s)),vec3.scale(E,p,t[1]*sin(s)),vec3.add(w,w,E),vec3.scale(y,f,e),vec3.add(y,y,d),vec3.add(vec3.create(),w,y)},A=(...e)=>{const r=e.map(e=>vec3.add(vec3.create(),e,t));return poly3.create(r)},P=[];for(let e=0;e<m;e++){const r=e/m;let t=(e+1)/m;c===2*Math.PI&&e===m-1&&(t=0),o[0]===a[0]&&o[1]===a[1]?(P.push(A(d,b(0,t,o),b(0,r,o))),P.push(A(b(0,t,o),b(1,t,o),b(1,r,o),b(0,r,o))),P.push(A(v,b(1,r,o),b(1,t,o)))):(a[0]>0&&a[1]>0&&P.push(A(d,b(0,t,a),b(0,r,a))),(a[0]>0||a[1]>0)&&P.push(A(b(0,r,a),b(0,t,a),b(1,r,o))),o[0]>0&&o[1]>0&&P.push(A(v,b(1,r,o),b(1,t,o))),(o[0]>0||o[1]>0)&&P.push(A(b(1,r,o),b(0,t,a),b(1,t,o))))}return c<2*Math.PI&&(P.push(A(d,b(0,0,a),v)),P.push(A(b(0,0,a),b(1,0,o),v)),P.push(A(d,v,b(0,1,a))),P.push(A(b(0,1,a),v,b(1,1,o)))),geom3.create(P)};module.exports=cylinderElliptic;
1101
1101
 
1102
- },{"../geometries/geom3":37,"../geometries/poly3":75,"../maths/constants":90,"../maths/vec3":217,"../utils/trigonometry":398,"./commonChecks":363}],368:[function(require,module,exports){
1103
- const{EPS:EPS}=require("../maths/constants"),vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{sin:sin,cos:cos}=require("../utils/trigonometry"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),ellipse=e=>{const r={center:[0,0],radius:[1,1],startAngle:0,endAngle:2*Math.PI,segments:32};let{center:t,radius:s,startAngle:n,endAngle:o,segments:a}=Object.assign({},r,e);if(!isNumberArray(t,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(s,2))throw new Error("radius must be an array of X and Y values");if(!s.every(e=>e>0))throw new Error("radius values must be greater than zero");if(!isGTE(n,0))throw new Error("startAngle must be positive");if(!isGTE(o,0))throw new Error("endAngle must be positive");if(!isGTE(a,3))throw new Error("segments must be three or more");n%=2*Math.PI,o%=2*Math.PI;let i=2*Math.PI;n<o&&(i=o-n),n>o&&(i=o+(2*Math.PI-n));const u=Math.min(s[0],s[1]);if(i<Math.acos((u*u+u*u-EPS*EPS)/(2*u*u)))throw new Error("startAngle and endAngle do not define a significant rotation");a=Math.floor(a*(i/(2*Math.PI)));const m=vec2.clone(t),h=i/a,c=[];a=i<2*Math.PI?a+1:a;for(let e=0;e<a;e++){const r=h*e+n,t=vec2.fromValues(s[0]*cos(r),s[1]*sin(r));vec2.add(t,m,t),c.push(t)}return i<2*Math.PI&&c.push(m),geom2.fromPoints(c)};module.exports=ellipse;
1102
+ },{"../geometries/geom3":37,"../geometries/poly3":75,"../maths/constants":90,"../maths/utils/trigonometry":168,"../maths/vec3":217,"./commonChecks":363}],368:[function(require,module,exports){
1103
+ const{EPS:EPS}=require("../maths/constants"),vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),ellipse=e=>{const r={center:[0,0],radius:[1,1],startAngle:0,endAngle:2*Math.PI,segments:32};let{center:t,radius:s,startAngle:n,endAngle:o,segments:a}=Object.assign({},r,e);if(!isNumberArray(t,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(s,2))throw new Error("radius must be an array of X and Y values");if(!s.every(e=>e>0))throw new Error("radius values must be greater than zero");if(!isGTE(n,0))throw new Error("startAngle must be positive");if(!isGTE(o,0))throw new Error("endAngle must be positive");if(!isGTE(a,3))throw new Error("segments must be three or more");n%=2*Math.PI,o%=2*Math.PI;let i=2*Math.PI;n<o&&(i=o-n),n>o&&(i=o+(2*Math.PI-n));const m=Math.min(s[0],s[1]);if(i<Math.acos((m*m+m*m-EPS*EPS)/(2*m*m)))throw new Error("startAngle and endAngle do not define a significant rotation");a=Math.floor(a*(i/(2*Math.PI)));const u=vec2.clone(t),h=i/a,c=[];a=i<2*Math.PI?a+1:a;for(let e=0;e<a;e++){const r=h*e+n,t=vec2.fromValues(s[0]*cos(r),s[1]*sin(r));vec2.add(t,u,t),c.push(t)}return i<2*Math.PI&&c.push(u),geom2.fromPoints(c)};module.exports=ellipse;
1104
1104
 
1105
- },{"../geometries/geom2":22,"../maths/constants":90,"../maths/vec2":186,"../utils/trigonometry":398,"./commonChecks":363}],369:[function(require,module,exports){
1106
- const vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../utils/trigonometry"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),ellipsoid=e=>{const{center:c,radius:r,segments:a,axes:s}=Object.assign({},{center:[0,0,0],radius:[1,1,1],segments:32,axes:[[1,0,0],[0,-1,0],[0,0,1]]},e);if(!isNumberArray(c,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(r,3))throw new Error("radius must be an array of X, Y and Z values");if(!r.every(e=>e>0))throw new Error("radius values must be greater than zero");if(!isGTE(a,4))throw new Error("segments must be four or more");const t=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[0]),r[0]),v=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[1]),r[1]),o=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[2]),r[2]),l=Math.round(a/4);let u;const i=[],d=vec3.create(),n=vec3.create();for(let e=0;e<=a;e++){const r=2*Math.PI*e/a,s=vec3.add(vec3.create(),vec3.scale(d,t,cos(r)),vec3.scale(n,v,sin(r)));if(e>0){let e,r;for(let a=0;a<=l;a++){const t=.5*Math.PI*a/l,v=cos(t),m=sin(t);if(a>0){let t,h=[];t=vec3.subtract(vec3.create(),vec3.scale(d,u,e),vec3.scale(n,o,r)),h.push(vec3.add(t,t,c)),t=vec3.subtract(vec3.create(),vec3.scale(d,s,e),vec3.scale(n,o,r)),h.push(vec3.add(t,t,c)),a<l&&(t=vec3.subtract(vec3.create(),vec3.scale(d,s,v),vec3.scale(n,o,m)),h.push(vec3.add(t,t,c))),t=vec3.subtract(vec3.create(),vec3.scale(d,u,v),vec3.scale(n,o,m)),h.push(vec3.add(t,t,c)),i.push(poly3.create(h)),h=[],t=vec3.add(vec3.create(),vec3.scale(d,u,e),vec3.scale(n,o,r)),h.push(vec3.add(vec3.create(),c,t)),t=vec3.add(t,vec3.scale(d,s,e),vec3.scale(n,o,r)),h.push(vec3.add(vec3.create(),c,t)),a<l&&(t=vec3.add(t,vec3.scale(d,s,v),vec3.scale(n,o,m)),h.push(vec3.add(vec3.create(),c,t))),t=vec3.add(t,vec3.scale(d,u,v),vec3.scale(n,o,m)),h.push(vec3.add(vec3.create(),c,t)),h.reverse(),i.push(poly3.create(h))}e=v,r=m}}u=s}return geom3.create(i)};module.exports=ellipsoid;
1105
+ },{"../geometries/geom2":22,"../maths/constants":90,"../maths/utils/trigonometry":168,"../maths/vec2":186,"./commonChecks":363}],369:[function(require,module,exports){
1106
+ const vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),ellipsoid=e=>{const{center:c,radius:r,segments:a,axes:s}=Object.assign({},{center:[0,0,0],radius:[1,1,1],segments:32,axes:[[1,0,0],[0,-1,0],[0,0,1]]},e);if(!isNumberArray(c,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(r,3))throw new Error("radius must be an array of X, Y and Z values");if(!r.every(e=>e>0))throw new Error("radius values must be greater than zero");if(!isGTE(a,4))throw new Error("segments must be four or more");const t=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[0]),r[0]),v=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[1]),r[1]),o=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),s[2]),r[2]),l=Math.round(a/4);let u;const i=[],d=vec3.create(),n=vec3.create();for(let e=0;e<=a;e++){const r=2*Math.PI*e/a,s=vec3.add(vec3.create(),vec3.scale(d,t,cos(r)),vec3.scale(n,v,sin(r)));if(e>0){let e,r;for(let a=0;a<=l;a++){const t=.5*Math.PI*a/l,v=cos(t),m=sin(t);if(a>0){let t,h=[];t=vec3.subtract(vec3.create(),vec3.scale(d,u,e),vec3.scale(n,o,r)),h.push(vec3.add(t,t,c)),t=vec3.subtract(vec3.create(),vec3.scale(d,s,e),vec3.scale(n,o,r)),h.push(vec3.add(t,t,c)),a<l&&(t=vec3.subtract(vec3.create(),vec3.scale(d,s,v),vec3.scale(n,o,m)),h.push(vec3.add(t,t,c))),t=vec3.subtract(vec3.create(),vec3.scale(d,u,v),vec3.scale(n,o,m)),h.push(vec3.add(t,t,c)),i.push(poly3.create(h)),h=[],t=vec3.add(vec3.create(),vec3.scale(d,u,e),vec3.scale(n,o,r)),h.push(vec3.add(vec3.create(),c,t)),t=vec3.add(t,vec3.scale(d,s,e),vec3.scale(n,o,r)),h.push(vec3.add(vec3.create(),c,t)),a<l&&(t=vec3.add(t,vec3.scale(d,s,v),vec3.scale(n,o,m)),h.push(vec3.add(vec3.create(),c,t))),t=vec3.add(t,vec3.scale(d,u,v),vec3.scale(n,o,m)),h.push(vec3.add(vec3.create(),c,t)),h.reverse(),i.push(poly3.create(h))}e=v,r=m}}u=s}return geom3.create(i)};module.exports=ellipsoid;
1107
1107
 
1108
- },{"../geometries/geom3":37,"../geometries/poly3":75,"../maths/vec3":217,"../utils/trigonometry":398,"./commonChecks":363}],370:[function(require,module,exports){
1109
- const mat4=require("../maths/mat4"),geom3=require("../geometries/geom3"),polyhedron=require("./polyhedron"),{isGT:isGT,isGTE:isGTE}=require("./commonChecks"),geodesicSphere=e=>{let{radius:t,frequency:r}=Object.assign({},{radius:1,frequency:6},e);if(!isGT(t,0))throw new Error("radius must be greater than zero");if(!isGTE(r,6))throw new Error("frequency must be six or more");r=Math.floor(r/6);const o=[[.850651,0,-.525731],[.850651,-0,.525731],[-.850651,-0,.525731],[-.850651,0,-.525731],[0,-.525731,.850651],[0,.525731,.850651],[0,.525731,-.850651],[0,-.525731,-.850651],[-.525731,-.850651,-0],[.525731,-.850651,-0],[.525731,.850651,0],[-.525731,.850651,0]],s=[[0,9,1],[1,10,0],[6,7,0],[10,6,0],[7,9,0],[5,1,4],[4,1,9],[5,10,1],[2,8,3],[3,11,2],[2,5,4],[4,8,2],[2,11,5],[3,7,6],[6,11,3],[8,7,3],[9,8,4],[11,10,5],[10,11,6],[8,9,7]],n=(e,t,r)=>{const o=e[0],s=e[1],n=e[2];let c=r;const a=[],f=[];for(let e=0;e<t;e++)for(let r=0;r<t-e;r++){const l=e/t,h=(e+1)/t,u=r/(t-e),m=(r+1)/(t-e),p=t-e-1?r/(t-e-1):1,g=[];g[0]=i(i(o,s,u),n,l),g[1]=i(i(o,s,m),n,l),g[2]=i(i(o,s,p),n,h);for(let e=0;e<3;e++){const t=Math.hypot(g[e][0],g[e][1],g[e][2]);for(let r=0;r<3;r++)g[e][r]/=t}if(a.push(g[0],g[1],g[2]),f.push([c,c+1,c+2]),c+=3,r<t-e-1){const u=t-e-1?(r+1)/(t-e-1):1;g[0]=i(i(o,s,m),n,l),g[1]=i(i(o,s,u),n,h),g[2]=i(i(o,s,p),n,h);for(let e=0;e<3;e++){const t=Math.hypot(g[e][0],g[e][1],g[e][2]);for(let r=0;r<3;r++)g[e][r]/=t}a.push(g[0],g[1],g[2]),f.push([c,c+1,c+2]),c+=3}}return{points:a,triangles:f,offset:c}},i=(e,t,r)=>{const o=1-r,s=[];for(let n=0;n<3;n++)s[n]=e[n]*o+t[n]*r;return s};let c=[],a=[],f=0;for(let e=0;e<s.length;e++){const t=n([o[s[e][0]],o[s[e][1]],o[s[e][2]]],r,f);c=c.concat(t.points),a=a.concat(t.triangles),f=t.offset}let l=polyhedron({points:c,faces:a,orientation:"inward"});return 1!==t&&(l=geom3.transform(mat4.fromScaling(mat4.create(),[t,t,t]),l)),l};module.exports=geodesicSphere;
1108
+ },{"../geometries/geom3":37,"../geometries/poly3":75,"../maths/utils/trigonometry":168,"../maths/vec3":217,"./commonChecks":363}],370:[function(require,module,exports){
1109
+ const mat4=require("../maths/mat4"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),polyhedron=require("./polyhedron"),{isGT:isGT,isGTE:isGTE}=require("./commonChecks"),geodesicSphere=e=>{let{radius:r,frequency:t}=Object.assign({},{radius:1,frequency:6},e);if(!isGT(r,0))throw new Error("radius must be greater than zero");if(!isGTE(t,6))throw new Error("frequency must be six or more");t=Math.floor(t/6);const o=[[.850651,0,-.525731],[.850651,-0,.525731],[-.850651,-0,.525731],[-.850651,0,-.525731],[0,-.525731,.850651],[0,.525731,.850651],[0,.525731,-.850651],[0,-.525731,-.850651],[-.525731,-.850651,-0],[.525731,-.850651,-0],[.525731,.850651,0],[-.525731,.850651,0]],s=[[0,9,1],[1,10,0],[6,7,0],[10,6,0],[7,9,0],[5,1,4],[4,1,9],[5,10,1],[2,8,3],[3,11,2],[2,5,4],[4,8,2],[2,11,5],[3,7,6],[6,11,3],[8,7,3],[9,8,4],[11,10,5],[10,11,6],[8,9,7]],n=(e,r,t)=>{const o=e[0],s=e[1],n=e[2];let c=t;const a=[],l=[];for(let e=0;e<r;e++)for(let t=0;t<r-e;t++){const f=e/r,u=(e+1)/r,h=t/(r-e),m=(t+1)/(r-e),g=r-e-1?t/(r-e-1):1,p=[];p[0]=i(i(o,s,h),n,f),p[1]=i(i(o,s,m),n,f),p[2]=i(i(o,s,g),n,u);for(let e=0;e<3;e++){const r=vec3.length(p[e]);for(let t=0;t<3;t++)p[e][t]/=r}if(a.push(p[0],p[1],p[2]),l.push([c,c+1,c+2]),c+=3,t<r-e-1){const h=r-e-1?(t+1)/(r-e-1):1;p[0]=i(i(o,s,m),n,f),p[1]=i(i(o,s,h),n,u),p[2]=i(i(o,s,g),n,u);for(let e=0;e<3;e++){const r=vec3.length(p[e]);for(let t=0;t<3;t++)p[e][t]/=r}a.push(p[0],p[1],p[2]),l.push([c,c+1,c+2]),c+=3}}return{points:a,triangles:l,offset:c}},i=(e,r,t)=>{const o=1-t,s=[];for(let n=0;n<3;n++)s[n]=e[n]*o+r[n]*t;return s};let c=[],a=[],l=0;for(let e=0;e<s.length;e++){const r=n([o[s[e][0]],o[s[e][1]],o[s[e][2]]],t,l);c=c.concat(r.points),a=a.concat(r.triangles),l=r.offset}let f=polyhedron({points:c,faces:a,orientation:"inward"});return 1!==r&&(f=geom3.transform(mat4.fromScaling(mat4.create(),[r,r,r]),f)),f};module.exports=geodesicSphere;
1110
1110
 
1111
- },{"../geometries/geom3":37,"../maths/mat4":140,"./commonChecks":363,"./polyhedron":374}],371:[function(require,module,exports){
1111
+ },{"../geometries/geom3":37,"../maths/mat4":139,"../maths/vec3":217,"./commonChecks":363,"./polyhedron":374}],371:[function(require,module,exports){
1112
1112
  module.exports={arc:require("./arc"),circle:require("./circle"),cube:require("./cube"),cuboid:require("./cuboid"),cylinder:require("./cylinder"),cylinderElliptic:require("./cylinderElliptic"),ellipse:require("./ellipse"),ellipsoid:require("./ellipsoid"),geodesicSphere:require("./geodesicSphere"),line:require("./line"),polygon:require("./polygon"),polyhedron:require("./polyhedron"),rectangle:require("./rectangle"),roundedCuboid:require("./roundedCuboid"),roundedCylinder:require("./roundedCylinder"),roundedRectangle:require("./roundedRectangle"),sphere:require("./sphere"),square:require("./square"),star:require("./star"),torus:require("./torus"),triangle:require("./triangle")};
1113
1113
 
1114
1114
  },{"./arc":361,"./circle":362,"./cube":364,"./cuboid":365,"./cylinder":366,"./cylinderElliptic":367,"./ellipse":368,"./ellipsoid":369,"./geodesicSphere":370,"./line":372,"./polygon":373,"./polyhedron":374,"./rectangle":375,"./roundedCuboid":376,"./roundedCylinder":377,"./roundedRectangle":378,"./sphere":379,"./square":380,"./star":381,"./torus":382,"./triangle":383}],372:[function(require,module,exports){
@@ -1124,12 +1124,12 @@ const geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),
1124
1124
  const vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{isNumberArray:isNumberArray}=require("./commonChecks"),rectangle=e=>{const{center:r,size:t}=Object.assign({},{center:[0,0],size:[2,2]},e);if(!isNumberArray(r,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(t,2))throw new Error("size must be an array of X and Y values");if(!t.every(e=>e>0))throw new Error("size values must be greater than zero");const a=[t[0]/2,t[1]/2],c=[a[0],-a[1]],s=[vec2.subtract(vec2.create(),r,a),vec2.add(vec2.create(),r,c),vec2.add(vec2.create(),r,a),vec2.subtract(vec2.create(),r,c)];return geom2.fromPoints(s)};module.exports=rectangle;
1125
1125
 
1126
1126
  },{"../geometries/geom2":22,"../maths/vec2":186,"./commonChecks":363}],376:[function(require,module,exports){
1127
- const{EPS:EPS}=require("../maths/constants"),vec2=require("../maths/vec2"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),createCorners=(e,r,t,s,c,o)=>{const a=Math.PI/2*c/s,n=Math.cos(a),h=Math.sin(a),u=s-c;let i=t*n,l=r[2]-(t-t*h);o||(l=t-t*h-r[2]),i=i>EPS?i:0;const d=vec3.add(vec3.create(),e,[r[0]-t,r[1]-t,l]),v=vec3.add(vec3.create(),e,[t-r[0],r[1]-t,l]),m=vec3.add(vec3.create(),e,[t-r[0],t-r[1],l]),p=vec3.add(vec3.create(),e,[r[0]-t,t-r[1],l]),f=[],g=[],E=[],y=[];for(let e=0;e<=u;e++){const r=u>0?Math.PI/2*e/u:0,t=vec2.fromAngleRadians(vec2.create(),r);vec2.scale(t,t,i);const s=vec3.fromVec2(vec3.create(),t);f.push(vec3.add(vec3.create(),d,s)),vec3.rotateZ(s,s,[0,0,0],Math.PI/2),g.push(vec3.add(vec3.create(),v,s)),vec3.rotateZ(s,s,[0,0,0],Math.PI/2),E.push(vec3.add(vec3.create(),m,s)),vec3.rotateZ(s,s,[0,0,0],Math.PI/2),y.push(vec3.add(vec3.create(),p,s))}return o?[f,g,E,y]:(f.reverse(),g.reverse(),E.reverse(),y.reverse(),[y,E,g,f])},stitchCorners=(e,r)=>{const t=[];for(let s=0;s<e.length;s++){const c=e[s],o=r[s];for(let e=0;e<c.length-1;e++)t.push(poly3.create([c[e],c[e+1],o[e]])),e<o.length-1&&t.push(poly3.create([o[e],c[e+1],o[e+1]]))}return t},stitchWalls=(e,r)=>{const t=[];for(let s=0;s<e.length;s++){let c=e[s],o=r[s];const a=c[c.length-1],n=o[o.length-1],h=(s+1)%e.length;c=e[h],o=r[h];const u=c[0],i=o[0];t.push(poly3.create([a,u,i,n]))}return t},stitchSides=(e,r)=>{e=(e=[e[3],e[2],e[1],e[0]]).map(e=>e.slice().reverse());const t=[];e.forEach(e=>{e.forEach(e=>t.push(e))});const s=[];r.forEach(e=>{e.forEach(e=>s.push(e))});const c=[];for(let e=0;e<s.length;e++){const r=(e+1)%s.length;c.push(poly3.create([t[e],t[r],s[r],s[e]]))}return c},roundedCuboid=e=>{let{center:r,size:t,roundRadius:s,segments:c}=Object.assign({},{center:[0,0,0],size:[2,2,2],roundRadius:.2,segments:32},e);if(!isNumberArray(r,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(t,3))throw new Error("size must be an array of X, Y and Z values");if(!t.every(e=>e>0))throw new Error("size values must be greater than zero");if(!isGT(s,0))throw new Error("roundRadius must be greater than zero");if(!isGTE(c,4))throw new Error("segments must be four or more");if(s>(t=t.map(e=>e/2))[0]-EPS||s>t[1]-EPS||s>t[2]-EPS)throw new Error("roundRadius must be smaller then the radius of all dimensions");c=Math.floor(c/4);let o=null,a=null,n=[];for(let e=0;e<=c;e++){const h=createCorners(r,t,s,c,e,!0),u=createCorners(r,t,s,c,e,!1);if(0===e&&(n=n.concat(stitchSides(u,h))),o&&(n=n.concat(stitchCorners(o,h),stitchWalls(o,h))),a&&(n=n.concat(stitchCorners(a,u),stitchWalls(a,u))),e===c){let e=h.map(e=>e[0]);n.push(poly3.create(e)),e=u.map(e=>e[0]),n.push(poly3.create(e))}o=h,a=u}return geom3.create(n)};module.exports=roundedCuboid;
1127
+ const{EPS:EPS}=require("../maths/constants"),vec2=require("../maths/vec2"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),createCorners=(e,r,t,s,c,o)=>{const a=Math.PI/2*c/s,n=cos(a),i=sin(a),u=s-c;let h=t*n,l=r[2]-(t-t*i);o||(l=t-t*i-r[2]),h=h>EPS?h:0;const d=vec3.add(vec3.create(),e,[r[0]-t,r[1]-t,l]),v=vec3.add(vec3.create(),e,[t-r[0],r[1]-t,l]),m=vec3.add(vec3.create(),e,[t-r[0],t-r[1],l]),p=vec3.add(vec3.create(),e,[r[0]-t,t-r[1],l]),f=[],g=[],E=[],y=[];for(let e=0;e<=u;e++){const r=u>0?Math.PI/2*e/u:0,t=vec2.fromAngleRadians(vec2.create(),r);vec2.scale(t,t,h);const s=vec3.fromVec2(vec3.create(),t);f.push(vec3.add(vec3.create(),d,s)),vec3.rotateZ(s,s,[0,0,0],Math.PI/2),g.push(vec3.add(vec3.create(),v,s)),vec3.rotateZ(s,s,[0,0,0],Math.PI/2),E.push(vec3.add(vec3.create(),m,s)),vec3.rotateZ(s,s,[0,0,0],Math.PI/2),y.push(vec3.add(vec3.create(),p,s))}return o?[f,g,E,y]:(f.reverse(),g.reverse(),E.reverse(),y.reverse(),[y,E,g,f])},stitchCorners=(e,r)=>{const t=[];for(let s=0;s<e.length;s++){const c=e[s],o=r[s];for(let e=0;e<c.length-1;e++)t.push(poly3.create([c[e],c[e+1],o[e]])),e<o.length-1&&t.push(poly3.create([o[e],c[e+1],o[e+1]]))}return t},stitchWalls=(e,r)=>{const t=[];for(let s=0;s<e.length;s++){let c=e[s],o=r[s];const a=c[c.length-1],n=o[o.length-1],i=(s+1)%e.length;c=e[i],o=r[i];const u=c[0],h=o[0];t.push(poly3.create([a,u,h,n]))}return t},stitchSides=(e,r)=>{e=(e=[e[3],e[2],e[1],e[0]]).map(e=>e.slice().reverse());const t=[];e.forEach(e=>{e.forEach(e=>t.push(e))});const s=[];r.forEach(e=>{e.forEach(e=>s.push(e))});const c=[];for(let e=0;e<s.length;e++){const r=(e+1)%s.length;c.push(poly3.create([t[e],t[r],s[r],s[e]]))}return c},roundedCuboid=e=>{let{center:r,size:t,roundRadius:s,segments:c}=Object.assign({},{center:[0,0,0],size:[2,2,2],roundRadius:.2,segments:32},e);if(!isNumberArray(r,3))throw new Error("center must be an array of X, Y and Z values");if(!isNumberArray(t,3))throw new Error("size must be an array of X, Y and Z values");if(!t.every(e=>e>0))throw new Error("size values must be greater than zero");if(!isGT(s,0))throw new Error("roundRadius must be greater than zero");if(!isGTE(c,4))throw new Error("segments must be four or more");if(s>(t=t.map(e=>e/2))[0]-EPS||s>t[1]-EPS||s>t[2]-EPS)throw new Error("roundRadius must be smaller then the radius of all dimensions");c=Math.floor(c/4);let o=null,a=null,n=[];for(let e=0;e<=c;e++){const i=createCorners(r,t,s,c,e,!0),u=createCorners(r,t,s,c,e,!1);if(0===e&&(n=n.concat(stitchSides(u,i))),o&&(n=n.concat(stitchCorners(o,i),stitchWalls(o,i))),a&&(n=n.concat(stitchCorners(a,u),stitchWalls(a,u))),e===c){let e=i.map(e=>e[0]);n.push(poly3.create(e)),e=u.map(e=>e[0]),n.push(poly3.create(e))}o=i,a=u}return geom3.create(n)};module.exports=roundedCuboid;
1128
1128
 
1129
- },{"../geometries/geom3":37,"../geometries/poly3":75,"../maths/constants":90,"../maths/vec2":186,"../maths/vec3":217,"./commonChecks":363}],377:[function(require,module,exports){
1130
- const{EPS:EPS}=require("../maths/constants"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../utils/trigonometry"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),roundedCylinder=e=>{const{center:c,height:r,radius:s,roundRadius:a,segments:t}=Object.assign({},{center:[0,0,0],height:2,radius:1,roundRadius:.2,segments:32},e);if(!isNumberArray(c,3))throw new Error("center must be an array of X, Y and Z values");if(!isGT(r,0))throw new Error("height must be greater then zero");if(!isGT(s,0))throw new Error("radius must be greater then zero");if(!isGT(a,0))throw new Error("roundRadius must be greater then zero");if(a>s-EPS)throw new Error("roundRadius must be smaller then the radius");if(!isGTE(t,4))throw new Error("segments must be four or more");const v=[0,0,-r/2],o=[0,0,r/2],u=vec3.subtract(vec3.create(),o,v);if(2*a>vec3.length(u)-EPS)throw new Error("height must be larger than twice roundRadius");let d;d=Math.abs(u[0])>Math.abs(u[1])?vec3.fromValues(0,1,0):vec3.fromValues(1,0,0);const i=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),u),a),n=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),vec3.cross(vec3.create(),i,d)),s),h=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),vec3.cross(vec3.create(),n,i)),s);vec3.add(v,v,i),vec3.subtract(o,o,i);const l=Math.floor(.25*t),m=e=>{const r=e.map(e=>vec3.add(e,e,c));return poly3.create(r)},p=[],b=vec3.create(),g=vec3.create();let f;for(let e=0;e<=t;e++){const c=2*Math.PI*e/t,r=vec3.add(vec3.create(),vec3.scale(b,n,cos(c)),vec3.scale(g,h,sin(c)));if(e>0){let e,c,s=[];s.push(vec3.add(vec3.create(),v,r)),s.push(vec3.add(vec3.create(),v,f)),s.push(vec3.add(vec3.create(),o,f)),s.push(vec3.add(vec3.create(),o,r)),p.push(m(s));for(let a=0;a<=l;a++){const t=.5*Math.PI*a/l,u=cos(t),d=sin(t);if(a>0){let t;s=[],t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,f,e),vec3.scale(g,i,c))),s.push(t),t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,r,e),vec3.scale(g,i,c))),s.push(t),a<l&&(t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,r,u),vec3.scale(g,i,d))),s.push(t)),t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,f,u),vec3.scale(g,i,d))),s.push(t),p.push(m(s)),s=[],t=vec3.add(vec3.create(),vec3.scale(b,f,e),vec3.scale(g,i,c)),vec3.add(t,t,o),s.push(t),t=vec3.add(vec3.create(),vec3.scale(b,r,e),vec3.scale(g,i,c)),vec3.add(t,t,o),s.push(t),a<l&&(t=vec3.add(vec3.create(),vec3.scale(b,r,u),vec3.scale(g,i,d)),vec3.add(t,t,o),s.push(t)),t=vec3.add(vec3.create(),vec3.scale(b,f,u),vec3.scale(g,i,d)),vec3.add(t,t,o),s.push(t),s.reverse(),p.push(m(s))}e=u,c=d}}f=r}return geom3.create(p)};module.exports=roundedCylinder;
1129
+ },{"../geometries/geom3":37,"../geometries/poly3":75,"../maths/constants":90,"../maths/utils/trigonometry":168,"../maths/vec2":186,"../maths/vec3":217,"./commonChecks":363}],377:[function(require,module,exports){
1130
+ const{EPS:EPS}=require("../maths/constants"),vec3=require("../maths/vec3"),geom3=require("../geometries/geom3"),poly3=require("../geometries/poly3"),{sin:sin,cos:cos}=require("../maths/utils/trigonometry"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),roundedCylinder=e=>{const{center:c,height:r,radius:s,roundRadius:a,segments:t}=Object.assign({},{center:[0,0,0],height:2,radius:1,roundRadius:.2,segments:32},e);if(!isNumberArray(c,3))throw new Error("center must be an array of X, Y and Z values");if(!isGT(r,0))throw new Error("height must be greater then zero");if(!isGT(s,0))throw new Error("radius must be greater then zero");if(!isGT(a,0))throw new Error("roundRadius must be greater then zero");if(a>s-EPS)throw new Error("roundRadius must be smaller then the radius");if(!isGTE(t,4))throw new Error("segments must be four or more");const v=[0,0,-r/2],o=[0,0,r/2],u=vec3.subtract(vec3.create(),o,v);if(2*a>vec3.length(u)-EPS)throw new Error("height must be larger than twice roundRadius");let d;d=Math.abs(u[0])>Math.abs(u[1])?vec3.fromValues(0,1,0):vec3.fromValues(1,0,0);const i=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),u),a),n=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),vec3.cross(vec3.create(),i,d)),s),h=vec3.scale(vec3.create(),vec3.normalize(vec3.create(),vec3.cross(vec3.create(),n,i)),s);vec3.add(v,v,i),vec3.subtract(o,o,i);const l=Math.floor(.25*t),m=e=>{const r=e.map(e=>vec3.add(e,e,c));return poly3.create(r)},p=[],b=vec3.create(),g=vec3.create();let f;for(let e=0;e<=t;e++){const c=2*Math.PI*e/t,r=vec3.add(vec3.create(),vec3.scale(b,n,cos(c)),vec3.scale(g,h,sin(c)));if(e>0){let e,c,s=[];s.push(vec3.add(vec3.create(),v,r)),s.push(vec3.add(vec3.create(),v,f)),s.push(vec3.add(vec3.create(),o,f)),s.push(vec3.add(vec3.create(),o,r)),p.push(m(s));for(let a=0;a<=l;a++){const t=.5*Math.PI*a/l,u=cos(t),d=sin(t);if(a>0){let t;s=[],t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,f,e),vec3.scale(g,i,c))),s.push(t),t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,r,e),vec3.scale(g,i,c))),s.push(t),a<l&&(t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,r,u),vec3.scale(g,i,d))),s.push(t)),t=vec3.add(vec3.create(),v,vec3.subtract(b,vec3.scale(b,f,u),vec3.scale(g,i,d))),s.push(t),p.push(m(s)),s=[],t=vec3.add(vec3.create(),vec3.scale(b,f,e),vec3.scale(g,i,c)),vec3.add(t,t,o),s.push(t),t=vec3.add(vec3.create(),vec3.scale(b,r,e),vec3.scale(g,i,c)),vec3.add(t,t,o),s.push(t),a<l&&(t=vec3.add(vec3.create(),vec3.scale(b,r,u),vec3.scale(g,i,d)),vec3.add(t,t,o),s.push(t)),t=vec3.add(vec3.create(),vec3.scale(b,f,u),vec3.scale(g,i,d)),vec3.add(t,t,o),s.push(t),s.reverse(),p.push(m(s))}e=u,c=d}}f=r}return geom3.create(p)};module.exports=roundedCylinder;
1131
1131
 
1132
- },{"../geometries/geom3":37,"../geometries/poly3":75,"../maths/constants":90,"../maths/vec3":217,"../utils/trigonometry":398,"./commonChecks":363}],378:[function(require,module,exports){
1132
+ },{"../geometries/geom3":37,"../geometries/poly3":75,"../maths/constants":90,"../maths/utils/trigonometry":168,"../maths/vec3":217,"./commonChecks":363}],378:[function(require,module,exports){
1133
1133
  const{EPS:EPS}=require("../maths/constants"),vec2=require("../maths/vec2"),geom2=require("../geometries/geom2"),{isGT:isGT,isGTE:isGTE,isNumberArray:isNumberArray}=require("./commonChecks"),roundedRectangle=e=>{let{center:r,size:a,roundRadius:t,segments:s}=Object.assign({},{center:[0,0],size:[2,2],roundRadius:.2,segments:32},e);if(!isNumberArray(r,2))throw new Error("center must be an array of X and Y values");if(!isNumberArray(a,2))throw new Error("size must be an array of X and Y values");if(!a.every(e=>e>0))throw new Error("size values must be greater than zero");if(!isGT(t,0))throw new Error("roundRadius must be greater than zero");if(!isGTE(s,4))throw new Error("segments must be four or more");if(t>(a=a.map(e=>e/2))[0]-EPS||t>a[1]-EPS)throw new Error("roundRadius must be smaller then the radius of all dimensions");const c=Math.floor(s/4),o=vec2.add(vec2.create(),r,[a[0]-t,a[1]-t]),n=vec2.add(vec2.create(),r,[t-a[0],a[1]-t]),i=vec2.add(vec2.create(),r,[t-a[0],t-a[1]]),u=vec2.add(vec2.create(),r,[a[0]-t,t-a[1]]),d=[],v=[],m=[],h=[];for(let e=0;e<=c;e++){const r=Math.PI/2*e/c,a=vec2.fromAngleRadians(vec2.create(),r);vec2.scale(a,a,t),d.push(vec2.add(vec2.create(),o,a)),vec2.rotate(a,a,vec2.create(),Math.PI/2),v.push(vec2.add(vec2.create(),n,a)),vec2.rotate(a,a,vec2.create(),Math.PI/2),m.push(vec2.add(vec2.create(),i,a)),vec2.rotate(a,a,vec2.create(),Math.PI/2),h.push(vec2.add(vec2.create(),u,a))}return geom2.fromPoints(d.concat(v,m,h))};module.exports=roundedRectangle;
1134
1134
 
1135
1135
  },{"../geometries/geom2":22,"../maths/constants":90,"../maths/vec2":186,"./commonChecks":363}],379:[function(require,module,exports){
@@ -1175,9 +1175,9 @@ const flatten=t=>t.reduce((t,a)=>Array.isArray(a)?t.concat(flatten(a)):t.concat(
1175
1175
  const fnNumberSort=(o,r)=>o-r;module.exports=fnNumberSort;
1176
1176
 
1177
1177
  },{}],393:[function(require,module,exports){
1178
- module.exports={areAllShapesTheSameType:require("./areAllShapesTheSameType"),cos:require("./trigonometry").cos,degToRad:require("./degToRad"),flatten:require("./flatten"),fnNumberSort:require("./fnNumberSort"),insertSorted:require("./insertSorted"),radiusToSegments:require("./radiusToSegments"),radToDeg:require("./radToDeg"),sin:require("./trigonometry").sin};
1178
+ module.exports={areAllShapesTheSameType:require("./areAllShapesTheSameType"),degToRad:require("./degToRad"),flatten:require("./flatten"),fnNumberSort:require("./fnNumberSort"),insertSorted:require("./insertSorted"),radiusToSegments:require("./radiusToSegments"),radToDeg:require("./radToDeg")};
1179
1179
 
1180
- },{"./areAllShapesTheSameType":389,"./degToRad":390,"./flatten":391,"./fnNumberSort":392,"./insertSorted":394,"./radToDeg":396,"./radiusToSegments":397,"./trigonometry":398}],394:[function(require,module,exports){
1180
+ },{"./areAllShapesTheSameType":389,"./degToRad":390,"./flatten":391,"./fnNumberSort":392,"./insertSorted":394,"./radToDeg":396,"./radiusToSegments":397}],394:[function(require,module,exports){
1181
1181
  const insertSorted=(t,e,o)=>{let r=0,s=t.length;for(;s>r;){const l=Math.floor((r+s)/2);o(e,t[l])>0?r=l+1:s=l}t.splice(r,0,e)};module.exports=insertSorted;
1182
1182
 
1183
1183
  },{}],395:[function(require,module,exports){
@@ -1189,8 +1189,5 @@ const radToDeg=o=>57.29577951308232*o;module.exports=radToDeg;
1189
1189
  },{}],397:[function(require,module,exports){
1190
1190
  const radiusToSegments=(t,e,a)=>{const s=e>0?2*t*Math.PI/e:0,o=a>0?2*Math.PI/a:0;return Math.ceil(Math.max(s,o,4))};module.exports=radiusToSegments;
1191
1191
 
1192
- },{}],398:[function(require,module,exports){
1193
- const{NEPS:NEPS}=require("../maths/constants"),rezero=s=>Math.abs(s)<NEPS?0:s,sin=s=>rezero(Math.sin(s)),cos=s=>rezero(Math.cos(s));module.exports={sin:sin,cos:cos};
1194
-
1195
- },{"../maths/constants":90}]},{},[88])(88)
1192
+ },{}]},{},[88])(88)
1196
1193
  });