ソースを参照

Add 'field.js'

alancnet 7 年 前
コミット
07a3c3c832
1 ファイル変更86 行追加0 行削除
  1. 86 0
      field.js

+ 86 - 0
field.js

@@ -0,0 +1,86 @@
+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))