geometry.test.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import type { GlobalPoint, LineSegment, Polygon, Radians } from "../../math";
  2. import {
  3. point,
  4. lineSegment,
  5. polygon,
  6. pointOnLineSegment,
  7. pointOnPolygon,
  8. polygonIncludesPoint,
  9. segmentsIntersectAt,
  10. } from "../../math";
  11. import { pointInEllipse, pointOnEllipse, type Ellipse } from "./shape";
  12. describe("point and line", () => {
  13. // const l: Line<GlobalPoint> = line(point(1, 0), point(1, 2));
  14. // it("point on left or right of line", () => {
  15. // expect(pointLeftofLine(point(0, 1), l)).toBe(true);
  16. // expect(pointLeftofLine(point(1, 1), l)).toBe(false);
  17. // expect(pointLeftofLine(point(2, 1), l)).toBe(false);
  18. // expect(pointRightofLine(point(0, 1), l)).toBe(false);
  19. // expect(pointRightofLine(point(1, 1), l)).toBe(false);
  20. // expect(pointRightofLine(point(2, 1), l)).toBe(true);
  21. // });
  22. const s: LineSegment<GlobalPoint> = lineSegment(point(1, 0), point(1, 2));
  23. it("point on the line", () => {
  24. expect(pointOnLineSegment(point(0, 1), s)).toBe(false);
  25. expect(pointOnLineSegment(point(1, 1), s, 0)).toBe(true);
  26. expect(pointOnLineSegment(point(2, 1), s)).toBe(false);
  27. });
  28. });
  29. describe("point and polygon", () => {
  30. const poly: Polygon<GlobalPoint> = polygon(
  31. point(10, 10),
  32. point(50, 10),
  33. point(50, 50),
  34. point(10, 50),
  35. );
  36. it("point on polygon", () => {
  37. expect(pointOnPolygon(point(30, 10), poly)).toBe(true);
  38. expect(pointOnPolygon(point(50, 30), poly)).toBe(true);
  39. expect(pointOnPolygon(point(30, 50), poly)).toBe(true);
  40. expect(pointOnPolygon(point(10, 30), poly)).toBe(true);
  41. expect(pointOnPolygon(point(30, 30), poly)).toBe(false);
  42. expect(pointOnPolygon(point(30, 70), poly)).toBe(false);
  43. });
  44. it("point in polygon", () => {
  45. const poly: Polygon<GlobalPoint> = polygon(
  46. point(0, 0),
  47. point(2, 0),
  48. point(2, 2),
  49. point(0, 2),
  50. );
  51. expect(polygonIncludesPoint(point(1, 1), poly)).toBe(true);
  52. expect(polygonIncludesPoint(point(3, 3), poly)).toBe(false);
  53. });
  54. });
  55. describe("point and ellipse", () => {
  56. const ellipse: Ellipse<GlobalPoint> = {
  57. center: point(0, 0),
  58. angle: 0 as Radians,
  59. halfWidth: 2,
  60. halfHeight: 1,
  61. };
  62. it("point on ellipse", () => {
  63. [point(0, 1), point(0, -1), point(2, 0), point(-2, 0)].forEach((p) => {
  64. expect(pointOnEllipse(p, ellipse)).toBe(true);
  65. });
  66. expect(pointOnEllipse(point(-1.4, 0.7), ellipse, 0.1)).toBe(true);
  67. expect(pointOnEllipse(point(-1.4, 0.71), ellipse, 0.01)).toBe(true);
  68. expect(pointOnEllipse(point(1.4, 0.7), ellipse, 0.1)).toBe(true);
  69. expect(pointOnEllipse(point(1.4, 0.71), ellipse, 0.01)).toBe(true);
  70. expect(pointOnEllipse(point(1, -0.86), ellipse, 0.1)).toBe(true);
  71. expect(pointOnEllipse(point(1, -0.86), ellipse, 0.01)).toBe(true);
  72. expect(pointOnEllipse(point(-1, -0.86), ellipse, 0.1)).toBe(true);
  73. expect(pointOnEllipse(point(-1, -0.86), ellipse, 0.01)).toBe(true);
  74. expect(pointOnEllipse(point(-1, 0.8), ellipse)).toBe(false);
  75. expect(pointOnEllipse(point(1, -0.8), ellipse)).toBe(false);
  76. });
  77. it("point in ellipse", () => {
  78. [point(0, 1), point(0, -1), point(2, 0), point(-2, 0)].forEach((p) => {
  79. expect(pointInEllipse(p, ellipse)).toBe(true);
  80. });
  81. expect(pointInEllipse(point(-1, 0.8), ellipse)).toBe(true);
  82. expect(pointInEllipse(point(1, -0.8), ellipse)).toBe(true);
  83. expect(pointInEllipse(point(-1, 1), ellipse)).toBe(false);
  84. expect(pointInEllipse(point(-1.4, 0.8), ellipse)).toBe(false);
  85. });
  86. });
  87. describe("line and line", () => {
  88. const lineA: LineSegment<GlobalPoint> = lineSegment(point(1, 4), point(3, 4));
  89. const lineB: LineSegment<GlobalPoint> = lineSegment(point(2, 1), point(2, 7));
  90. const lineC: LineSegment<GlobalPoint> = lineSegment(point(1, 8), point(3, 8));
  91. const lineD: LineSegment<GlobalPoint> = lineSegment(point(1, 8), point(3, 8));
  92. const lineE: LineSegment<GlobalPoint> = lineSegment(point(1, 9), point(3, 9));
  93. const lineF: LineSegment<GlobalPoint> = lineSegment(point(1, 2), point(3, 4));
  94. const lineG: LineSegment<GlobalPoint> = lineSegment(point(0, 1), point(2, 3));
  95. it("intersection", () => {
  96. expect(segmentsIntersectAt(lineA, lineB)).toEqual([2, 4]);
  97. expect(segmentsIntersectAt(lineA, lineC)).toBe(null);
  98. expect(segmentsIntersectAt(lineB, lineC)).toBe(null);
  99. expect(segmentsIntersectAt(lineC, lineD)).toBe(null); // Line overlapping line is not intersection!
  100. expect(segmentsIntersectAt(lineE, lineD)).toBe(null);
  101. expect(segmentsIntersectAt(lineF, lineG)).toBe(null);
  102. });
  103. });