Bladeren bron

Add a new combined lightness-chroma metric, reorder metrics

Kirk Trombley 3 jaren geleden
bovenliggende
commit
061173990b
3 gewijzigde bestanden met toevoegingen van 39 en 28 verwijderingen
  1. 3 3
      nearest.html
  2. 25 19
      web/metrics.js
  3. 11 6
      web/render.js

+ 3 - 3
nearest.html

@@ -22,7 +22,7 @@
       number: 10,
       useCluster: true,
       clusterSettings: {
-        sortMetric: "chroma",
+        sortMetric: "chromaLight",
         scaleOption: "direct",
         sortOrder: "max",
       },
@@ -66,8 +66,8 @@
         addOption(metric.option, value);
       });
 
-      document.getElementById("sort-metric").firstChild.nextSibling.nextSibling.nextSibling.nextSibling.selected = true;
-      document.getElementById("cluster-sort-metric").lastChild.previousSibling.previousSibling.selected = true;
+      document.getElementById("sort-metric").firstChild.nextSibling.nextSibling.selected = true;
+      document.getElementById("cluster-sort-metric").lastChild.selected = true;
       
       onRandomColor(state);
     }

+ 25 - 19
web/metrics.js

@@ -1,4 +1,12 @@
 const metrics = {
+  alpha: { // combine sigma and bigTheta
+    option: "Geometric Difference (α)",
+    displayName: String.raw`\alpha`,
+    displayBody: p => String.raw`
+      \sqrt{\sigma\left(${p}\right)^{2 - L\left(\vec{q}\right)} \Theta\left(${p}\right)^{L\left(\vec{q}\right)}}
+    `,
+    evaluate: () => 0, // calculated below
+  },
   sigma: { // RMS
     option: "RMS Deviation (σ)",
     displayName: String.raw`\sigma`,
@@ -15,14 +23,6 @@ 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)^{2 - L\left(\vec{q}\right)} \Theta\left(${p}\right)^{L\left(\vec{q}\right)}}
-    `,
-    evaluate: () => 0, // calculated below
-  },
   theta: { // angle of mean
     option: "Angular Difference (θ)",
     displayName: String.raw`\theta`,
@@ -82,6 +82,18 @@ const metrics = {
     `,
     evaluate: data => data.inertia,
   },
+  muNuAngle: {
+    option: "Mu-Nu Angle (V)",
+    displayName: "V",
+    displayBody: p => String.raw`\angle \left( \vec{\mu}\left(${p}\right), \vec{\nu}\left(${p}\right) \right)`,
+    evaluate: data => data.muNuAngle,
+  },
+  size: {
+    option: "Size (N)",
+    displayName: "N",
+    displayBody: p => String.raw`\left|${p}\right|`,
+    evaluate: data => data.size,
+  },
   lightness: {
     option: "Mean Lightness (L)",
     displayName: "L",
@@ -96,18 +108,12 @@ const metrics = {
     displayBody: p => String.raw`\text{chroma}\left(\vec{\mu}\left(${p}\right)\right)`,
     evaluate: data => data.mu.chroma,
   },
-  muNuAngle: {
-    option: "Mu-Nu Angle (V)",
-    displayName: "V",
-    displayBody: p => String.raw`\angle \left( \vec{\mu}\left(${p}\right), \vec{\nu}\left(${p}\right) \right)`,
-    evaluate: data => data.muNuAngle,
+  chromaLight: {
+    option: "Colorfulness (γ)",
+    displayName: String.raw`\gamma`,
+    displayBody: p => String.raw`\sqrt{C\left(${p}\right) L\left(${p}\right)}`,
+    evaluate: data => Math.sqrt(data.mu.lightness * data.mu.chroma),
   },
-  size: {
-    option: "Size (N)",
-    displayName: "N",
-    displayBody: p => String.raw`\left|${p}\right|`,
-    evaluate: data => data.size,
-  }
 };
 
 const applyMetrics = (data, target) => {

+ 11 - 6
web/render.js

@@ -35,9 +35,9 @@ const renderPokemonTileCluster = (area, totalSize, { mu, nu }, scores) => {
       </div>
       <div class="toggle-on">
         ${
-          [ ["σ =", scores.sigma.toFixed(3)],
+          [ ["α =", scores.alpha.toFixed(3)],
+            ["σ =", scores.sigma.toFixed(3)],
             ["Θ =", scores.bigTheta.toFixed(3)],
-            ["α =", scores.alpha.toFixed(3)],
             ["θ =", scores.theta.toFixed(3) + "°"],
             ["ϕ =", scores.phi.toFixed(3) + "°"],
             ["δ =", scores.delta.toFixed(3)],
@@ -60,6 +60,7 @@ const renderPokemonTileCluster = (area, totalSize, { mu, nu }, scores) => {
             ["I =", scores.inertia.toFixed(2)],
             ["L =", scores.lightness.toFixed(2)],
             ["C =", scores.chroma.toFixed(2)],
+            ["γ = ", scores.chromaLight.toFixed(2)],
             ["V =", scores.muNuAngle.toFixed(2)],
             ["N =", scores.size],
           ]
@@ -106,9 +107,9 @@ const renderPokemonTile = (kind, name, { total: { mu, nu, size }, clusters }, sc
         </div>
         <div class="toggle-on">
           ${ renderStatRow(
-            [ ["σ =", scores.total.sigma.toFixed(3)],
+            [ ["α =", scores.total.alpha.toFixed(3)],
+              ["σ =", scores.total.sigma.toFixed(3)],
               ["Θ =", scores.total.bigTheta.toFixed(3)],
-              ["α =", scores.total.alpha.toFixed(3)],
             ].map(([lbl, val]) => renderStatPair(lbl, val))
           )}
           ${ renderStatRow(
@@ -131,12 +132,16 @@ const renderPokemonTile = (kind, name, { total: { mu, nu, size }, clusters }, sc
           )}
           ${ renderStatRow(
             [ ["I =", scores.total.inertia.toFixed(2)],
-              ["L =", scores.total.lightness.toFixed(2)],
-              ["C =", scores.total.chroma.toFixed(2)],
               ["V =", scores.total.muNuAngle.toFixed(2)],
               ["N =", size],
             ].map(([lbl, val, cls]) => renderStatPair(lbl, val, cls))
           )}
+          ${ renderStatRow(
+            [ ["L =", scores.total.lightness.toFixed(2)],
+              ["C =", scores.total.chroma.toFixed(2)],
+              ["γ = ", scores.total.chromaLight.toFixed(2)],
+            ].map(([lbl, val, cls]) => renderStatPair(lbl, val, cls))
+          )}
           ${ bestClusterIndex < 0 ? "" : `<hr style="width: 80%; color: ${textColor}"/>` }
           ${ renderStatRow([
             `<span class="pkmn-tile_indicator">${bestClusterIndex === 0 ? "▼" : ""}</span>`,