@js-draw/math 1.17.0 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. package/dist/cjs/Mat33.js +6 -1
  2. package/dist/cjs/Vec3.d.ts +2 -1
  3. package/dist/cjs/Vec3.js +5 -7
  4. package/dist/cjs/lib.d.ts +2 -1
  5. package/dist/cjs/lib.js +5 -1
  6. package/dist/cjs/shapes/BezierJSWrapper.d.ts +4 -0
  7. package/dist/cjs/shapes/BezierJSWrapper.js +35 -0
  8. package/dist/cjs/shapes/LineSegment2.d.ts +11 -0
  9. package/dist/cjs/shapes/LineSegment2.js +26 -1
  10. package/dist/cjs/shapes/Parameterized2DShape.d.ts +6 -1
  11. package/dist/cjs/shapes/Parameterized2DShape.js +6 -1
  12. package/dist/cjs/shapes/Path.d.ts +96 -12
  13. package/dist/cjs/shapes/Path.js +338 -15
  14. package/dist/cjs/shapes/QuadraticBezier.d.ts +2 -3
  15. package/dist/cjs/shapes/QuadraticBezier.js +2 -3
  16. package/dist/cjs/shapes/Rect2.d.ts +6 -1
  17. package/dist/cjs/shapes/Rect2.js +5 -1
  18. package/dist/cjs/utils/convexHull2Of.d.ts +9 -0
  19. package/dist/cjs/utils/convexHull2Of.js +61 -0
  20. package/dist/cjs/utils/convexHull2Of.test.d.ts +1 -0
  21. package/dist/mjs/Mat33.mjs +6 -1
  22. package/dist/mjs/Vec3.d.ts +2 -1
  23. package/dist/mjs/Vec3.mjs +5 -7
  24. package/dist/mjs/lib.d.ts +2 -1
  25. package/dist/mjs/lib.mjs +2 -1
  26. package/dist/mjs/shapes/BezierJSWrapper.d.ts +4 -0
  27. package/dist/mjs/shapes/BezierJSWrapper.mjs +35 -0
  28. package/dist/mjs/shapes/LineSegment2.d.ts +11 -0
  29. package/dist/mjs/shapes/LineSegment2.mjs +26 -1
  30. package/dist/mjs/shapes/Parameterized2DShape.d.ts +6 -1
  31. package/dist/mjs/shapes/Parameterized2DShape.mjs +6 -1
  32. package/dist/mjs/shapes/Path.d.ts +96 -12
  33. package/dist/mjs/shapes/Path.mjs +335 -14
  34. package/dist/mjs/shapes/QuadraticBezier.d.ts +2 -3
  35. package/dist/mjs/shapes/QuadraticBezier.mjs +2 -3
  36. package/dist/mjs/shapes/Rect2.d.ts +6 -1
  37. package/dist/mjs/shapes/Rect2.mjs +5 -1
  38. package/dist/mjs/utils/convexHull2Of.d.ts +9 -0
  39. package/dist/mjs/utils/convexHull2Of.mjs +59 -0
  40. package/dist/mjs/utils/convexHull2Of.test.d.ts +1 -0
  41. package/package.json +2 -2
  42. package/src/Mat33.ts +8 -2
  43. package/src/Vec3.test.ts +16 -0
  44. package/src/Vec3.ts +7 -8
  45. package/src/lib.ts +3 -0
  46. package/src/shapes/BezierJSWrapper.ts +41 -0
  47. package/src/shapes/LineSegment2.test.ts +26 -0
  48. package/src/shapes/LineSegment2.ts +31 -1
  49. package/src/shapes/Parameterized2DShape.ts +6 -1
  50. package/src/shapes/Path.test.ts +173 -5
  51. package/src/shapes/Path.ts +390 -18
  52. package/src/shapes/QuadraticBezier.test.ts +21 -0
  53. package/src/shapes/QuadraticBezier.ts +2 -3
  54. package/src/shapes/Rect2.ts +6 -2
  55. package/src/utils/convexHull2Of.test.ts +43 -0
  56. package/src/utils/convexHull2Of.ts +71 -0
@@ -0,0 +1,71 @@
1
+ import { Point2, Vec2 } from '../Vec2';
2
+
3
+ /**
4
+ * Implements Gift Wrapping, in $O(nh)$. This algorithm is not the most efficient in the worst case.
5
+ *
6
+ * See https://en.wikipedia.org/wiki/Gift_wrapping_algorithm
7
+ * and https://www.cs.jhu.edu/~misha/Spring16/06.pdf
8
+ */
9
+ const convexHull2Of = (points: Point2[]) => {
10
+ if (points.length === 0) {
11
+ return [];
12
+ }
13
+
14
+ // 1. Start with a vertex on the hull
15
+ const lowestPoint = points.reduce(
16
+ (lowest, current) => current.y < lowest.y ? current : lowest,
17
+ points[0]
18
+ );
19
+ const vertices = [ lowestPoint ];
20
+ let toProcess = [...points.filter(p => !p.eq(lowestPoint))];
21
+ let lastBaseDirection = Vec2.of(-1, 0);
22
+
23
+ // 2. Find the point with greatest angle from the vertex:
24
+ //
25
+ // . . .
26
+ // . . / <- Notice that **all** other points are to the
27
+ // / **left** of the vector from the current
28
+ // ./ vertex to the new point.
29
+ while (toProcess.length > 0) {
30
+ const lastVertex = vertices[vertices.length - 1];
31
+
32
+ let smallestDotProductSoFar: number = lastBaseDirection.dot(lowestPoint.minus(lastVertex).normalizedOrZero());
33
+ let furthestPointSoFar = lowestPoint;
34
+ for (const point of toProcess) {
35
+ // Maximizing the angle is the same as minimizing the dot product:
36
+ // point.minus(lastVertex)
37
+ // ^
38
+ // /
39
+ // /
40
+ // ϑ /
41
+ // <-----. lastBaseDirection
42
+ const currentDotProduct = lastBaseDirection.dot(point.minus(lastVertex).normalizedOrZero());
43
+
44
+ if (currentDotProduct <= smallestDotProductSoFar) {
45
+ furthestPointSoFar = point;
46
+ smallestDotProductSoFar = currentDotProduct;
47
+ }
48
+ }
49
+ toProcess = toProcess.filter(p => !p.eq(furthestPointSoFar));
50
+
51
+ const newBaseDirection = furthestPointSoFar.minus(lastVertex).normalized();
52
+
53
+ // If the last vertex is on the same edge as the current, there's no need to include
54
+ // the previous one.
55
+ if (Math.abs(newBaseDirection.dot(lastBaseDirection)) === 1 && vertices.length > 1) {
56
+ vertices.pop();
57
+ }
58
+
59
+ // Stoping condition: We've gone in a full circle.
60
+ if (furthestPointSoFar.eq(lowestPoint)) {
61
+ break;
62
+ } else {
63
+ vertices.push(furthestPointSoFar);
64
+ lastBaseDirection = lastVertex.minus(furthestPointSoFar).normalized();
65
+ }
66
+ }
67
+
68
+ return vertices;
69
+ };
70
+
71
+ export default convexHull2Of;