Files
AFFiNE-Mirror/blocksuite/affine/block-surface/src/__tests__/math-utils.unit.spec.ts
T
2024-12-20 15:38:06 +08:00

159 lines
3.7 KiB
TypeScript

import {
almostEqual,
assertExists,
isPointOnLineSegment,
type IVec,
lineEllipseIntersects,
lineIntersects,
linePolygonIntersects,
linePolylineIntersects,
pointAlmostEqual,
polygonGetPointTangent,
rotatePoints,
toDegree,
toRadian,
} from '@blocksuite/global/utils';
import { describe, expect, it } from 'vitest';
describe('Line', () => {
it('should intersect', () => {
let rst = lineIntersects([0, 0], [1, 1], [0, 1], [1, 0]);
expect(rst).toBeDefined();
expect(rst).toMatchObject([0.5, 0.5]);
rst = lineIntersects([5, 5], [15, 5], [10, 0], [10, 10]);
expect(rst).toBeDefined();
expect(rst).toMatchObject([10, 5]);
});
it('should not intersect', () => {
const rst = lineIntersects([0, 0], [1, 0], [0, 1], [1, 1]);
expect(rst).toBeNull();
});
it('should intersect when infinity', () => {
const rst = lineIntersects([0, 0], [0, 10], [1, 1], [10, 1], true);
expect(rst).toBeDefined();
expect(rst).toMatchObject([0, 1]);
});
it('lineEllipseIntersects', () => {
const rst = lineEllipseIntersects([0, -5], [0, 5], [0, 0], 1, 1);
const expected: IVec[] = [
[0, 1],
[0, -1],
];
assertExists(rst);
expect(
rst.every((point, index) => pointAlmostEqual(point, expected[index]))
).toBeTruthy();
});
it('lineEllipseIntersects with rotate', () => {
const rst = lineEllipseIntersects(
[0, -5],
[0, 5],
[0, 0],
3,
2,
Math.PI / 2
);
expect(rst).toBeDefined();
if (rst) {
pointAlmostEqual(rst[0], [0, 3]);
pointAlmostEqual(rst[1], [0, -3]);
}
});
it('linePolygonIntersects', () => {
const rst = linePolygonIntersects(
[5, 5],
[15, 5],
[
[0, 0],
[10, 0],
[10, 10],
[0, 10],
]
);
assertExists(rst);
expect(pointAlmostEqual(rst[0], [10, 5])).toBeTruthy();
});
it('linePolylineIntersects', () => {
const rst = linePolylineIntersects(
[5, 5],
[-5, 5],
[
[0, 0],
[10, 0],
[10, 10],
[0, 10],
]
);
expect(rst).toBeNull();
});
it('isPointOnLineSegment', () => {
const line: IVec[] = [
[0, 0],
[1, 0],
];
const point: IVec = [0.5, 0];
expect(isPointOnLineSegment(point, line)).toBe(true);
expect(isPointOnLineSegment([0.01, 0], line)).toBe(true);
expect(isPointOnLineSegment([-0.01, 0], line)).toBe(false);
expect(isPointOnLineSegment([0.5, 0.1], line)).toBe(false);
expect(isPointOnLineSegment([0.5, -0.1], line)).toBe(false);
});
it('rotatePoints', () => {
const points: IVec[] = [
[0, 0],
[1, 0],
[1, 1],
[0, 1],
];
const rst = rotatePoints(points, [0.5, 0.5], 90);
const expected = [
[1, 0],
[1, 1],
[0, 1],
[0, 0],
];
expect(
rst.every((p, i) => {
return (
almostEqual(p[0], expected[i][0]) && almostEqual(p[1], expected[i][1])
);
})
).toBeTruthy();
});
it('polygonGetPointTangent', () => {
const points: IVec[] = [
[0, 0],
[1, 0],
[1, 1],
[0, 1],
];
expect(polygonGetPointTangent(points, [0, 0.5])).toMatchObject([0, -1]);
expect(polygonGetPointTangent(points, [0.5, 0])).toMatchObject([1, 0]);
});
it('toRadian', () => {
expect(toRadian(180)).toBe(Math.PI);
expect(toRadian(90)).toBe(Math.PI / 2);
expect(toRadian(0)).toBe(0);
expect(toRadian(360)).toBe(Math.PI * 2);
});
it('toDegree', () => {
expect(toDegree(Math.PI)).toBe(180);
expect(toDegree(Math.PI / 2)).toBe(90);
expect(toDegree(0)).toBe(0);
expect(toDegree(Math.PI * 2)).toBe(360);
});
});