'use client'; import React, { useState, useEffect, useRef, useMemo } from 'react'; export default function OpticalImagingAnimation() { const VIEW_WIDTH = 1000; const VIEW_HEIGHT = 600; const CENTER_X = VIEW_WIDTH / 2; const CENTER_Y = VIEW_HEIGHT / 2; // Optical Constants const FOCAL_LENGTH = 120; // Focal length (f) const OBJ_HEIGHT = 80; // Height of the object // Animation State const [time, setTime] = useState(0); // Animation Loop useEffect(() => { let animationFrameId: number; const animate = () => { setTime(t => t + 0.005); animationFrameId = requestAnimationFrame(animate); }; animationFrameId = requestAnimationFrame(animate); return () => cancelAnimationFrame(animationFrameId); }, []); // Calculate dynamic physics // Oscillate object distance (u) between 1.5f and 3.5f const u = 250 + Math.sin(time) * 90; // Object distance from lens center // Lens Equation: 1/f = 1/u + 1/v => v = (u * f) / (u - f) const v = (u * FOCAL_LENGTH) / (u - FOCAL_LENGTH); // Image distance // Magnification: m = -v/u const m = -v / u; const imgHeight = OBJ_HEIGHT * m; // Negative means inverted // Coordinates const objX = CENTER_X - u; const objY = CENTER_Y - OBJ_HEIGHT; const imgX = CENTER_X + v; const imgY = CENTER_Y - imgHeight; // Note: imgHeight is negative, so this adds to Y // Ray 1: Parallel to axis -> Refracts through Focal Point (F) const ray1Path = ` M ${objX},${objY} L ${CENTER_X},${objY} L ${imgX},${imgY} L ${imgX + (imgX - CENTER_X) * 0.2},${imgY + (imgY - CENTER_Y) * 0.2} `; // Ray 2: Through Optical Center (O) -> No refraction const ray2Path = ` M ${objX},${objY} L ${imgX},${imgY} L ${imgX + (imgX - objX) * 0.1},${imgY + (imgY - objY) * 0.1} `; // Ray 3: Through Focal Point (F') -> Refracts Parallel const ray3Path = ` M ${objX},${objY} L ${CENTER_X},${imgY} L ${imgX},${imgY} L ${imgX + 100},${imgY} `; // Formatting numbers const formatNum = (n: number) => Math.abs(n).toFixed(0); const formatMag = (n: number) => Math.abs(n).toFixed(2); return ( {/* Glow Filters */} {/* Gradients */} {/* --- Background Grid & Axis --- */} {Array.from({ length: 20 }).map((_, i) => ( ))} {Array.from({ length: 12 }).map((_, i) => ( ))} {/* Principal Axis */} {/* --- The Lens --- */} {/* Glass Body */} {/* Reflection Highlights */} 凸透镜 (Convex Lens) {/* --- Focal Points --- */} {[-1, 1].map((dir) => ( F {FOCAL_LENGTH}px ))} {/* --- Light Rays --- */} {/* Ray 1 (Parallel -> Focus) */} {/* Ray 2 (Center) */} {/* Ray 3 (Focus -> Parallel) */} {/* Photon Particles */} {/* --- Object (Candle/Arrow) --- */} {/* Object Body */} {/* Base */} {/* Label */} 物体 (Object) {/* Distance Line */} u = {formatNum(u)} {/* --- Image (Inverted) --- */} {/* Image Body (Ghostly) */} {/* Arrow Head Simulation */} 0 ? -10 : 10)} L 0 ${-imgHeight} L 5 ${-imgHeight + (imgHeight > 0 ? -10 : 10)}`} fill="none" stroke="#10b981" strokeWidth="3" /> {/* Label */} 实像 (Real Image) {/* Distance Line */} v = {formatNum(v)} {/* --- Dashboard / Info Panel --- */} 成像参数 (Parameters) 焦距 (f): {FOCAL_LENGTH} 物距 (u): {formatNum(u)} 像距 (v): {formatNum(v)} 放大率 (m): {formatMag(m)}x 性质: 倒立实像 {/* --- Diagram Labels --- */} 凸透镜成像原理 / Convex Lens Imaging ); }