fix: make circular and spiral presets truthful
This commit is contained in:
@@ -67,6 +67,116 @@ test("격자·선형·링·Fermat preset이 개수와 생성 경계를 지킨다
|
||||
}
|
||||
});
|
||||
|
||||
test("원형과 Fermat preset은 비정사각 경계에서도 실제 내접원 좌표를 만든다", () => {
|
||||
const aperture = { width: 0.5, height: 0.3 };
|
||||
const edgeInsetM = 0.02;
|
||||
const expectedRadius = 0.13;
|
||||
const count = 12;
|
||||
|
||||
for (const type of ["ring", "spiral"]) {
|
||||
const rectangle = generatePresetMicrophones({
|
||||
type,
|
||||
aperture,
|
||||
shape: "rectangle",
|
||||
edgeInsetM,
|
||||
count,
|
||||
});
|
||||
const ellipse = generatePresetMicrophones({
|
||||
type,
|
||||
aperture,
|
||||
shape: "ellipse",
|
||||
edgeInsetM,
|
||||
count,
|
||||
});
|
||||
assertEqual(
|
||||
JSON.stringify(rectangle),
|
||||
JSON.stringify(ellipse),
|
||||
type + " coordinates describe the preset instead of tracing the boundary shape",
|
||||
);
|
||||
assert(
|
||||
rectangle.every((microphone) =>
|
||||
positionInsideAperture(microphone.position, aperture, "rectangle") &&
|
||||
positionInsideAperture(microphone.position, aperture, "ellipse")),
|
||||
type + " inscribed-circle coordinates fit either generation boundary",
|
||||
);
|
||||
}
|
||||
|
||||
const ring = generatePresetMicrophones({
|
||||
type: "ring",
|
||||
aperture,
|
||||
shape: "rectangle",
|
||||
edgeInsetM,
|
||||
count,
|
||||
});
|
||||
for (const microphone of ring) {
|
||||
assertNear(
|
||||
Math.hypot(microphone.position[0], microphone.position[1]),
|
||||
expectedRadius,
|
||||
1e-8,
|
||||
"ring radius",
|
||||
);
|
||||
}
|
||||
|
||||
const spiral = generatePresetMicrophones({
|
||||
type: "spiral",
|
||||
aperture,
|
||||
shape: "rectangle",
|
||||
edgeInsetM,
|
||||
count,
|
||||
});
|
||||
spiral.forEach((microphone, index) => {
|
||||
assertNear(
|
||||
Math.hypot(microphone.position[0], microphone.position[1]),
|
||||
expectedRadius * Math.sqrt((index + 0.5) / count),
|
||||
1e-8,
|
||||
"equal-area Fermat radius " + index,
|
||||
);
|
||||
});
|
||||
assertEqual(
|
||||
generatePresetMicrophones({ type: "spiral", aperture, count: 1 })[0].position.join(","),
|
||||
"0,0,0",
|
||||
"single-microphone spiral is centered",
|
||||
);
|
||||
});
|
||||
|
||||
test("Archimedean preset은 중심부터 내접원까지 선형 반경의 실제 나선을 만든다", () => {
|
||||
const aperture = { width: 0.5, height: 0.3 };
|
||||
const edgeInsetM = 0.02;
|
||||
const maximumRadius = 0.13;
|
||||
const turns = 2.5;
|
||||
const count = 11;
|
||||
const microphones = generatePresetMicrophones({
|
||||
type: "archimedean",
|
||||
aperture,
|
||||
shape: "rectangle",
|
||||
edgeInsetM,
|
||||
turns,
|
||||
count,
|
||||
});
|
||||
assertEqual(microphones.length, count, "Archimedean count");
|
||||
microphones.forEach((microphone, index) => {
|
||||
assertNear(
|
||||
Math.hypot(microphone.position[0], microphone.position[1]),
|
||||
maximumRadius * index / (count - 1),
|
||||
1e-8,
|
||||
"Archimedean linear radius " + index,
|
||||
);
|
||||
});
|
||||
assertEqual(microphones[0].position.join(","), "0,0,0", "spiral starts at center");
|
||||
assertNear(microphones.at(-1).position[0], -maximumRadius, 1e-8, "2.5 turns end at -x");
|
||||
assertNear(microphones.at(-1).position[1], 0, 1e-8, "2.5 turns end on x axis");
|
||||
assertThrows(
|
||||
() => generatePresetMicrophones({
|
||||
type: "archimedean",
|
||||
aperture,
|
||||
turns: 0,
|
||||
count,
|
||||
}),
|
||||
"0.25",
|
||||
"Archimedean turn lower bound",
|
||||
);
|
||||
});
|
||||
|
||||
test("타원 격자는 요청한 rows x columns 수를 유지하며 경계 안에 배치된다", () => {
|
||||
const aperture = { width: 0.45, height: 0.3 };
|
||||
const microphones = generatePresetMicrophones({
|
||||
|
||||
Reference in New Issue
Block a user