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

115 lines
2.6 KiB
TypeScript

import type { IVec, IVec3 } from '@blocksuite/global/utils';
import { almostEqual } from '@blocksuite/global/utils';
import { describe, expect, it } from 'vitest';
import { AStarRunner } from '../utils/a-star.js';
function mergePath(points: IVec3[]) {
if (points.length === 0) return points;
const rst: IVec3[] = [points[0]];
for (let i = 1; i < points.length - 1; i++) {
const cur = points[i];
const last = points[i - 1];
const next = points[i + 1];
if (
almostEqual(last[0], cur[0], 0.02) &&
almostEqual(cur[0], next[0], 0.02)
)
continue;
if (
almostEqual(last[1], cur[1], 0.02) &&
almostEqual(cur[1], next[1], 0.02)
)
continue;
rst.push(cur);
}
rst.push(points[points.length - 1]);
return rst;
}
describe('a* algorithm', () => {
/**
* 0 ----------------
* |
* |
* ------------------- 0
*/
it('width is greater than height', () => {
const sp: IVec3 = [0, 0, 0];
const ep: IVec3 = [200, 100, 0];
const osp: IVec3 = [-1, 0, 0];
const oep: IVec3 = [201, 100, 0];
const points: IVec3[] = [
sp,
ep,
[100, 0, 0],
[200, 0, 0],
[0, 50, 0],
[100, 50, 3],
[200, 50, 0],
[0, 100, 0],
[100, 100, 0],
] as IVec3[];
const aStar = new AStarRunner(points, sp, ep, osp, oep);
aStar.run();
let path: IVec[] | IVec3[] = aStar.path;
path.pop();
path.shift();
path = mergePath(path);
const expected = [
[0, 0],
[100, 0],
[100, 100],
[200, 100],
];
path.forEach((p, i) => {
expect(p[0]).toBe(expected[i][0]);
expect(p[1]).toBe(expected[i][1]);
});
});
/**
* 0
* |
* |
* |
* |----|
* |
* |
* |
* 0
*/
it('height is greater than width', () => {
const sp: IVec3 = [0, 0, 0];
const ep: IVec3 = [100, 200, 0];
const osp: IVec3 = [0, -1, 0];
const oep: IVec3 = [100, 201, 0];
const points: IVec3[] = [
sp,
[50, 0, 0],
[100, 0, 0],
[0, 100, 0],
[50, 100, 3],
[100, 100, 0],
[0, 200, 0],
[50, 200, 0],
ep,
];
const aStar = new AStarRunner(points, sp, ep, osp, oep);
aStar.run();
let path = aStar.path;
path.pop();
path.shift();
path = mergePath(path);
const expected = [
[0, 0],
[0, 100],
[100, 100],
[100, 200],
];
path.forEach((p, i) => {
expect(p[0]).toBe(expected[i][0]);
expect(p[1]).toBe(expected[i][1]);
});
});
});