mitose e meiose interfase
Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo@martinsevieira.adv.br>
This commit is contained in:
1 parent
734b967f11
commit
efb57d9e38
2 files changed
+123
-23
No files matched your search
@@ -75,7 +75,8 @@ interface CellSlotState {
|
|||||||
position: THREE.Vector3;
|
position: THREE.Vector3;
|
||||||
radius: { value: number };
|
radius: { value: number };
|
||||||
envelope: { value: number };
|
envelope: { value: number };
|
||||||
spindle: { value: number };
|
centrosomes: { value: number };
|
||||||
|
fibers: { value: number };
|
||||||
elongated: { value: number };
|
elongated: { value: number };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,27 +84,41 @@ function AnimatedCellSlot({
|
|||||||
target,
|
target,
|
||||||
state,
|
state,
|
||||||
}: {
|
}: {
|
||||||
target: { center: [number, number, number]; radius: number; envelope: number; spindle: boolean; elongated: number } | null;
|
target: {
|
||||||
|
center: [number, number, number];
|
||||||
|
radius: number;
|
||||||
|
envelope: number;
|
||||||
|
spindle: boolean;
|
||||||
|
centrosomes?: boolean;
|
||||||
|
elongated: number;
|
||||||
|
} | null;
|
||||||
state: CellSlotState;
|
state: CellSlotState;
|
||||||
}) {
|
}) {
|
||||||
const groupRef = useRef<THREE.Group>(null);
|
const groupRef = useRef<THREE.Group>(null);
|
||||||
const membraneRef = useRef<THREE.Mesh>(null);
|
const membraneRef = useRef<THREE.Mesh>(null);
|
||||||
const membraneMatRef = useRef<THREE.MeshStandardMaterial>(null);
|
const membraneMatRef = useRef<THREE.MeshStandardMaterial>(null);
|
||||||
const envelopeMatRef = useRef<THREE.MeshStandardMaterial>(null);
|
const envelopeMatRef = useRef<THREE.MeshStandardMaterial>(null);
|
||||||
const spindleRef = useRef<THREE.Group>(null);
|
const centrosomesRef = useRef<THREE.Group>(null);
|
||||||
|
const fibersRef = useRef<THREE.Group>(null);
|
||||||
|
|
||||||
useFrame((_, delta) => {
|
useFrame((_, delta) => {
|
||||||
const k = smoothing(delta);
|
const k = smoothing(delta);
|
||||||
const targetPos = target ? new THREE.Vector3(...target.center) : state.position.clone();
|
const targetPos = target ? new THREE.Vector3(...target.center) : state.position.clone();
|
||||||
const targetRadius = target ? target.radius : 0;
|
const targetRadius = target ? target.radius : 0;
|
||||||
const targetEnvelope = target ? target.envelope : 0;
|
const targetEnvelope = target ? target.envelope : 0;
|
||||||
const targetSpindle = target?.spindle ? 1 : 0;
|
const targetFibers = target?.spindle ? 1 : 0;
|
||||||
|
// Centrossomos ficam visíveis tanto na G2 (só eles, terminando de se
|
||||||
|
// preparar) quanto durante o fuso de verdade (prófase em diante) —
|
||||||
|
// `spindle: true` já implica centrossomos visíveis, sem precisar
|
||||||
|
// repetir `centrosomes: true` em cada estágio.
|
||||||
|
const targetCentrosomes = target?.spindle || target?.centrosomes ? 1 : 0;
|
||||||
const targetElongated = target ? target.elongated : 0;
|
const targetElongated = target ? target.elongated : 0;
|
||||||
|
|
||||||
state.position.lerp(targetPos, k);
|
state.position.lerp(targetPos, k);
|
||||||
state.radius.value = THREE.MathUtils.lerp(state.radius.value, targetRadius, k);
|
state.radius.value = THREE.MathUtils.lerp(state.radius.value, targetRadius, k);
|
||||||
state.envelope.value = THREE.MathUtils.lerp(state.envelope.value, targetEnvelope, k);
|
state.envelope.value = THREE.MathUtils.lerp(state.envelope.value, targetEnvelope, k);
|
||||||
state.spindle.value = THREE.MathUtils.lerp(state.spindle.value, targetSpindle, k);
|
state.centrosomes.value = THREE.MathUtils.lerp(state.centrosomes.value, targetCentrosomes, k);
|
||||||
|
state.fibers.value = THREE.MathUtils.lerp(state.fibers.value, targetFibers, k);
|
||||||
state.elongated.value = THREE.MathUtils.lerp(state.elongated.value, targetElongated, k);
|
state.elongated.value = THREE.MathUtils.lerp(state.elongated.value, targetElongated, k);
|
||||||
|
|
||||||
if (groupRef.current) groupRef.current.position.copy(state.position);
|
if (groupRef.current) groupRef.current.position.copy(state.position);
|
||||||
@@ -114,8 +129,14 @@ function AnimatedCellSlot({
|
|||||||
}
|
}
|
||||||
if (membraneMatRef.current) membraneMatRef.current.opacity = Math.min(0.22, state.radius.value * 0.28);
|
if (membraneMatRef.current) membraneMatRef.current.opacity = Math.min(0.22, state.radius.value * 0.28);
|
||||||
if (envelopeMatRef.current) envelopeMatRef.current.opacity = state.envelope.value * 0.35;
|
if (envelopeMatRef.current) envelopeMatRef.current.opacity = state.envelope.value * 0.35;
|
||||||
if (spindleRef.current) spindleRef.current.visible = state.spindle.value > 0.05;
|
if (centrosomesRef.current) {
|
||||||
if (spindleRef.current) spindleRef.current.scale.setScalar(state.spindle.value);
|
centrosomesRef.current.visible = state.centrosomes.value > 0.05;
|
||||||
|
centrosomesRef.current.scale.setScalar(state.centrosomes.value);
|
||||||
|
}
|
||||||
|
if (fibersRef.current) {
|
||||||
|
fibersRef.current.visible = state.fibers.value > 0.05;
|
||||||
|
fibersRef.current.scale.setScalar(state.fibers.value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -137,18 +158,25 @@ function AnimatedCellSlot({
|
|||||||
<sphereGeometry args={[0.42, 24, 24]} />
|
<sphereGeometry args={[0.42, 24, 24]} />
|
||||||
<meshStandardMaterial ref={envelopeMatRef} color="#c4b5fd" transparent opacity={0} depthWrite={false} />
|
<meshStandardMaterial ref={envelopeMatRef} color="#c4b5fd" transparent opacity={0} depthWrite={false} />
|
||||||
</mesh>
|
</mesh>
|
||||||
{/* fuso mitótico: 2 centrossomos + fibras finas em leque */}
|
{/* Centrossomos — visíveis sozinhos na G2 (recém-duplicados, ainda
|
||||||
<group ref={spindleRef}>
|
sem fibra nenhuma) e continuam visíveis junto do fuso a partir
|
||||||
|
da prófase. */}
|
||||||
|
<group ref={centrosomesRef}>
|
||||||
{[-1, 1].map((side) => (
|
{[-1, 1].map((side) => (
|
||||||
<group key={side} position={[side * 0.65, 0, 0]}>
|
<mesh key={side} position={[side * 0.65, 0, 0]}>
|
||||||
<mesh>
|
<sphereGeometry args={[0.035, 10, 10]} />
|
||||||
<sphereGeometry args={[0.035, 10, 10]} />
|
<meshStandardMaterial color="#f8fafc" />
|
||||||
<meshStandardMaterial color="#f8fafc" />
|
</mesh>
|
||||||
</mesh>
|
))}
|
||||||
|
</group>
|
||||||
|
{/* fibras do fuso — só a partir da prófase (quando `spindle: true`) */}
|
||||||
|
<group ref={fibersRef}>
|
||||||
|
{[-1, 1].map((side) => (
|
||||||
|
<group key={side}>
|
||||||
{[-0.25, -0.1, 0.1, 0.25].map((offset, i) => (
|
{[-0.25, -0.1, 0.1, 0.25].map((offset, i) => (
|
||||||
<mesh
|
<mesh
|
||||||
key={i}
|
key={i}
|
||||||
position={[side * -0.32, offset * 0.6, offset]}
|
position={[side * 0.65 + side * -0.32, offset * 0.6, offset]}
|
||||||
rotation={[0, 0, side > 0 ? Math.PI / 2 + offset * 0.3 : -Math.PI / 2 + offset * 0.3]}
|
rotation={[0, 0, side > 0 ? Math.PI / 2 + offset * 0.3 : -Math.PI / 2 + offset * 0.3]}
|
||||||
>
|
>
|
||||||
<cylinderGeometry args={[0.004, 0.004, 0.64, 4]} />
|
<cylinderGeometry args={[0.004, 0.004, 0.64, 4]} />
|
||||||
@@ -172,7 +200,8 @@ export function CellDivisionScene({ stage }: { stage: Stage }) {
|
|||||||
position: new THREE.Vector3(0, 0, 0),
|
position: new THREE.Vector3(0, 0, 0),
|
||||||
radius: { value: 0 },
|
radius: { value: 0 },
|
||||||
envelope: { value: 0 },
|
envelope: { value: 0 },
|
||||||
spindle: { value: 0 },
|
centrosomes: { value: 0 },
|
||||||
|
fibers: { value: 0 },
|
||||||
elongated: { value: 0 },
|
elongated: { value: 0 },
|
||||||
})),
|
})),
|
||||||
[],
|
[],
|
||||||
|
|||||||
@@ -28,7 +28,11 @@ export interface CellTarget {
|
|||||||
center: [number, number, number];
|
center: [number, number, number];
|
||||||
radius: number;
|
radius: number;
|
||||||
envelope: number; // opacidade do envelope nuclear (0 = dissolvido, 1 = intacto)
|
envelope: number; // opacidade do envelope nuclear (0 = dissolvido, 1 = intacto)
|
||||||
spindle: boolean; // mostra fuso mitótico (centrossomos + fibras) neste estágio
|
spindle: boolean; // mostra o fuso mitótico completo (centrossomos + fibras) neste estágio
|
||||||
|
// Mostra só os 2 centrossomos, sem fibras — a duplicação deles termina
|
||||||
|
// na G2, antes do fuso de verdade se formar na prófase. Opcional porque
|
||||||
|
// só a G2 precisa disso; `spindle: true` já implica centrossomos visíveis.
|
||||||
|
centrosomes?: boolean;
|
||||||
elongated: number; // 0 = esférica, 1 = alongada com sulco de clivagem (citocinese em andamento)
|
elongated: number; // 0 = esférica, 1 = alongada com sulco de clivagem (citocinese em andamento)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +66,21 @@ function single(id: string, color: string, cell: number, pos: [number, number, n
|
|||||||
return { id, color, cell, pos, rot };
|
return { id, color, cell, pos, rot };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cromossomo AINDA NÃO duplicado (G1, antes da fase S): as duas
|
||||||
|
// cromátides-irmãs existem como entidades (o sistema de animação espera
|
||||||
|
// as 8 IDs em todo estágio — ver CellDivisionScene.tsx), mas ficam na
|
||||||
|
// MESMA posição E MESMA rotação, uma exatamente em cima da outra —
|
||||||
|
// visualmente indistinguíveis de um cromossomo único. Quando o estágio
|
||||||
|
// seguinte (fase S) muda a rotação da cromátide "b" pra 180°, ela
|
||||||
|
// "gira pra fora" de trás da outra — a duplicação do DNA acontecendo
|
||||||
|
// diante dos olhos, não só descrita no texto.
|
||||||
|
function unduplicated(idA: string, idB: string, color: string, cell: number, pos: [number, number, number]): ChromatidTarget[] {
|
||||||
|
return [
|
||||||
|
{ id: idA, color, cell, pos, rot: 0 },
|
||||||
|
{ id: idB, color, cell, pos, rot: 0 },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// ============================= MITOSE ===================================
|
// ============================= MITOSE ===================================
|
||||||
// As 4 cromátides-irmãs (uma de cada cromossomo) vão pro polo A, as outras
|
// As 4 cromátides-irmãs (uma de cada cromossomo) vão pro polo A, as outras
|
||||||
// 4 pro polo B — as duas células-filhas ficam geneticamente IDÊNTICAS à
|
// 4 pro polo B — as duas células-filhas ficam geneticamente IDÊNTICAS à
|
||||||
@@ -69,11 +88,37 @@ function single(id: string, color: string, cell: number, pos: [number, number, n
|
|||||||
|
|
||||||
export const MITOSIS_STAGES: Stage[] = [
|
export const MITOSIS_STAGES: Stage[] = [
|
||||||
{
|
{
|
||||||
id: "interfase",
|
id: "interfase-g1",
|
||||||
label: "Interfase",
|
label: "Interfase — G1",
|
||||||
description:
|
description:
|
||||||
"A célula não está se dividindo: cresce e, na fase S, duplica todo o seu DNA. Os cromossomos já estão duplicados, mas ainda descondensados (finos, dispersos) — por isso não aparecem como bastões nítidos ainda.",
|
"A célula recém-formada cresce e funciona normalmente. Cada cromossomo ainda tem só 1 cromátide (não duplicado) — é o estado em que a célula passa a maior parte da vida, antes de se preparar pra dividir.",
|
||||||
cells: [{ center: [0, 0, 0], radius: R, envelope: 1, spindle: false, elongated: 0 }],
|
cells: [{ center: [0, 0, 0], radius: R, envelope: 1, spindle: false, elongated: 0 }],
|
||||||
|
chromatids: [
|
||||||
|
...unduplicated("b1a", "b1b", COLOR_B, 0, [-0.28, 0.22, 0.1]),
|
||||||
|
...unduplicated("c1a", "c1b", COLOR_C, 0, [0.05, 0.3, -0.15]),
|
||||||
|
...unduplicated("o1a", "o1b", COLOR_O, 0, [0.25, -0.15, 0.2]),
|
||||||
|
...unduplicated("y1a", "y1b", COLOR_Y, 0, [-0.1, -0.28, -0.1]),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "interfase-s",
|
||||||
|
label: "Interfase — Fase S",
|
||||||
|
description:
|
||||||
|
"O momento-chave da interfase: na fase S (\"síntese\"), a célula duplica TODO o seu DNA — cada cromossomo passa a ter 2 cromátides-irmãs idênticas, unidas pelo centrômero (o \"X\"). Sem essa duplicação, a mitose não teria DNA suficiente pra dar 1 cópia completa a cada célula-filha. Os cromossomos continuam descondensados (finos, dispersos) — ainda não dá pra vê-los como bastões nítidos.",
|
||||||
|
cells: [{ center: [0, 0, 0], radius: R, envelope: 1, spindle: false, elongated: 0 }],
|
||||||
|
chromatids: [
|
||||||
|
...pair("b1a", "b1b", COLOR_B, 0, [-0.28, 0.22, 0.1]),
|
||||||
|
...pair("c1a", "c1b", COLOR_C, 0, [0.05, 0.3, -0.15]),
|
||||||
|
...pair("o1a", "o1b", COLOR_O, 0, [0.25, -0.15, 0.2]),
|
||||||
|
...pair("y1a", "y1b", COLOR_Y, 0, [-0.1, -0.28, -0.1]),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "interfase-g2",
|
||||||
|
label: "Interfase — G2",
|
||||||
|
description:
|
||||||
|
"A célula continua crescendo e confere/repara o DNA recém-duplicado antes de seguir em frente — se o DNA estiver com erro grave demais pra corrigir, a divisão pode ser interrompida aqui. É também na G2 que os centrossomos (já duplicados) terminam de se preparar — por isso aparecem 2 pela primeira vez, ainda sem fibras.",
|
||||||
|
cells: [{ center: [0, 0, 0], radius: R, envelope: 1, spindle: false, centrosomes: true, elongated: 0 }],
|
||||||
chromatids: [
|
chromatids: [
|
||||||
...pair("b1a", "b1b", COLOR_B, 0, [-0.28, 0.22, 0.1]),
|
...pair("b1a", "b1b", COLOR_B, 0, [-0.28, 0.22, 0.1]),
|
||||||
...pair("c1a", "c1b", COLOR_C, 0, [0.05, 0.3, -0.15]),
|
...pair("c1a", "c1b", COLOR_C, 0, [0.05, 0.3, -0.15]),
|
||||||
@@ -186,11 +231,37 @@ export const MITOSIS_STAGES: Stage[] = [
|
|||||||
|
|
||||||
export const MEIOSIS_STAGES: Stage[] = [
|
export const MEIOSIS_STAGES: Stage[] = [
|
||||||
{
|
{
|
||||||
id: "interfase",
|
id: "interfase-g1",
|
||||||
label: "Interfase",
|
label: "Interfase — G1",
|
||||||
description:
|
description:
|
||||||
"Igual à mitose: a célula duplica todo o seu DNA na fase S. Os cromossomos já duplicados continuam descondensados.",
|
"Igual à mitose: a célula cresce e funciona normalmente, com cada cromossomo ainda numa única cromátide (não duplicado).",
|
||||||
cells: [{ center: [0, 0, 0], radius: R, envelope: 1, spindle: false, elongated: 0 }],
|
cells: [{ center: [0, 0, 0], radius: R, envelope: 1, spindle: false, elongated: 0 }],
|
||||||
|
chromatids: [
|
||||||
|
...unduplicated("b1a", "b1b", COLOR_B, 0, [-0.28, 0.22, 0.1]),
|
||||||
|
...unduplicated("c1a", "c1b", COLOR_C, 0, [0.05, 0.3, -0.15]),
|
||||||
|
...unduplicated("o1a", "o1b", COLOR_O, 0, [0.25, -0.15, 0.2]),
|
||||||
|
...unduplicated("y1a", "y1b", COLOR_Y, 0, [-0.1, -0.28, -0.1]),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "interfase-s",
|
||||||
|
label: "Interfase — Fase S",
|
||||||
|
description:
|
||||||
|
"Igual à mitose: na fase S, a célula duplica TODO o seu DNA antes de entrar em meiose — cada cromossomo passa a ter 2 cromátides-irmãs. Isso é o que permite que, mesmo depois de DUAS divisões (Meiose I e II), cada gameta final ainda receba 1 cromátide completa. Os cromossomos continuam descondensados por enquanto.",
|
||||||
|
cells: [{ center: [0, 0, 0], radius: R, envelope: 1, spindle: false, elongated: 0 }],
|
||||||
|
chromatids: [
|
||||||
|
...pair("b1a", "b1b", COLOR_B, 0, [-0.28, 0.22, 0.1]),
|
||||||
|
...pair("c1a", "c1b", COLOR_C, 0, [0.05, 0.3, -0.15]),
|
||||||
|
...pair("o1a", "o1b", COLOR_O, 0, [0.25, -0.15, 0.2]),
|
||||||
|
...pair("y1a", "y1b", COLOR_Y, 0, [-0.1, -0.28, -0.1]),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "interfase-g2",
|
||||||
|
label: "Interfase — G2",
|
||||||
|
description:
|
||||||
|
"Igual à mitose: a célula confere/repara o DNA duplicado e termina de preparar os centrossomos (já duplicados, por isso aparecem 2 pela primeira vez) antes de entrar na Prófase I.",
|
||||||
|
cells: [{ center: [0, 0, 0], radius: R, envelope: 1, spindle: false, centrosomes: true, elongated: 0 }],
|
||||||
chromatids: [
|
chromatids: [
|
||||||
...pair("b1a", "b1b", COLOR_B, 0, [-0.28, 0.22, 0.1]),
|
...pair("b1a", "b1b", COLOR_B, 0, [-0.28, 0.22, 0.1]),
|
||||||
...pair("c1a", "c1b", COLOR_C, 0, [0.05, 0.3, -0.15]),
|
...pair("c1a", "c1b", COLOR_C, 0, [0.05, 0.3, -0.15]),
|
||||||
|
|||||||
Reference in new issue
Block a user