cores nas regioes anatomicas

This commit is contained in:
Rodrigo Bertoldo de Sousa Martins committed 2026-09-16 11:53:14 -03:00
1 parent 149a12640b
commit a972670b7d
1 file changed
+42 -2
+42 -2
View File
@@ -106,6 +106,42 @@ function muscleColorVariant(baseHex, variantKey) {
return hslToHex(h + hueShift, s, Math.min(0.85, Math.max(0.25, l + lightShift))); return hslToHex(h + hueShift, s, Math.min(0.85, Math.max(0.25, l + lightShift)));
} }
// Regiões de superfície (epigástrica, mesogástrica/umbilical, hipogástrica
// etc.) são o oposto do caso muscular: em vez de estruturas ANATOMICAMENTE
// relacionadas que precisam parecer "da mesma família" (uma leve variação
// em torno da cor-base do sistema já resolve), aqui são divisões
// TOPOGRÁFICAS lado a lado (as 9 regiões do abdome, por exemplo) que
// precisam ser claramente distinguíveis umas das outras à primeira vista —
// como num diagrama didático de livro-texto.
//
// Sortear o matiz por hash (`hash % 360`) parece razoável, mas com ~170
// nomes de região caindo aleatoriamente num círculo de 360°, é comum dois
// nomes vizinhos (ex: "umbilical region" e "hypogastric region", que ficam
// EMPILHADOS no abdome) calharem de cair perto um do outro por pura
// coincidência de hash — testamos e foi exatamente o que aconteceu.
// Em vez disso, distribuímos os matizes pelo "ângulo dourado" (~137.5°) na
// ordem alfabética de TODOS os nomes de região conhecidos (as chaves de
// REGION_DESCRIPTIONS): esse incremento é a técnica clássica pra espalhar
// N categorias por um círculo de cores sem duas vizinhas na lista saírem
// vizinhas na cor. Saturação/luminosidade ficam fixas numa faixa pastel,
// pra toda região continuar parecendo parte do mesmo sistema visual.
// Esquerda/direita da MESMA região (mesmo variantKey, já sem sufixo de
// lado) sempre saem com a cor igual.
const REGION_HUE_ORDER = Object.keys(REGION_DESCRIPTIONS).sort();
const REGION_HUE_INDEX = new Map(REGION_HUE_ORDER.map((k, i) => [k, i]));
const GOLDEN_ANGLE_DEG = 137.50776;
function regionColorVariant(variantKey) {
const index = REGION_HUE_INDEX.has(variantKey)
? REGION_HUE_INDEX.get(variantKey)
: REGION_HUE_ORDER.length + (stringHash(variantKey) % 360); // nomes fora da lista (raro): ainda determinístico
const hue = ((index * GOLDEN_ANGLE_DEG) % 360) / 360;
const hash = stringHash(variantKey);
const sat = 0.5 + ((hash >> 8) % 16) / 100; // 0.50–0.65
const light = 0.6 + ((hash >> 16) % 14) / 100; // 0.60–0.73
return hslToHex(hue, sat, light);
}
// Tom mais escuro da MESMA cor do músculo — usado nos sulcos cosméticos // Tom mais escuro da MESMA cor do músculo — usado nos sulcos cosméticos
// (ver MUSCULAR_COSMETIC_GROOVES), pra parecer uma "dobra"/sombra na // (ver MUSCULAR_COSMETIC_GROOVES), pra parecer uma "dobra"/sombra na
// própria superfície do músculo em vez de um elemento estranho. // própria superfície do músculo em vez de um elemento estranho.
@@ -736,7 +772,11 @@ for (const { fbx, key } of SOURCES) {
if (materialCache.has(cacheKey)) return materialCache.get(cacheKey); if (materialCache.has(cacheKey)) return materialCache.get(cacheKey);
const sys = systemBySlug.get(systemSlug); const sys = systemBySlug.get(systemSlug);
const baseHex = sys?.colorHex ?? "#cccccc"; const baseHex = sys?.colorHex ?? "#cccccc";
const colorHex = variantKey ? muscleColorVariant(baseHex, variantKey) : baseHex; const colorHex = !variantKey
? baseHex
: systemSlug === "regioes"
? regionColorVariant(variantKey)
: muscleColorVariant(baseHex, variantKey);
const mat = doc const mat = doc
.createMaterial(cacheKey) .createMaterial(cacheKey)
.setBaseColorFactor(hexToRgb(colorHex)) .setBaseColorFactor(hexToRgb(colorHex))
@@ -818,7 +858,7 @@ for (const { fbx, key } of SOURCES) {
: key === "nervous" : key === "nervous"
? NERVE_DESCRIPTIONS[base.toLowerCase()] ?? "" ? NERVE_DESCRIPTIONS[base.toLowerCase()] ?? ""
: ""; : "";
if (key === "muscular") muscleColorKey = base.toLowerCase(); if (key === "muscular" || key === "regions") muscleColorKey = base.toLowerCase();
} }
const material = materialFor(systemSlug, muscleColorKey); const material = materialFor(systemSlug, muscleColorKey);