ellipse.test.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import {
  2. ellipse,
  3. ellipseSegmentInterceptPoints,
  4. ellipseIncludesPoint,
  5. ellipseTouchesPoint,
  6. ellipseLineIntersectionPoints,
  7. } from "../src/ellipse";
  8. import { line } from "../src/line";
  9. import { pointFrom } from "../src/point";
  10. import { lineSegment } from "../src/segment";
  11. import type { Ellipse, GlobalPoint } from "../src/types";
  12. describe("point and ellipse", () => {
  13. it("point on ellipse", () => {
  14. const target: Ellipse<GlobalPoint> = ellipse(pointFrom(1, 2), 2, 1);
  15. [
  16. pointFrom(1, 3),
  17. pointFrom(1, 1),
  18. pointFrom(3, 2),
  19. pointFrom(-1, 2),
  20. ].forEach((p) => {
  21. expect(ellipseTouchesPoint(p, target)).toBe(true);
  22. });
  23. expect(ellipseTouchesPoint(pointFrom(-0.4, 2.7), target, 0.1)).toBe(true);
  24. expect(ellipseTouchesPoint(pointFrom(-0.4, 2.71), target, 0.01)).toBe(true);
  25. expect(ellipseTouchesPoint(pointFrom(2.4, 2.7), target, 0.1)).toBe(true);
  26. expect(ellipseTouchesPoint(pointFrom(2.4, 2.71), target, 0.01)).toBe(true);
  27. expect(ellipseTouchesPoint(pointFrom(2, 1.14), target, 0.1)).toBe(true);
  28. expect(ellipseTouchesPoint(pointFrom(2, 1.14), target, 0.01)).toBe(true);
  29. expect(ellipseTouchesPoint(pointFrom(0, 1.14), target, 0.1)).toBe(true);
  30. expect(ellipseTouchesPoint(pointFrom(0, 1.14), target, 0.01)).toBe(true);
  31. expect(ellipseTouchesPoint(pointFrom(0, 2.8), target)).toBe(false);
  32. expect(ellipseTouchesPoint(pointFrom(2, 1.2), target)).toBe(false);
  33. });
  34. it("point in ellipse", () => {
  35. const target: Ellipse<GlobalPoint> = ellipse(pointFrom(0, 0), 2, 1);
  36. [
  37. pointFrom(0, 1),
  38. pointFrom(0, -1),
  39. pointFrom(2, 0),
  40. pointFrom(-2, 0),
  41. ].forEach((p) => {
  42. expect(ellipseIncludesPoint(p, target)).toBe(true);
  43. });
  44. expect(ellipseIncludesPoint(pointFrom(-1, 0.8), target)).toBe(true);
  45. expect(ellipseIncludesPoint(pointFrom(1, -0.8), target)).toBe(true);
  46. // Point on outline
  47. expect(ellipseIncludesPoint(pointFrom(2, 0), target)).toBe(true);
  48. expect(ellipseIncludesPoint(pointFrom(-1, 1), target)).toBe(false);
  49. expect(ellipseIncludesPoint(pointFrom(-1.4, 0.8), target)).toBe(false);
  50. });
  51. });
  52. describe("segment and ellipse", () => {
  53. it("detects outside segment", () => {
  54. const e = ellipse(pointFrom(0, 0), 2, 2);
  55. expect(
  56. ellipseSegmentInterceptPoints(
  57. e,
  58. lineSegment<GlobalPoint>(pointFrom(-100, 0), pointFrom(-10, 0)),
  59. ),
  60. ).toEqual([]);
  61. expect(
  62. ellipseSegmentInterceptPoints(
  63. e,
  64. lineSegment<GlobalPoint>(pointFrom(-10, 0), pointFrom(10, 0)),
  65. ),
  66. ).toEqual([pointFrom(-2, 0), pointFrom(2, 0)]);
  67. expect(
  68. ellipseSegmentInterceptPoints(
  69. e,
  70. lineSegment<GlobalPoint>(pointFrom(-10, -2), pointFrom(10, -2)),
  71. ),
  72. ).toEqual([pointFrom(0, -2)]);
  73. expect(
  74. ellipseSegmentInterceptPoints(
  75. e,
  76. lineSegment<GlobalPoint>(pointFrom(0, -1), pointFrom(0, 1)),
  77. ),
  78. ).toEqual([]);
  79. });
  80. });
  81. describe("line and ellipse", () => {
  82. const e = ellipse(pointFrom(0, 0), 2, 2);
  83. it("detects outside line", () => {
  84. expect(
  85. ellipseLineIntersectionPoints(
  86. e,
  87. line<GlobalPoint>(pointFrom(-10, -10), pointFrom(10, -10)),
  88. ),
  89. ).toEqual([]);
  90. });
  91. it("detects line intersecting ellipse", () => {
  92. expect(
  93. ellipseLineIntersectionPoints(
  94. e,
  95. line<GlobalPoint>(pointFrom(0, -1), pointFrom(0, 1)),
  96. ),
  97. ).toEqual([pointFrom(0, 2), pointFrom(0, -2)]);
  98. expect(
  99. ellipseLineIntersectionPoints(
  100. e,
  101. line<GlobalPoint>(pointFrom(-100, 0), pointFrom(-10, 0)),
  102. ).map(([x, y]) => pointFrom(Math.round(x), Math.round(y))),
  103. ).toEqual([pointFrom(2, 0), pointFrom(-2, 0)]);
  104. });
  105. it("detects line touching ellipse", () => {
  106. expect(
  107. ellipseLineIntersectionPoints(
  108. e,
  109. line<GlobalPoint>(pointFrom(-2, -2), pointFrom(2, -2)),
  110. ),
  111. ).toEqual([pointFrom(0, -2)]);
  112. });
  113. });