@js-draw/math 1.17.0 → 1.18.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 (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;