improve drawLine

This commit is contained in:
Felix Roos 2022-04-24 00:56:16 +02:00
parent dd03ad6c14
commit a0d6fc47e0
2 changed files with 27 additions and 22 deletions

View File

@ -1,32 +1,25 @@
import { gcd } from './fraction.mjs'; import Fraction, { gcd } from './fraction.mjs';
function drawLine(pat, chars = 60) { function drawLine(pat, chars = 60) {
let c = 0; let cycle = 0;
let pos = Fraction(0);
let lines = ['']; let lines = [''];
let emptyLine = ''; // this will be the "reference" empty line, which will be copied into extra lines
const slots = []; const slots = [];
while (lines[0].length < chars) { while (lines[0].length < chars) {
const haps = pat.queryArc(c, c + 1); const haps = pat.queryArc(cycle, cycle + 1);
const durations = haps.filter((hap) => hap.hasOnset()).map((hap) => hap.duration); const durations = haps.filter((hap) => hap.hasOnset()).map((hap) => hap.duration);
const totalSlots = gcd(...durations).inverse(); const totalSlots = gcd(...durations).inverse(); // number of character slots for the current cycle
slots.push(totalSlots); slots.push(totalSlots); // remember slots for possible empty lines needed in a later cycle
const minDuration = durations.reduce((a, b) => a.min(b), durations[0]); const minDuration = durations.reduce((a, b) => a.min(b), durations[0]); // min duration = step length
lines = lines.map((line) => line + '|'); lines = lines.map((line) => line + '|'); // add pipe character before each cycle
emptyLine += '|';
for (let i = 0; i < totalSlots; i++) { for (let i = 0; i < totalSlots; i++) {
const step = c * totalSlots + i; const [begin, end] = [pos, pos.add(minDuration)];
const [begin, end] = [minDuration.mul(step), minDuration.mul(step + 1)];
const matches = haps.filter((hap) => hap.whole.begin.lte(begin) && hap.whole.end.gte(end)); const matches = haps.filter((hap) => hap.whole.begin.lte(begin) && hap.whole.end.gte(end));
const missingLines = matches.length - lines.length; const missingLines = matches.length - lines.length;
if (missingLines > 0) { if (missingLines > 0) {
console.log(c, 'missingLines', missingLines); lines = lines.concat(Array(missingLines).fill(emptyLine));
const emptyCycles =
'|' +
new Array(c)
.fill()
.map((_, l) => Array(slots[l]).fill('.').join(''))
.join('|') +
Array(i).fill('.').join('');
lines = lines.concat(Array(missingLines).fill(emptyCycles));
} }
lines = lines.map((line, i) => { lines = lines.map((line, i) => {
const hap = matches[i]; const hap = matches[i];
@ -37,8 +30,10 @@ function drawLine(pat, chars = 60) {
} }
return line + '.'; return line + '.';
}); });
emptyLine += '.';
pos = pos.add(minDuration);
} }
c++; cycle++;
} }
return lines.join('\n'); return lines.join('\n');
} }

View File

@ -1,12 +1,19 @@
import { fastcat, stack } from '../pattern.mjs'; import { fastcat, stack, slowcat } from '../pattern.mjs';
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import drawLine from '../drawLine.mjs'; import drawLine from '../drawLine.mjs';
describe('drawLine', () => { describe('drawLine', () => {
it('should work', () => { it('supports equal lengths', () => {
assert.equal(drawLine(fastcat(0), 4), '|0|0');
assert.equal(drawLine(fastcat(0, 1), 4), '|01|01');
assert.equal(drawLine(fastcat(0, 1, 2), 6), '|012|012');
});
it('supports unequal lengths', () => {
assert.equal(drawLine(fastcat(0, [1, 2]), 10), '|0-12|0-12'); assert.equal(drawLine(fastcat(0, [1, 2]), 10), '|0-12|0-12');
assert.equal(drawLine(fastcat(0, [1, 2, 3]), 10), '|0--123|0--123'); assert.equal(drawLine(fastcat(0, [1, 2, 3]), 10), '|0--123|0--123');
assert.equal(drawLine(fastcat(0, 1, [2, 3]), 10), '|0-1-23|0-1-23'); assert.equal(drawLine(fastcat(0, 1, [2, 3]), 10), '|0-1-23|0-1-23');
});
it('supports multiple lines', () => {
assert.equal( assert.equal(
drawLine(fastcat(0, stack(1, 2)), 10), drawLine(fastcat(0, stack(1, 2)), 10),
`|01|01|01|01 `|01|01|01|01
@ -30,4 +37,7 @@ describe('drawLine', () => {
|..4|..4|..4`, |..4|..4|..4`,
); );
}); });
it('supports unequal cycle lengths', () => {
assert.equal(drawLine(slowcat(0, [1, 2]), 10), `|0|12|0|12`);
});
}); });