diff --git a/src/components/Faux3DLattice.vue b/src/components/Faux3DLattice.vue index 22be0375..cbbcad12 100644 --- a/src/components/Faux3DLattice.vue +++ b/src/components/Faux3DLattice.vue @@ -5,7 +5,6 @@ */ import { useJiLatticeStore } from '@/stores/ji-lattice' import { spanLattice3D } from 'ji-lattice' -import { TimeMonzo, type Interval } from 'sonic-weave' import { computed, nextTick, reactive, ref, watch } from 'vue' const EPSILON = 1e-6 @@ -16,7 +15,7 @@ const NEAR_PLANE = 0.5 const store = useJiLatticeStore() const props = defineProps<{ - relativeIntervals: Interval[] + monzos: number[][] labels: string[] colors: string[] heldNotes: Set @@ -26,24 +25,8 @@ const svgElement = ref(null) const viewBox = reactive([-1, -1, 2, 2]) -const monzos = computed(() => { - const numComponents = store.horizontalCoordinates.length - const result: number[][] = [] - for (const interval of props.relativeIntervals) { - const value = interval.value.clone() - if (value instanceof TimeMonzo) { - value.numberOfComponents = numComponents - const monzo = value.primeExponents.map((pe) => pe.valueOf()) - result.push(monzo) - } else { - result.push(Array(numComponents).fill(0)) - } - } - return result -}) - const lattice = computed(() => { - const result = spanLattice3D(monzos.value, store.latticeOptions3D) + const result = spanLattice3D(props.monzos, store.latticeOptions3D) // Center everything so that the vanishing point is at the center of the view box const inorm = 1 / result.vertices.length const avgX = result.vertices.reduce((s, v) => s + v.x, 0) * inorm @@ -72,6 +55,7 @@ watch( svgElement.value, lattice.value, props.labels, + store.depth, store.labelOffset, store.size, store.showLabels diff --git a/src/components/JustIntonationLattice.vue b/src/components/JustIntonationLattice.vue index 05750a7c..3683a545 100644 --- a/src/components/JustIntonationLattice.vue +++ b/src/components/JustIntonationLattice.vue @@ -19,7 +19,10 @@ const svgElement = ref(null) const viewBox = reactive([-1, -1, 2, 2]) const monzos = computed(() => { - const numComponents = store.horizontalCoordinates.length + const numComponents = Math.max( + store.horizontalCoordinates.length, + store.verticalCoordinates.length + ) const result: number[][] = [] for (const interval of props.relativeIntervals) { const value = interval.value.clone() diff --git a/src/stores/ji-lattice.ts b/src/stores/ji-lattice.ts index f7bbf0ba..09e147cf 100644 --- a/src/stores/ji-lattice.ts +++ b/src/stores/ji-lattice.ts @@ -10,7 +10,7 @@ import { WGP9, primeSphere } from 'ji-lattice' -import { LOG_PRIMES, mmod } from 'xen-dev-utils' +import { LOG_PRIMES, dot, mmod } from 'xen-dev-utils' import { computedAndError } from '@/utils' import { TimeMonzo, parseChord } from 'sonic-weave' @@ -209,8 +209,25 @@ export const useJiLatticeStore = defineStore('ji-lattice', () => { } // 3D presets + + function autoDepth(monzos: number[][]) { + if (!xCoords.length || !yCoords.length || !zCoords.length) { + return + } + const x = monzos.map((m) => dot(m, xCoords)) + const y = monzos.map((m) => dot(m, yCoords)) + const z = monzos.map((m) => dot(m, zCoords)) + const objectSize = Math.max( + Math.max(...x) - Math.min(...x), + Math.max(...y) - Math.min(...y), + Math.max(...z) - Math.min(...z) + ) + depth.value = Math.ceil(2 * objectSize) + } + function WGP(equaveIndex = 0) { size.value = 2 + depth.value = 100 const w = WGP9(equaveIndex) xCoords.length = 0 xCoords.push(...w.horizontalCoordinates) @@ -348,6 +365,7 @@ export const useJiLatticeStore = defineStore('ji-lattice', () => { scott24, pr72, pe72, + autoDepth, WGP, sphere, pitch, diff --git a/src/views/LatticeView.vue b/src/views/LatticeView.vue index 98bc075a..7d2dcaab 100644 --- a/src/views/LatticeView.vue +++ b/src/views/LatticeView.vue @@ -12,6 +12,7 @@ import { useGridStore } from '@/stores/grid' import { useCyclesStore } from '@/stores/edo-cycles' import { setAndReportValidity } from '@/utils' import Faux3DLattice from '@/components/Faux3DLattice.vue' +import { TimeMonzo } from 'sonic-weave' const state = useStateStore() const scale = useScaleStore() @@ -56,6 +57,26 @@ const heldNotes = computed(() => { return result }) +const monzos3D = computed(() => { + const numComponents = Math.max( + jiLattice.xCoords.length, + jiLattice.yCoords.length, + jiLattice.zCoords.length + ) + const result: number[][] = [] + for (const interval of scale.latticeIntervals) { + const value = interval.value.clone() + if (value instanceof TimeMonzo) { + value.numberOfComponents = numComponents + const monzo = value.primeExponents.map((pe) => pe.valueOf()) + result.push(monzo) + } else { + result.push(Array(numComponents).fill(0)) + } + } + return result +}) + watch(jiPreset, (newValue) => { switch (newValue) { case 'grady': @@ -97,14 +118,15 @@ watch(preset3D, (newValue) => { switch (newValue) { case 'WGP': jiLattice.WGP() - return + break case 'sphere': jiLattice.sphere() - return + break case 'sphere3': jiLattice.sphere(1) - return + break } + jiLattice.autoDepth(monzos3D.value) }) function inferConfig() { @@ -152,12 +174,15 @@ function inferConfig() { // Set the config for 3D too, but use isometric by default if (limit <= 9) { jiLattice.WGP(equaveIndex) + jiLattice.autoDepth(monzos3D.value) jiLattice.kraigGrady(equaveIndex) } else if (limit <= 24) { jiLattice.sphere(equaveIndex, 24) + jiLattice.autoDepth(monzos3D.value) jiLattice.scott24(equaveIndex) } else if (equaveIndex < 72) { jiLattice.sphere(equaveIndex, 72) + jiLattice.autoDepth(monzos3D.value) jiLattice.pe72(equaveIndex) } else { return @@ -247,7 +272,7 @@ onMounted(() => { v-else-if="state.latticeType === '3d'" :labels="scale.latticeLabels" :colors="scale.latticeColors" - :relativeIntervals="scale.latticeIntervals" + :monzos="monzos3D" :heldNotes="heldNotes" />