aboutsummaryrefslogtreecommitdiffstats
path: root/packages/math/ellipse.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/math/ellipse.test.ts')
-rw-r--r--packages/math/ellipse.test.ts126
1 files changed, 126 insertions, 0 deletions
diff --git a/packages/math/ellipse.test.ts b/packages/math/ellipse.test.ts
new file mode 100644
index 0000000..507cc5a
--- /dev/null
+++ b/packages/math/ellipse.test.ts
@@ -0,0 +1,126 @@
+import {
+ ellipse,
+ ellipseSegmentInterceptPoints,
+ ellipseIncludesPoint,
+ ellipseTouchesPoint,
+ ellipseLineIntersectionPoints,
+} from "./ellipse";
+import { line } from "./line";
+import { pointFrom } from "./point";
+import { lineSegment } from "./segment";
+import type { Ellipse, GlobalPoint } from "./types";
+
+describe("point and ellipse", () => {
+ it("point on ellipse", () => {
+ const target: Ellipse<GlobalPoint> = ellipse(pointFrom(1, 2), 2, 1);
+ [
+ pointFrom(1, 3),
+ pointFrom(1, 1),
+ pointFrom(3, 2),
+ pointFrom(-1, 2),
+ ].forEach((p) => {
+ expect(ellipseTouchesPoint(p, target)).toBe(true);
+ });
+ expect(ellipseTouchesPoint(pointFrom(-0.4, 2.7), target, 0.1)).toBe(true);
+ expect(ellipseTouchesPoint(pointFrom(-0.4, 2.71), target, 0.01)).toBe(true);
+
+ expect(ellipseTouchesPoint(pointFrom(2.4, 2.7), target, 0.1)).toBe(true);
+ expect(ellipseTouchesPoint(pointFrom(2.4, 2.71), target, 0.01)).toBe(true);
+
+ expect(ellipseTouchesPoint(pointFrom(2, 1.14), target, 0.1)).toBe(true);
+ expect(ellipseTouchesPoint(pointFrom(2, 1.14), target, 0.01)).toBe(true);
+
+ expect(ellipseTouchesPoint(pointFrom(0, 1.14), target, 0.1)).toBe(true);
+ expect(ellipseTouchesPoint(pointFrom(0, 1.14), target, 0.01)).toBe(true);
+
+ expect(ellipseTouchesPoint(pointFrom(0, 2.8), target)).toBe(false);
+ expect(ellipseTouchesPoint(pointFrom(2, 1.2), target)).toBe(false);
+ });
+
+ it("point in ellipse", () => {
+ const target: Ellipse<GlobalPoint> = ellipse(pointFrom(0, 0), 2, 1);
+ [
+ pointFrom(0, 1),
+ pointFrom(0, -1),
+ pointFrom(2, 0),
+ pointFrom(-2, 0),
+ ].forEach((p) => {
+ expect(ellipseIncludesPoint(p, target)).toBe(true);
+ });
+
+ expect(ellipseIncludesPoint(pointFrom(-1, 0.8), target)).toBe(true);
+ expect(ellipseIncludesPoint(pointFrom(1, -0.8), target)).toBe(true);
+
+ // Point on outline
+ expect(ellipseIncludesPoint(pointFrom(2, 0), target)).toBe(true);
+
+ expect(ellipseIncludesPoint(pointFrom(-1, 1), target)).toBe(false);
+ expect(ellipseIncludesPoint(pointFrom(-1.4, 0.8), target)).toBe(false);
+ });
+});
+
+describe("segment and ellipse", () => {
+ it("detects outside segment", () => {
+ const e = ellipse(pointFrom(0, 0), 2, 2);
+
+ expect(
+ ellipseSegmentInterceptPoints(
+ e,
+ lineSegment<GlobalPoint>(pointFrom(-100, 0), pointFrom(-10, 0)),
+ ),
+ ).toEqual([]);
+ expect(
+ ellipseSegmentInterceptPoints(
+ e,
+ lineSegment<GlobalPoint>(pointFrom(-10, 0), pointFrom(10, 0)),
+ ),
+ ).toEqual([pointFrom(-2, 0), pointFrom(2, 0)]);
+ expect(
+ ellipseSegmentInterceptPoints(
+ e,
+ lineSegment<GlobalPoint>(pointFrom(-10, -2), pointFrom(10, -2)),
+ ),
+ ).toEqual([pointFrom(0, -2)]);
+ expect(
+ ellipseSegmentInterceptPoints(
+ e,
+ lineSegment<GlobalPoint>(pointFrom(0, -1), pointFrom(0, 1)),
+ ),
+ ).toEqual([]);
+ });
+});
+
+describe("line and ellipse", () => {
+ const e = ellipse(pointFrom(0, 0), 2, 2);
+
+ it("detects outside line", () => {
+ expect(
+ ellipseLineIntersectionPoints(
+ e,
+ line<GlobalPoint>(pointFrom(-10, -10), pointFrom(10, -10)),
+ ),
+ ).toEqual([]);
+ });
+ it("detects line intersecting ellipse", () => {
+ expect(
+ ellipseLineIntersectionPoints(
+ e,
+ line<GlobalPoint>(pointFrom(0, -1), pointFrom(0, 1)),
+ ),
+ ).toEqual([pointFrom(0, 2), pointFrom(0, -2)]);
+ expect(
+ ellipseLineIntersectionPoints(
+ e,
+ line<GlobalPoint>(pointFrom(-100, 0), pointFrom(-10, 0)),
+ ).map(([x, y]) => pointFrom(Math.round(x), Math.round(y))),
+ ).toEqual([pointFrom(2, 0), pointFrom(-2, 0)]);
+ });
+ it("detects line touching ellipse", () => {
+ expect(
+ ellipseLineIntersectionPoints(
+ e,
+ line<GlobalPoint>(pointFrom(-2, -2), pointFrom(2, -2)),
+ ),
+ ).toEqual([pointFrom(0, -2)]);
+ });
+});