class Field { constructor(...sizes) { this.n = sizes.length this.sizes = sizes this.data = [] const g = (p, n) => { if (n < sizes.length) { const end = n === sizes.length - 1 for (let i = 0; i < sizes[n]; i++) { p[i] = end ? 0 : [] g(p[i], n + 1) } } } g(this.data, 0) } * indices() { const self = this const g = function*(p, n) { if (n === self.sizes.length) yield p const size = self.sizes[n] for (let i = 0; i < size; i++) { yield* g([...p, i], n + 1) } } yield* g([], 0) } get(...indices) { const g = (o, n) => { if (n === indices.length || n === this.sizes.length) return o const i = indices[n] console.log(i, n) const f = Math.floor(i) const r = i - f if (r) { // Return weighted value const a = g(o[f], n + 1) const b = g(o[f + 1], n + 1) return a * (1 - r) + b * r } else { return g(o[f], n + 1) } } return g(this.data, 0) } set(value, ...indices) { const g = (o, w, n) => { const end = (n === indices.length - 1 || n === this.sizes.length - 1) const i = indices[n] console.log(i, w, n) const f = Math.floor(i) const r = i - f if (r) { if (end) { // o[f] = 1, v = .3, w = 1 ... expected result o[f] = .3 // value - o[f] = -.7 ... * w = 1.. yep o[f] = o[f] + (1 - r) * w * (value - o[f]) o[f + 1] = o[f + 1] + r * w * (value - o[f + 1]) } else { g(o[f], (1 - r) * w, n + 1) g(o[f + 1], r * w, n + 1) } } else { if (end) { o[f] = o[f] + w * (value - o[f]) } else { g(o[f], w, n + 1) } } } return g(this.data, 1, 0) } } const f = new Field(2,2,2) for (let i of f.indices()) { console.log(i) } f.set(1, .5,.5, .5) console.log(JSON.stringify(f.data)) console.log(f.get(.5, .5, .5))