mitose e meiose interfase

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo@martinsevieira.adv.br>
This commit is contained in:
Rodrigo Bertoldo de Sousa Martins committed 2026-09-17 12:39:56 -03:00
1 parent 734b967f11
commit efb57d9e38
2 files changed
+123 -23

No files matched your search

@@ -75,7 +75,8 @@ interface CellSlotState {
position: THREE.Vector3;
radius: { value: number };
envelope: { value: number };
spindle: { value: number };
centrosomes: { value: number };
fibers: { value: number };
elongated: { value: number };
}
@@ -83,27 +84,41 @@ function AnimatedCellSlot({
target,
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;
}) {
const groupRef = useRef<THREE.Group>(null);
const membraneRef = useRef<THREE.Mesh>(null);
const membraneMatRef = 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) => {
const k = smoothing(delta);
const targetPos = target ? new THREE.Vector3(...target.center) : state.position.clone();
const targetRadius = target ? target.radius : 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;
state.position.lerp(targetPos, k);
state.radius.value = THREE.MathUtils.lerp(state.radius.value, targetRadius, 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);
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 (envelopeMatRef.current) envelopeMatRef.current.opacity = state.envelope.value * 0.35;
if (spindleRef.current) spindleRef.current.visible = state.spindle.value > 0.05;
if (spindleRef.current) spindleRef.current.scale.setScalar(state.spindle.value);
if (centrosomesRef.current) {
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 (
@@ -137,18 +158,25 @@ function AnimatedCellSlot({
<sphereGeometry args={[0.42, 24, 24]} />
<meshStandardMaterial ref={envelopeMatRef} color="#c4b5fd" transparent opacity={0} depthWrite={false} />
</mesh>
{/* fuso mitótico: 2 centrossomos + fibras finas em leque */}
<group ref={spindleRef}>
{/* Centrossomos — visíveis sozinhos na G2 (recém-duplicados, ainda
sem fibra nenhuma) e continuam visíveis junto do fuso a partir
da prófase. */}
<group ref={centrosomesRef}>
{[-1, 1].map((side) => (
<group key={side} position={[side * 0.65, 0, 0]}>
<mesh>
<sphereGeometry args={[0.035, 10, 10]} />
<meshStandardMaterial color="#f8fafc" />
</mesh>
<mesh key={side} position={[side * 0.65, 0, 0]}>
<sphereGeometry args={[0.035, 10, 10]} />
<meshStandardMaterial color="#f8fafc" />
</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) => (
<mesh
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]}
>
<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),
radius: { value: 0 },
envelope: { value: 0 },
spindle: { value: 0 },
centrosomes: { value: 0 },
fibers: { value: 0 },
elongated: { value: 0 },
})),
[],