pts 0.10.12 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/{pts.d.ts → index.d.ts} +1245 -1207
  2. package/dist/index.js +6825 -6660
  3. package/dist/index.mjs +6785 -0
  4. package/package.json +12 -33
  5. package/tsup.browser.js +21 -0
  6. package/tsup.min.js +23 -0
  7. package/tsup.module.js +15 -0
  8. package/dist/es2015/Canvas.js +0 -684
  9. package/dist/es2015/Canvas.js.map +0 -1
  10. package/dist/es2015/Color.js +0 -337
  11. package/dist/es2015/Color.js.map +0 -1
  12. package/dist/es2015/Create.js +0 -275
  13. package/dist/es2015/Create.js.map +0 -1
  14. package/dist/es2015/Dom.js +0 -448
  15. package/dist/es2015/Dom.js.map +0 -1
  16. package/dist/es2015/Form.js +0 -80
  17. package/dist/es2015/Form.js.map +0 -1
  18. package/dist/es2015/Image.js +0 -220
  19. package/dist/es2015/Image.js.map +0 -1
  20. package/dist/es2015/LinearAlgebra.js +0 -286
  21. package/dist/es2015/LinearAlgebra.js.map +0 -1
  22. package/dist/es2015/Num.js +0 -477
  23. package/dist/es2015/Num.js.map +0 -1
  24. package/dist/es2015/Op.js +0 -978
  25. package/dist/es2015/Op.js.map +0 -1
  26. package/dist/es2015/Physics.js +0 -383
  27. package/dist/es2015/Physics.js.map +0 -1
  28. package/dist/es2015/Play.js +0 -339
  29. package/dist/es2015/Play.js.map +0 -1
  30. package/dist/es2015/Pt.js +0 -463
  31. package/dist/es2015/Pt.js.map +0 -1
  32. package/dist/es2015/Space.js +0 -331
  33. package/dist/es2015/Space.js.map +0 -1
  34. package/dist/es2015/Svg.js +0 -367
  35. package/dist/es2015/Svg.js.map +0 -1
  36. package/dist/es2015/Types.js +0 -3
  37. package/dist/es2015/Types.js.map +0 -1
  38. package/dist/es2015/Typography.js +0 -40
  39. package/dist/es2015/Typography.js.map +0 -1
  40. package/dist/es2015/UI.js +0 -273
  41. package/dist/es2015/UI.js.map +0 -1
  42. package/dist/es2015/Util.js +0 -200
  43. package/dist/es2015/Util.js.map +0 -1
  44. package/dist/es2015/_lib.js +0 -45
  45. package/dist/es2015/_lib.js.map +0 -1
  46. package/dist/es2015/_module.js +0 -18
  47. package/dist/es2015/_module.js.map +0 -1
  48. package/dist/es2015/uheprng.js +0 -69
  49. package/dist/es2015/uheprng.js.map +0 -1
  50. package/dist/index.js.map +0 -1
package/dist/es2015/Op.js DELETED
@@ -1,978 +0,0 @@
1
- /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
2
- import { Util } from "./Util";
3
- import { Geom, Num } from "./Num";
4
- import { Pt, Group } from "./Pt";
5
- import { Mat } from "./LinearAlgebra";
6
- let _errorLength = (obj, param = "expected") => Util.warn("Group's length is less than " + param, obj);
7
- let _errorOutofBound = (obj, param = "") => Util.warn(`Index ${param} is out of bound in Group`, obj);
8
- export class Line {
9
- static fromAngle(anchor, angle, magnitude) {
10
- let g = new Group(new Pt(anchor), new Pt(anchor));
11
- g[1].toAngle(angle, magnitude, true);
12
- return g;
13
- }
14
- static slope(p1, p2) {
15
- return (p2[0] - p1[0] === 0) ? undefined : (p2[1] - p1[1]) / (p2[0] - p1[0]);
16
- }
17
- static intercept(p1, p2) {
18
- if (p2[0] - p1[0] === 0) {
19
- return undefined;
20
- }
21
- else {
22
- let m = (p2[1] - p1[1]) / (p2[0] - p1[0]);
23
- let c = p1[1] - m * p1[0];
24
- return { slope: m, yi: c, xi: (m === 0) ? undefined : -c / m };
25
- }
26
- }
27
- static sideOfPt2D(line, pt) {
28
- let _line = Util.iterToArray(line);
29
- return (_line[1][0] - _line[0][0]) * (pt[1] - _line[0][1]) - (pt[0] - _line[0][0]) * (_line[1][1] - _line[0][1]);
30
- }
31
- static collinear(p1, p2, p3, threshold = 0.01) {
32
- let a = new Pt(0, 0, 0).to(p1).$subtract(p2);
33
- let b = new Pt(0, 0, 0).to(p1).$subtract(p3);
34
- return a.$cross(b).divide(1000).equals(new Pt(0, 0, 0), threshold);
35
- }
36
- static magnitude(line) {
37
- let _line = Util.iterToArray(line);
38
- return (_line.length >= 2) ? _line[1].$subtract(_line[0]).magnitude() : 0;
39
- }
40
- static magnitudeSq(line) {
41
- let _line = Util.iterToArray(line);
42
- return (_line.length >= 2) ? _line[1].$subtract(_line[0]).magnitudeSq() : 0;
43
- }
44
- static perpendicularFromPt(line, pt, asProjection = false) {
45
- let _line = Util.iterToArray(line);
46
- if (_line[0].equals(_line[1]))
47
- return undefined;
48
- let a = _line[0].$subtract(_line[1]);
49
- let b = _line[1].$subtract(pt);
50
- let proj = b.$subtract(a.$project(b));
51
- return (asProjection) ? proj : proj.$add(pt);
52
- }
53
- static distanceFromPt(line, pt) {
54
- let _line = Util.iterToArray(line);
55
- let projectionVector = Line.perpendicularFromPt(_line, pt, true);
56
- if (projectionVector) {
57
- return projectionVector.magnitude();
58
- }
59
- else {
60
- return _line[0].$subtract(pt).magnitude();
61
- }
62
- }
63
- static intersectRay2D(la, lb) {
64
- let _la = Util.iterToArray(la);
65
- let _lb = Util.iterToArray(lb);
66
- let a = Line.intercept(_la[0], _la[1]);
67
- let b = Line.intercept(_lb[0], _lb[1]);
68
- let pa = _la[0];
69
- let pb = _lb[0];
70
- if (a == undefined) {
71
- if (b == undefined)
72
- return undefined;
73
- let y1 = -b.slope * (pb[0] - pa[0]) + pb[1];
74
- return new Pt(pa[0], y1);
75
- }
76
- else {
77
- if (b == undefined) {
78
- let y1 = -a.slope * (pa[0] - pb[0]) + pa[1];
79
- return new Pt(pb[0], y1);
80
- }
81
- else if (b.slope != a.slope) {
82
- let px = (a.slope * pa[0] - b.slope * pb[0] + pb[1] - pa[1]) / (a.slope - b.slope);
83
- let py = a.slope * (px - pa[0]) + pa[1];
84
- return new Pt(px, py);
85
- }
86
- else {
87
- if (a.yi == b.yi) {
88
- return new Pt(pa[0], pa[1]);
89
- }
90
- else {
91
- return undefined;
92
- }
93
- }
94
- }
95
- }
96
- static intersectLine2D(la, lb) {
97
- let _la = Util.iterToArray(la);
98
- let _lb = Util.iterToArray(lb);
99
- let pt = Line.intersectRay2D(_la, _lb);
100
- return (pt && Geom.withinBound(pt, _la[0], _la[1]) && Geom.withinBound(pt, _lb[0], _lb[1])) ? pt : undefined;
101
- }
102
- static intersectLineWithRay2D(line, ray) {
103
- let _line = Util.iterToArray(line);
104
- let _ray = Util.iterToArray(ray);
105
- let pt = Line.intersectRay2D(_line, _ray);
106
- return (pt && Geom.withinBound(pt, _line[0], _line[1])) ? pt : undefined;
107
- }
108
- static intersectPolygon2D(lineOrRay, poly, sourceIsRay = false) {
109
- let _lineOrRay = Util.iterToArray(lineOrRay);
110
- let _poly = Util.iterToArray(poly);
111
- let fn = sourceIsRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;
112
- let pts = new Group();
113
- for (let i = 0, len = _poly.length; i < len; i++) {
114
- let next = (i === len - 1) ? 0 : i + 1;
115
- let d = fn([_poly[i], _poly[next]], _lineOrRay);
116
- if (d)
117
- pts.push(d);
118
- }
119
- return (pts.length > 0) ? pts : undefined;
120
- }
121
- static intersectLines2D(lines1, lines2, isRay = false) {
122
- let group = new Group();
123
- let fn = isRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;
124
- for (let l1 of lines1) {
125
- for (let l2 of lines2) {
126
- let _ip = fn(l1, l2);
127
- if (_ip)
128
- group.push(_ip);
129
- }
130
- }
131
- return group;
132
- }
133
- static intersectGridWithRay2D(ray, gridPt) {
134
- let _ray = Util.iterToArray(ray);
135
- let t = Line.intercept(new Pt(_ray[0]).subtract(gridPt), new Pt(_ray[1]).subtract(gridPt));
136
- let g = new Group();
137
- if (t && t.xi)
138
- g.push(new Pt(gridPt[0] + t.xi, gridPt[1]));
139
- if (t && t.yi)
140
- g.push(new Pt(gridPt[0], gridPt[1] + t.yi));
141
- return g;
142
- }
143
- static intersectGridWithLine2D(line, gridPt) {
144
- let _line = Util.iterToArray(line);
145
- let g = Line.intersectGridWithRay2D(_line, gridPt);
146
- let gg = new Group();
147
- for (let i = 0, len = g.length; i < len; i++) {
148
- if (Geom.withinBound(g[i], _line[0], _line[1]))
149
- gg.push(g[i]);
150
- }
151
- return gg;
152
- }
153
- static intersectRect2D(line, rect) {
154
- let _line = Util.iterToArray(line);
155
- let _rect = Util.iterToArray(rect);
156
- let box = Geom.boundingBox(Group.fromPtArray(_line));
157
- if (!Rectangle.hasIntersectRect2D(box, _rect))
158
- return new Group();
159
- return Line.intersectLines2D([_line], Rectangle.sides(_rect));
160
- }
161
- static subpoints(line, num) {
162
- let _line = Util.iterToArray(line);
163
- let pts = new Group();
164
- for (let i = 1; i <= num; i++) {
165
- pts.push(Geom.interpolate(_line[0], _line[1], i / (num + 1)));
166
- }
167
- return pts;
168
- }
169
- static crop(line, size, index = 0, cropAsCircle = true) {
170
- let _line = Util.iterToArray(line);
171
- let tdx = (index === 0) ? 1 : 0;
172
- let ls = _line[tdx].$subtract(_line[index]);
173
- if (ls[0] === 0 || size[0] === 0)
174
- return _line[index];
175
- if (cropAsCircle) {
176
- let d = ls.unit().multiply(size[1]);
177
- return _line[index].$add(d);
178
- }
179
- else {
180
- let rect = Rectangle.fromCenter(_line[index], size);
181
- let sides = Rectangle.sides(rect);
182
- let sideIdx = 0;
183
- if (Math.abs(ls[1] / ls[0]) > Math.abs(size[1] / size[0])) {
184
- sideIdx = (ls[1] < 0) ? 0 : 2;
185
- }
186
- else {
187
- sideIdx = (ls[0] < 0) ? 3 : 1;
188
- }
189
- return Line.intersectRay2D(sides[sideIdx], _line);
190
- }
191
- }
192
- static marker(line, size, graphic = ("arrow" || "line"), atTail = true) {
193
- let _line = Util.iterToArray(line);
194
- let h = atTail ? 0 : 1;
195
- let t = atTail ? 1 : 0;
196
- let unit = _line[h].$subtract(_line[t]);
197
- if (unit.magnitudeSq() === 0)
198
- return new Group();
199
- unit.unit();
200
- let ps = Geom.perpendicular(unit).multiply(size[0]).add(_line[t]);
201
- if (graphic == "arrow") {
202
- ps.add(unit.$multiply(size[1]));
203
- return new Group(_line[t], ps[0], ps[1]);
204
- }
205
- else {
206
- return new Group(ps[0], ps[1]);
207
- }
208
- }
209
- static toRect(line) {
210
- let _line = Util.iterToArray(line);
211
- return new Group(_line[0].$min(_line[1]), _line[0].$max(_line[1]));
212
- }
213
- }
214
- export class Rectangle {
215
- static from(topLeft, widthOrSize, height) {
216
- return Rectangle.fromTopLeft(topLeft, widthOrSize, height);
217
- }
218
- static fromTopLeft(topLeft, widthOrSize, height) {
219
- let size = (typeof widthOrSize == "number") ? [widthOrSize, (height || widthOrSize)] : widthOrSize;
220
- return new Group(new Pt(topLeft), new Pt(topLeft).add(size));
221
- }
222
- static fromCenter(center, widthOrSize, height) {
223
- let half = (typeof widthOrSize == "number") ? [widthOrSize / 2, (height || widthOrSize) / 2] : new Pt(widthOrSize).divide(2);
224
- return new Group(new Pt(center).subtract(half), new Pt(center).add(half));
225
- }
226
- static toCircle(pts, within = true) {
227
- return Circle.fromRect(pts, within);
228
- }
229
- static toSquare(pts, enclose = false) {
230
- let _pts = Util.iterToArray(pts);
231
- let s = Rectangle.size(_pts);
232
- let m = (enclose) ? s.maxValue().value : s.minValue().value;
233
- return Rectangle.fromCenter(Rectangle.center(_pts), m, m);
234
- }
235
- static size(pts) {
236
- let p = Util.iterToArray(pts);
237
- return p[0].$max(p[1]).subtract(p[0].$min(p[1]));
238
- }
239
- static center(pts) {
240
- let p = Util.iterToArray(pts);
241
- let min = p[0].$min(p[1]);
242
- let max = p[0].$max(p[1]);
243
- return min.add(max.$subtract(min).divide(2));
244
- }
245
- static corners(rect) {
246
- let _rect = Util.iterToArray(rect);
247
- let p0 = _rect[0].$min(_rect[1]);
248
- let p2 = _rect[0].$max(_rect[1]);
249
- return new Group(p0, new Pt(p2.x, p0.y), p2, new Pt(p0.x, p2.y));
250
- }
251
- static sides(rect) {
252
- let [p0, p1, p2, p3] = Rectangle.corners(rect);
253
- return [
254
- new Group(p0, p1), new Group(p1, p2),
255
- new Group(p2, p3), new Group(p3, p0)
256
- ];
257
- }
258
- static boundingBox(rects) {
259
- let _rects = Util.iterToArray(rects);
260
- let merged = Util.flatten(_rects, false);
261
- let min = Pt.make(2, Number.MAX_VALUE);
262
- let max = Pt.make(2, Number.MIN_VALUE);
263
- for (let i = 0, len = merged.length; i < len; i++) {
264
- let k = 0;
265
- for (let m of merged[i]) {
266
- min[k] = Math.min(min[k], m[k]);
267
- max[k] = Math.max(max[k], m[k]);
268
- if (++k >= 2)
269
- break;
270
- }
271
- }
272
- return new Group(min, max);
273
- }
274
- static polygon(rect) {
275
- return Rectangle.corners(rect);
276
- }
277
- static quadrants(rect, center) {
278
- let _rect = Util.iterToArray(rect);
279
- let corners = Rectangle.corners(_rect);
280
- let _center = (center != undefined) ? new Pt(center) : Rectangle.center(_rect);
281
- return corners.map((c) => new Group(c, _center).boundingBox());
282
- }
283
- static halves(rect, ratio = 0.5, asRows = false) {
284
- let _rect = Util.iterToArray(rect);
285
- let min = _rect[0].$min(_rect[1]);
286
- let max = _rect[0].$max(_rect[1]);
287
- let mid = (asRows) ? Num.lerp(min[1], max[1], ratio) : Num.lerp(min[0], max[0], ratio);
288
- return (asRows)
289
- ? [new Group(min, new Pt(max[0], mid)), new Group(new Pt(min[0], mid), max)]
290
- : [new Group(min, new Pt(mid, max[1])), new Group(new Pt(mid, min[1]), max)];
291
- }
292
- static withinBound(rect, pt) {
293
- let _rect = Util.iterToArray(rect);
294
- return Geom.withinBound(pt, _rect[0], _rect[1]);
295
- }
296
- static hasIntersectRect2D(rect1, rect2, resetBoundingBox = false) {
297
- let _rect1 = Util.iterToArray(rect1);
298
- let _rect2 = Util.iterToArray(rect2);
299
- if (resetBoundingBox) {
300
- _rect1 = Geom.boundingBox(_rect1);
301
- _rect2 = Geom.boundingBox(_rect2);
302
- }
303
- if (_rect1[0][0] > _rect2[1][0] || _rect2[0][0] > _rect1[1][0])
304
- return false;
305
- if (_rect1[0][1] > _rect2[1][1] || _rect2[0][1] > _rect1[1][1])
306
- return false;
307
- return true;
308
- }
309
- static intersectRect2D(rect1, rect2) {
310
- let _rect1 = Util.iterToArray(rect1);
311
- let _rect2 = Util.iterToArray(rect2);
312
- if (!Rectangle.hasIntersectRect2D(_rect1, _rect2))
313
- return new Group();
314
- return Line.intersectLines2D(Rectangle.sides(_rect1), Rectangle.sides(_rect2));
315
- }
316
- }
317
- export class Circle {
318
- static fromRect(pts, enclose = false) {
319
- let _pts = Util.iterToArray(pts);
320
- let r = 0;
321
- let min = r = Rectangle.size(_pts).minValue().value / 2;
322
- if (enclose) {
323
- let max = Rectangle.size(_pts).maxValue().value / 2;
324
- r = Math.sqrt(min * min + max * max);
325
- }
326
- else {
327
- r = min;
328
- }
329
- return new Group(Rectangle.center(_pts), new Pt(r, r));
330
- }
331
- static fromTriangle(pts, enclose = false) {
332
- if (enclose) {
333
- return Triangle.circumcircle(pts);
334
- }
335
- else {
336
- return Triangle.incircle(pts);
337
- }
338
- }
339
- static fromCenter(pt, radius) {
340
- return new Group(new Pt(pt), new Pt(radius, radius));
341
- }
342
- static withinBound(pts, pt, threshold = 0) {
343
- let _pts = Util.iterToArray(pts);
344
- let d = _pts[0].$subtract(pt);
345
- return d.dot(d) + threshold < _pts[1].x * _pts[1].x;
346
- }
347
- static intersectRay2D(circle, ray) {
348
- let _pts = Util.iterToArray(circle);
349
- let _ray = Util.iterToArray(ray);
350
- let d = _ray[0].$subtract(_ray[1]);
351
- let f = _pts[0].$subtract(_ray[0]);
352
- let a = d.dot(d);
353
- let b = f.dot(d);
354
- let c = f.dot(f) - _pts[1].x * _pts[1].x;
355
- let p = b / a;
356
- let q = c / a;
357
- let disc = p * p - q;
358
- if (disc < 0) {
359
- return new Group();
360
- }
361
- else {
362
- let discSqrt = Math.sqrt(disc);
363
- let t1 = -p + discSqrt;
364
- let p1 = _ray[0].$subtract(d.$multiply(t1));
365
- if (disc === 0)
366
- return new Group(p1);
367
- let t2 = -p - discSqrt;
368
- let p2 = _ray[0].$subtract(d.$multiply(t2));
369
- return new Group(p1, p2);
370
- }
371
- }
372
- static intersectLine2D(circle, line) {
373
- let _pts = Util.iterToArray(circle);
374
- let _line = Util.iterToArray(line);
375
- let ps = Circle.intersectRay2D(_pts, _line);
376
- let g = new Group();
377
- if (ps.length > 0) {
378
- for (let i = 0, len = ps.length; i < len; i++) {
379
- if (Rectangle.withinBound(_line, ps[i]))
380
- g.push(ps[i]);
381
- }
382
- }
383
- return g;
384
- }
385
- static intersectCircle2D(circle1, circle2) {
386
- let _pts = Util.iterToArray(circle1);
387
- let _circle = Util.iterToArray(circle2);
388
- let dv = _circle[0].$subtract(_pts[0]);
389
- let dr2 = dv.magnitudeSq();
390
- let dr = Math.sqrt(dr2);
391
- let ar = _pts[1].x;
392
- let br = _circle[1].x;
393
- let ar2 = ar * ar;
394
- let br2 = br * br;
395
- if (dr > ar + br) {
396
- return new Group();
397
- }
398
- else if (dr < Math.abs(ar - br)) {
399
- return new Group(_pts[0].clone());
400
- }
401
- else {
402
- let a = (ar2 - br2 + dr2) / (2 * dr);
403
- let h = Math.sqrt(ar2 - a * a);
404
- let p = dv.$multiply(a / dr).add(_pts[0]);
405
- return new Group(new Pt(p.x + h * dv.y / dr, p.y - h * dv.x / dr), new Pt(p.x - h * dv.y / dr, p.y + h * dv.x / dr));
406
- }
407
- }
408
- static intersectRect2D(circle, rect) {
409
- let _pts = Util.iterToArray(circle);
410
- let _rect = Util.iterToArray(rect);
411
- let sides = Rectangle.sides(_rect);
412
- let g = [];
413
- for (let i = 0, len = sides.length; i < len; i++) {
414
- let ps = Circle.intersectLine2D(_pts, sides[i]);
415
- if (ps.length > 0)
416
- g.push(ps);
417
- }
418
- return Util.flatten(g);
419
- }
420
- static toRect(circle, within = false) {
421
- let _pts = Util.iterToArray(circle);
422
- let r = _pts[1][0];
423
- if (within) {
424
- let half = Math.sqrt(r * r) / 2;
425
- return new Group(_pts[0].$subtract(half), _pts[0].$add(half));
426
- }
427
- else {
428
- return new Group(_pts[0].$subtract(r), _pts[0].$add(r));
429
- }
430
- }
431
- static toTriangle(circle, within = true) {
432
- let _pts = Util.iterToArray(circle);
433
- if (within) {
434
- let ang = -Math.PI / 2;
435
- let inc = Math.PI * 2 / 3;
436
- let g = new Group();
437
- for (let i = 0; i < 3; i++) {
438
- g.push(_pts[0].clone().toAngle(ang, _pts[1][0], true));
439
- ang += inc;
440
- }
441
- return g;
442
- }
443
- else {
444
- return Triangle.fromCenter(_pts[0], _pts[1][0]);
445
- }
446
- }
447
- }
448
- export class Triangle {
449
- static fromRect(rect) {
450
- let _rect = Util.iterToArray(rect);
451
- let top = _rect[0].$add(_rect[1]).divide(2);
452
- top.y = _rect[0][1];
453
- let left = _rect[1].clone();
454
- left.x = _rect[0][0];
455
- return new Group(top, _rect[1].clone(), left);
456
- }
457
- static fromCircle(circle) {
458
- return Circle.toTriangle(circle, true);
459
- }
460
- static fromCenter(pt, size) {
461
- return Triangle.fromCircle(Circle.fromCenter(pt, size));
462
- }
463
- static medial(tri) {
464
- let _pts = Util.iterToArray(tri);
465
- if (_pts.length < 3)
466
- return _errorLength(new Group(), 3);
467
- return Polygon.midpoints(_pts, true);
468
- }
469
- static oppositeSide(tri, index) {
470
- let _pts = Util.iterToArray(tri);
471
- if (_pts.length < 3)
472
- return _errorLength(new Group(), 3);
473
- if (index === 0) {
474
- return Group.fromPtArray([_pts[1], _pts[2]]);
475
- }
476
- else if (index === 1) {
477
- return Group.fromPtArray([_pts[0], _pts[2]]);
478
- }
479
- else {
480
- return Group.fromPtArray([_pts[0], _pts[1]]);
481
- }
482
- }
483
- static altitude(tri, index) {
484
- let _pts = Util.iterToArray(tri);
485
- let opp = Triangle.oppositeSide(_pts, index);
486
- if (opp.length > 1) {
487
- return new Group(_pts[index], Line.perpendicularFromPt(opp, _pts[index]));
488
- }
489
- else {
490
- return new Group();
491
- }
492
- }
493
- static orthocenter(tri) {
494
- let _pts = Util.iterToArray(tri);
495
- if (_pts.length < 3)
496
- return _errorLength(undefined, 3);
497
- let a = Triangle.altitude(_pts, 0);
498
- let b = Triangle.altitude(_pts, 1);
499
- return Line.intersectRay2D(a, b);
500
- }
501
- static incenter(tri) {
502
- let _pts = Util.iterToArray(tri);
503
- if (_pts.length < 3)
504
- return _errorLength(undefined, 3);
505
- let a = Polygon.bisector(_pts, 0).add(_pts[0]);
506
- let b = Polygon.bisector(_pts, 1).add(_pts[1]);
507
- return Line.intersectRay2D(new Group(_pts[0], a), new Group(_pts[1], b));
508
- }
509
- static incircle(tri, center) {
510
- let _pts = Util.iterToArray(tri);
511
- let c = (center) ? center : Triangle.incenter(_pts);
512
- let area = Polygon.area(_pts);
513
- let perim = Polygon.perimeter(_pts, true);
514
- let r = 2 * area / perim.total;
515
- return Circle.fromCenter(c, r);
516
- }
517
- static circumcenter(tri) {
518
- let _pts = Util.iterToArray(tri);
519
- let md = Triangle.medial(_pts);
520
- let a = [md[0], Geom.perpendicular(_pts[0].$subtract(md[0])).p1.$add(md[0])];
521
- let b = [md[1], Geom.perpendicular(_pts[1].$subtract(md[1])).p1.$add(md[1])];
522
- return Line.intersectRay2D(a, b);
523
- }
524
- static circumcircle(tri, center) {
525
- let _pts = Util.iterToArray(tri);
526
- let c = (center) ? center : Triangle.circumcenter(_pts);
527
- let r = _pts[0].$subtract(c).magnitude();
528
- return Circle.fromCenter(c, r);
529
- }
530
- }
531
- export class Polygon {
532
- static centroid(pts) {
533
- return Geom.centroid(pts);
534
- }
535
- static rectangle(center, widthOrSize, height) {
536
- return Rectangle.corners(Rectangle.fromCenter(center, widthOrSize, height));
537
- }
538
- static fromCenter(center, radius, sides) {
539
- let g = new Group();
540
- for (let i = 0; i < sides; i++) {
541
- let ang = Math.PI * 2 * i / sides;
542
- g.push(new Pt(Math.cos(ang) * radius, Math.sin(ang) * radius).add(center));
543
- }
544
- return g;
545
- }
546
- static lineAt(pts, index) {
547
- let _pts = Util.iterToArray(pts);
548
- if (index < 0 || index >= _pts.length)
549
- throw new Error("index out of the Polygon's range");
550
- return new Group(_pts[index], (index === _pts.length - 1) ? _pts[0] : _pts[index + 1]);
551
- }
552
- static lines(poly, closePath = true) {
553
- let _pts = Util.iterToArray(poly);
554
- if (_pts.length < 2)
555
- return _errorLength(new Group(), 2);
556
- let sp = Util.split(_pts, 2, 1);
557
- if (closePath)
558
- sp.push(new Group(_pts[_pts.length - 1], _pts[0]));
559
- return sp.map((g) => g);
560
- }
561
- static midpoints(poly, closePath = false, t = 0.5) {
562
- let sides = Polygon.lines(poly, closePath);
563
- let mids = sides.map((s) => Geom.interpolate(s[0], s[1], t));
564
- return mids;
565
- }
566
- static adjacentSides(poly, index, closePath = false) {
567
- let _pts = Util.iterToArray(poly);
568
- if (_pts.length < 2)
569
- return _errorLength(new Group(), 2);
570
- if (index < 0 || index >= _pts.length)
571
- return _errorOutofBound(new Group(), index);
572
- let gs = [];
573
- let left = index - 1;
574
- if (closePath && left < 0)
575
- left = _pts.length - 1;
576
- if (left >= 0)
577
- gs.push(new Group(_pts[index], _pts[left]));
578
- let right = index + 1;
579
- if (closePath && right > _pts.length - 1)
580
- right = 0;
581
- if (right <= _pts.length - 1)
582
- gs.push(new Group(_pts[index], _pts[right]));
583
- return gs;
584
- }
585
- static bisector(poly, index) {
586
- let sides = Polygon.adjacentSides(poly, index, true);
587
- if (sides.length >= 2) {
588
- let a = sides[0][1].$subtract(sides[0][0]).unit();
589
- let b = sides[1][1].$subtract(sides[1][0]).unit();
590
- return a.add(b).divide(2);
591
- }
592
- else {
593
- return undefined;
594
- }
595
- }
596
- static perimeter(poly, closePath = false) {
597
- let lines = Polygon.lines(poly, closePath);
598
- let mag = 0;
599
- let p = Pt.make(lines.length, 0);
600
- for (let i = 0, len = lines.length; i < len; i++) {
601
- let m = Line.magnitude(lines[i]);
602
- mag += m;
603
- p[i] = m;
604
- }
605
- return {
606
- total: mag,
607
- segments: p
608
- };
609
- }
610
- static area(pts) {
611
- let _pts = Util.iterToArray(pts);
612
- if (_pts.length < 3)
613
- return _errorLength(new Group(), 3);
614
- let det = (a, b) => a[0] * b[1] - a[1] * b[0];
615
- let area = 0;
616
- for (let i = 0, len = _pts.length; i < len; i++) {
617
- if (i < _pts.length - 1) {
618
- area += det(_pts[i], _pts[i + 1]);
619
- }
620
- else {
621
- area += det(_pts[i], _pts[0]);
622
- }
623
- }
624
- return Math.abs(area / 2);
625
- }
626
- static convexHull(pts, sorted = false) {
627
- let _pts = Util.iterToArray(pts);
628
- if (_pts.length < 3)
629
- return _errorLength(new Group(), 3);
630
- if (!sorted) {
631
- _pts = _pts.slice();
632
- _pts.sort((a, b) => a[0] - b[0]);
633
- }
634
- let left = (a, b, c) => {
635
- return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]) > 0;
636
- };
637
- let dq = [];
638
- let bot = _pts.length - 2;
639
- let top = bot + 3;
640
- dq[bot] = _pts[2];
641
- dq[top] = _pts[2];
642
- if (left(_pts[0], _pts[1], _pts[2])) {
643
- dq[bot + 1] = _pts[0];
644
- dq[bot + 2] = _pts[1];
645
- }
646
- else {
647
- dq[bot + 1] = _pts[1];
648
- dq[bot + 2] = _pts[0];
649
- }
650
- for (let i = 3, len = _pts.length; i < len; i++) {
651
- let pt = _pts[i];
652
- if (left(dq[bot], dq[bot + 1], pt) && left(dq[top - 1], dq[top], pt)) {
653
- continue;
654
- }
655
- while (!left(dq[bot], dq[bot + 1], pt)) {
656
- bot += 1;
657
- }
658
- bot -= 1;
659
- dq[bot] = pt;
660
- while (!left(dq[top - 1], dq[top], pt)) {
661
- top -= 1;
662
- }
663
- top += 1;
664
- dq[top] = pt;
665
- }
666
- let hull = new Group();
667
- for (let h = 0; h < (top - bot); h++) {
668
- hull.push(dq[bot + h]);
669
- }
670
- return hull;
671
- }
672
- static network(poly, originIndex = 0) {
673
- let _pts = Util.iterToArray(poly);
674
- let g = [];
675
- for (let i = 0, len = _pts.length; i < len; i++) {
676
- if (i != originIndex)
677
- g.push(new Group(_pts[originIndex], _pts[i]));
678
- }
679
- return g;
680
- }
681
- static nearestPt(poly, pt) {
682
- let _near = Number.MAX_VALUE;
683
- let _item = -1;
684
- let i = 0;
685
- for (let p of poly) {
686
- let d = p.$subtract(pt).magnitudeSq();
687
- if (d < _near) {
688
- _near = d;
689
- _item = i;
690
- }
691
- i++;
692
- }
693
- return _item;
694
- }
695
- static projectAxis(poly, unitAxis) {
696
- let _poly = Util.iterToArray(poly);
697
- let dot = unitAxis.dot(_poly[0]);
698
- let d = new Pt(dot, dot);
699
- for (let n = 1, len = _poly.length; n < len; n++) {
700
- dot = unitAxis.dot(_poly[n]);
701
- d = new Pt(Math.min(dot, d[0]), Math.max(dot, d[1]));
702
- }
703
- return d;
704
- }
705
- static _axisOverlap(poly1, poly2, unitAxis) {
706
- let pa = Polygon.projectAxis(poly1, unitAxis);
707
- let pb = Polygon.projectAxis(poly2, unitAxis);
708
- return (pa[0] < pb[0]) ? pb[0] - pa[1] : pa[0] - pb[1];
709
- }
710
- static hasIntersectPoint(poly, pt) {
711
- let _poly = Util.iterToArray(poly);
712
- let c = false;
713
- for (let i = 0, len = _poly.length; i < len; i++) {
714
- let ln = Polygon.lineAt(_poly, i);
715
- if (((ln[0][1] > pt[1]) != (ln[1][1] > pt[1])) &&
716
- (pt[0] < (ln[1][0] - ln[0][0]) * (pt[1] - ln[0][1]) / (ln[1][1] - ln[0][1]) + ln[0][0])) {
717
- c = !c;
718
- }
719
- }
720
- return c;
721
- }
722
- static hasIntersectCircle(poly, circle) {
723
- let _poly = Util.iterToArray(poly);
724
- let _circle = Util.iterToArray(circle);
725
- let info = {
726
- which: -1,
727
- dist: 0,
728
- normal: null,
729
- edge: null,
730
- vertex: null,
731
- };
732
- let c = _circle[0];
733
- let r = _circle[1][0];
734
- let minDist = Number.MAX_SAFE_INTEGER;
735
- for (let i = 0, len = _poly.length; i < len; i++) {
736
- let edge = Polygon.lineAt(_poly, i);
737
- let axis = new Pt(edge[0].y - edge[1].y, edge[1].x - edge[0].x).unit();
738
- let poly2 = new Group(c.$add(axis.$multiply(r)), c.$subtract(axis.$multiply(r)));
739
- let dist = Polygon._axisOverlap(_poly, poly2, axis);
740
- if (dist > 0) {
741
- return null;
742
- }
743
- else if (Math.abs(dist) < minDist) {
744
- let check = Rectangle.withinBound(edge, Line.perpendicularFromPt(edge, c)) || Circle.intersectLine2D(circle, edge).length > 0;
745
- if (check) {
746
- info.edge = edge;
747
- info.normal = axis;
748
- minDist = Math.abs(dist);
749
- info.which = i;
750
- }
751
- }
752
- }
753
- if (!info.edge)
754
- return null;
755
- let dir = c.$subtract(Polygon.centroid(_poly)).dot(info.normal);
756
- if (dir < 0)
757
- info.normal.multiply(-1);
758
- info.dist = minDist;
759
- info.vertex = c;
760
- return info;
761
- }
762
- static hasIntersectPolygon(poly1, poly2) {
763
- let _poly1 = Util.iterToArray(poly1);
764
- let _poly2 = Util.iterToArray(poly2);
765
- let info = {
766
- which: -1,
767
- dist: 0,
768
- normal: new Pt(),
769
- edge: new Group(),
770
- vertex: new Pt()
771
- };
772
- let minDist = Number.MAX_SAFE_INTEGER;
773
- for (let i = 0, plen = (_poly1.length + _poly2.length); i < plen; i++) {
774
- let edge = (i < _poly1.length) ? Polygon.lineAt(_poly1, i) : Polygon.lineAt(_poly2, i - _poly1.length);
775
- let axis = new Pt(edge[0].y - edge[1].y, edge[1].x - edge[0].x).unit();
776
- let dist = Polygon._axisOverlap(_poly1, _poly2, axis);
777
- if (dist > 0) {
778
- return null;
779
- }
780
- else if (Math.abs(dist) < minDist) {
781
- info.edge = edge;
782
- info.normal = axis;
783
- minDist = Math.abs(dist);
784
- info.which = (i < _poly1.length) ? 0 : 1;
785
- }
786
- }
787
- info.dist = minDist;
788
- let b1 = (info.which === 0) ? _poly2 : _poly1;
789
- let b2 = (info.which === 0) ? _poly1 : _poly2;
790
- let c1 = Polygon.centroid(b1);
791
- let c2 = Polygon.centroid(b2);
792
- let dir = c1.$subtract(c2).dot(info.normal);
793
- if (dir < 0)
794
- info.normal.multiply(-1);
795
- let smallest = Number.MAX_SAFE_INTEGER;
796
- for (let i = 0, len = b1.length; i < len; i++) {
797
- let d = info.normal.dot(b1[i].$subtract(c2));
798
- if (d < smallest) {
799
- smallest = d;
800
- info.vertex = b1[i];
801
- }
802
- }
803
- return info;
804
- }
805
- static intersectPolygon2D(poly1, poly2) {
806
- let _poly1 = Util.iterToArray(poly1);
807
- let _poly2 = Util.iterToArray(poly2);
808
- let lp = Polygon.lines(_poly1);
809
- let g = [];
810
- for (let i = 0, len = lp.length; i < len; i++) {
811
- let ins = Line.intersectPolygon2D(lp[i], _poly2, false);
812
- if (ins)
813
- g.push(ins);
814
- }
815
- return Util.flatten(g, true);
816
- }
817
- static toRects(polys) {
818
- let boxes = [];
819
- for (let g of polys) {
820
- boxes.push(Geom.boundingBox(g));
821
- }
822
- let merged = Util.flatten(boxes, false);
823
- boxes.unshift(Geom.boundingBox(merged));
824
- return boxes;
825
- }
826
- }
827
- export class Curve {
828
- static getSteps(steps) {
829
- let ts = new Group();
830
- for (let i = 0; i <= steps; i++) {
831
- let t = i / steps;
832
- ts.push(new Pt(t * t * t, t * t, t, 1));
833
- }
834
- return ts;
835
- }
836
- static controlPoints(pts, index = 0, copyStart = false) {
837
- let _pts = Util.iterToArray(pts);
838
- if (index > _pts.length - 1)
839
- return new Group();
840
- let _index = (i) => (i < _pts.length - 1) ? i : _pts.length - 1;
841
- let p0 = _pts[index];
842
- index = (copyStart) ? index : index + 1;
843
- return new Group(p0, _pts[_index(index++)], _pts[_index(index++)], _pts[_index(index++)]);
844
- }
845
- static _calcPt(ctrls, params) {
846
- let x = ctrls.reduce((a, c, i) => a + c.x * params[i], 0);
847
- let y = ctrls.reduce((a, c, i) => a + c.y * params[i], 0);
848
- if (ctrls[0].length > 2) {
849
- let z = ctrls.reduce((a, c, i) => a + c.z * params[i], 0);
850
- return new Pt(x, y, z);
851
- }
852
- return new Pt(x, y);
853
- }
854
- static catmullRom(pts, steps = 10) {
855
- let _pts = Util.iterToArray(pts);
856
- if (_pts.length < 2)
857
- return new Group();
858
- let ps = new Group();
859
- let ts = Curve.getSteps(steps);
860
- let c = Curve.controlPoints(_pts, 0, true);
861
- for (let i = 0; i <= steps; i++) {
862
- ps.push(Curve.catmullRomStep(ts[i], c));
863
- }
864
- let k = 0;
865
- while (k < _pts.length - 2) {
866
- let cp = Curve.controlPoints(_pts, k);
867
- if (cp.length > 0) {
868
- for (let i = 0; i <= steps; i++) {
869
- ps.push(Curve.catmullRomStep(ts[i], cp));
870
- }
871
- k++;
872
- }
873
- }
874
- return ps;
875
- }
876
- static catmullRomStep(step, ctrls) {
877
- let m = new Group(new Pt(-0.5, 1, -0.5, 0), new Pt(1.5, -2.5, 0, 1), new Pt(-1.5, 2, 0.5, 0), new Pt(0.5, -0.5, 0, 0));
878
- return Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
879
- }
880
- static cardinal(pts, steps = 10, tension = 0.5) {
881
- let _pts = Util.iterToArray(pts);
882
- if (_pts.length < 2)
883
- return new Group();
884
- let ps = new Group();
885
- let ts = Curve.getSteps(steps);
886
- let c = Curve.controlPoints(_pts, 0, true);
887
- for (let i = 0; i <= steps; i++) {
888
- ps.push(Curve.cardinalStep(ts[i], c, tension));
889
- }
890
- let k = 0;
891
- while (k < _pts.length - 2) {
892
- let cp = Curve.controlPoints(_pts, k);
893
- if (cp.length > 0) {
894
- for (let i = 0; i <= steps; i++) {
895
- ps.push(Curve.cardinalStep(ts[i], cp, tension));
896
- }
897
- k++;
898
- }
899
- }
900
- return ps;
901
- }
902
- static cardinalStep(step, ctrls, tension = 0.5) {
903
- let m = new Group(new Pt(-1, 2, -1, 0), new Pt(-1, 1, 0, 0), new Pt(1, -2, 1, 0), new Pt(1, -1, 0, 0));
904
- let h = Mat.multiply([step], m, true)[0].multiply(tension);
905
- let h2 = (2 * step[0] - 3 * step[1] + 1);
906
- let h3 = -2 * step[0] + 3 * step[1];
907
- let pt = Curve._calcPt(ctrls, h);
908
- pt.x += h2 * ctrls[1].x + h3 * ctrls[2].x;
909
- pt.y += h2 * ctrls[1].y + h3 * ctrls[2].y;
910
- if (pt.length > 2)
911
- pt.z += h2 * ctrls[1].z + h3 * ctrls[2].z;
912
- return pt;
913
- }
914
- static bezier(pts, steps = 10) {
915
- let _pts = Util.iterToArray(pts);
916
- if (_pts.length < 4)
917
- return new Group();
918
- let ps = new Group();
919
- let ts = Curve.getSteps(steps);
920
- let k = 0;
921
- while (k < _pts.length - 3) {
922
- let c = Curve.controlPoints(_pts, k);
923
- if (c.length > 0) {
924
- for (let i = 0; i <= steps; i++) {
925
- ps.push(Curve.bezierStep(ts[i], c));
926
- }
927
- k += 3;
928
- }
929
- }
930
- return ps;
931
- }
932
- static bezierStep(step, ctrls) {
933
- let m = new Group(new Pt(-1, 3, -3, 1), new Pt(3, -6, 3, 0), new Pt(-3, 3, 0, 0), new Pt(1, 0, 0, 0));
934
- return Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
935
- }
936
- static bspline(pts, steps = 10, tension = 1) {
937
- let _pts = Util.iterToArray(pts);
938
- if (_pts.length < 2)
939
- return new Group();
940
- let ps = new Group();
941
- let ts = Curve.getSteps(steps);
942
- let k = 0;
943
- while (k < _pts.length - 3) {
944
- let c = Curve.controlPoints(_pts, k);
945
- if (c.length > 0) {
946
- if (tension !== 1) {
947
- for (let i = 0; i <= steps; i++) {
948
- ps.push(Curve.bsplineTensionStep(ts[i], c, tension));
949
- }
950
- }
951
- else {
952
- for (let i = 0; i <= steps; i++) {
953
- ps.push(Curve.bsplineStep(ts[i], c));
954
- }
955
- }
956
- k++;
957
- }
958
- }
959
- return ps;
960
- }
961
- static bsplineStep(step, ctrls) {
962
- let m = new Group(new Pt(-0.16666666666666666, 0.5, -0.5, 0.16666666666666666), new Pt(0.5, -1, 0, 0.6666666666666666), new Pt(-0.5, 0.5, 0.5, 0.16666666666666666), new Pt(0.16666666666666666, 0, 0, 0));
963
- return Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
964
- }
965
- static bsplineTensionStep(step, ctrls, tension = 1) {
966
- let m = new Group(new Pt(-0.16666666666666666, 0.5, -0.5, 0.16666666666666666), new Pt(-1.5, 2, 0, -0.3333333333333333), new Pt(1.5, -2.5, 0.5, 0.16666666666666666), new Pt(0.16666666666666666, 0, 0, 0));
967
- let h = Mat.multiply([step], m, true)[0].multiply(tension);
968
- let h2 = (2 * step[0] - 3 * step[1] + 1);
969
- let h3 = -2 * step[0] + 3 * step[1];
970
- let pt = Curve._calcPt(ctrls, h);
971
- pt.x += h2 * ctrls[1].x + h3 * ctrls[2].x;
972
- pt.y += h2 * ctrls[1].y + h3 * ctrls[2].y;
973
- if (pt.length > 2)
974
- pt.z += h2 * ctrls[1].z + h3 * ctrls[2].z;
975
- return pt;
976
- }
977
- }
978
- //# sourceMappingURL=Op.js.map