Skip to content

Instantly share code, notes, and snippets.

@amiika
Created September 25, 2025 19:30
Show Gist options
  • Select an option

  • Save amiika/f658b86fd8e36a28a9a697f01fca5603 to your computer and use it in GitHub Desktop.

Select an option

Save amiika/f658b86fd8e36a28a9a697f01fca5603 to your computer and use it in GitHub Desktop.
Tonnetz generators
/**
* Transforms triad intervals into Tonnetz generator vectors.
*
* @param triadIntervals An array [a, b, c] representing the intervals
* around a triad, which must sum to 12.
* @returns An array [u, v] of the two generator vectors, or null if the input is invalid.
*/
function triadIntervalsToGenerators(triadIntervals) {
// Validate the input
if (!Array.isArray(triadIntervals) || triadIntervals.length !== 3 || triadIntervals.reduce((sum, val) => sum + val, 0) !== 12) {
console.error("Invalid input: Must be an array of 3 intervals summing to 12.");
return null;
}
const [a, b, c] = triadIntervals;
// The first generator vector 'u' is simply the first interval from the root.
const u = a;
// The second generator vector 'v' is the interval from the root to the third note.
// This is equivalent to a + b, or more simply, 12 - c.
const v = 12 - c;
// Conventional to list the larger interval first
return [u, v].sort((x, y) => y - x);
}
console.log(triadIntervalsToGenerators([3,4,5]))
const TONNETZ_GENERATORS: readonly (readonly [number, number])[] = [
// Standard Major/Minor
[7, 4], // from [4, 3, 5] (Major Triad)
[7, 3], // from [3, 4, 5] (Minor Triad)
// Other Connected Spaces
[2, 1], // from [1, 1, 10]
[3, 1], // from [1, 2, 9]
[4, 1], // from [1, 3, 8]
[5, 1], // from [1, 4, 7]
[6, 1], // from [1, 5, 6]
[5, 2], // from [2, 3, 7]
[7, 2], // from [2, 5, 5]
// Non-Connected (Fragmented) Spaces
[4, 2], // from [2, 2, 8] (Whole-tone fragment)
[6, 2], // from [2, 4, 6] (Whole-tone fragment)
[6, 3], // from [3, 3, 6] (Hexatonic)
[8, 4], // from [4, 4, 4] (Augmented)
// Additional Interesting Non-Standard Spaces
[4, 3], // from [3, 1, 8] (Hexatonic)
[5, 3], // from [3, 2, 7] (Diatonic fragment)
[5, 4], // from [4, 1, 7] (Diatonic fragment)
[8, 3], // from [3, 5, 4] (Hexatonic)
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment