Kirk Trombley 3 лет назад
Родитель
Сommit
74b3b0a8ab
2 измененных файлов с 31 добавлено и 13 удалено
  1. 16 3
      web/metrics.js
  2. 15 10
      web/render.js

+ 16 - 3
web/metrics.js

@@ -15,6 +15,13 @@ const metrics = {
     `,
     evaluate: (data, target) => 1 - vectorDot(data.nu, target.unit),
   },
+  alpha: { // combine sigma and bigTheta
+    option: "Geometric Difference (α)",
+    displayName: String.raw`\alpha`,
+    displayBody: p => String.raw`
+      \sqrt{\sigma\left(${p}\right)\Theta\left(${p}\right)}
+    `,
+    evaluate: () => 0, // calculated below
   },
   theta: { // angle of mean
     option: "Angular Difference (θ)",
@@ -97,6 +104,12 @@ const metrics = {
   }
 };
 
-const applyMetrics = (data, target) => Object.fromEntries(
-  Object.entries(metrics).map(([name, metric]) => [name, metric.evaluate(data, target)])
-);
+const applyMetrics = (data, target) => {
+  const scores = Object.fromEntries(
+    Object.entries(metrics)
+      .map(([name, metric]) => [name, metric.evaluate(data, target)])
+  );
+  // rearranges to geometric mean of sigma and bigTheta
+  scores.alpha = Math.sqrt(scores.sigma * scores.bigTheta);
+  return scores;
+};

+ 15 - 10
web/render.js

@@ -36,12 +36,13 @@ const renderPokemonTileCluster = (area, totalSize, { mu, nu }, scores) => {
       <div class="toggle-on">
         ${
           [ ["σ =", scores.sigma.toFixed(3)],
-            ["δ =", scores.delta.toFixed(3)],
-            ["M =", scores.manhattan.toFixed(3)],
-            ["Ч =", scores.ch.toFixed(3)],
             ["Θ =", scores.bigTheta.toFixed(3)],
+            ["α =", scores.alpha.toFixed(3)],
             ["θ =", scores.theta.toFixed(3) + "°"],
             ["ϕ =", scores.phi.toFixed(3) + "°"],
+            ["δ =", scores.delta.toFixed(3)],
+            ["M =", scores.manhattan.toFixed(3)],
+            ["Ч =", scores.ch.toFixed(3)],
             ["ℓ =", scores.lightnessDiff.toFixed(3)],
           ]
             .map(([lbl, val]) => renderStatPair(lbl, val))
@@ -53,11 +54,11 @@ const renderPokemonTileCluster = (area, totalSize, { mu, nu }, scores) => {
           [ ["μ =", `(${mu.vector[0].toFixed(2)},`],
             ["", mu.vector[1].toFixed(2) + ","],
             ["", mu.vector[2].toFixed(2) + ")"],
-            ["I =", scores.inertia.toFixed(2)],
-            ["ℒ =", scores.lightness.toFixed(2) + "°"],
             ["ν =", `(${nu[0].toFixed(2)},`],
             ["", nu[1].toFixed(2) + ","],
             ["", nu[2].toFixed(2) + ")"],
+            ["I =", scores.inertia.toFixed(2)],
+            ["ℒ =", scores.lightness.toFixed(2)],
             ["V =", scores.muNuAngle.toFixed(2)],
             ["N =", scores.size],
           ]
@@ -105,15 +106,19 @@ const renderPokemonTile = (kind, name, { total: { mu, nu, size }, clusters }, sc
         <div class="toggle-on">
           ${ renderStatRow(
             [ ["σ =", scores.total.sigma.toFixed(3)],
-              ["δ =", scores.total.delta.toFixed(3)],
-              ["M =", scores.total.manhattan.toFixed(3)],
-              ["Ч =", scores.total.ch.toFixed(3)],
+              ["Θ =", scores.total.bigTheta.toFixed(3)],
+              ["α =", scores.total.alpha.toFixed(3)],
             ].map(([lbl, val]) => renderStatPair(lbl, val))
           )}
           ${ renderStatRow(
-            [ ["Θ =", scores.total.bigTheta.toFixed(3)],
-              ["θ =", scores.total.theta.toFixed(3) + "°"],
+            [ ["θ =", scores.total.theta.toFixed(3) + "°"],
               ["ϕ =", scores.total.phi.toFixed(3) + "°"],
+            ].map(([lbl, val]) => renderStatPair(lbl, val))
+          )}
+          ${ renderStatRow(
+            [ ["δ =", scores.total.delta.toFixed(3)],
+              ["M =", scores.total.manhattan.toFixed(3)],
+              ["Ч =", scores.total.ch.toFixed(3)],
               ["ℓ =", scores.total.lightnessDiff.toFixed(3)],
             ].map(([lbl, val]) => renderStatPair(lbl, val))
           )}