diff --git a/examples/case04/Readme.html b/examples/case04/Readme.html
index 69c5fd9..4c2e8cf 100644
--- a/examples/case04/Readme.html
+++ b/examples/case04/Readme.html
@@ -250,7 +250,20 @@ MathJax = {
-3.2 偏心率定义
+3.2 月球绕地球轨道
+
+拖动下方滑块改变月球轨道偏心率 $e_\text{moon}$(真实值 0.0549):
+
+
+
+
+
+
+
+
+
+
+3.3 偏心率定义
偏心率 $e$ 描述椭圆轨道偏离正圆的程度:
@@ -263,12 +276,12 @@ MathJax = {
| $e$ 值 | 轨道形状 | 说明 |
| $e = 0$ | 正圆形 | 速度恒定,距离恒定 |
- | $0 < e < 1$ | 椭圆 | 近日点速度最大,远日点速度最小 |
+ | $0 < e < 1$ | 椭圆 | 近日点/近地点速度最大,远日点/远地点速度最小 |
| $e = 1$ | 抛物线 | 逃逸轨道,速度恰好达到逃逸速度 |
| $e > 1$ | 双曲线 | 飞越轨道,速度超过逃逸速度 |
-
3.3 半长轴与半短轴的关系
+
3.4 半长轴与半短轴的关系
-
3.4 近日点与远日点
+
3.5 近日点与远日点
近日点(距太阳最近)和远日点(距太阳最远)的距离分别为:
@@ -291,7 +304,7 @@ MathJax = {
-
3.5 开普勒三大定律
+
3.6 开普勒三大定律
- 椭圆定律:行星轨道是椭圆,太阳位于椭圆的一个焦点上。
@@ -587,6 +600,221 @@ MathJax = {
slider.addEventListener('input', update);
update();
})();
+
+// ── 月球绕地球轨道图 ──
+(function() {
+ var canvas = document.getElementById('moonCanvas');
+ var ctx = canvas.getContext('2d');
+ var slider = document.getElementById('moonESlider');
+ var eDisplay = document.getElementById('moonEDisplay');
+ var infoDiv = document.getElementById('moonInfo');
+
+ var W = 760, H = 400;
+ var cx = 380, cy = 200;
+ var A = 140;
+
+ function draw(e) {
+ ctx.clearRect(0, 0, W, H);
+
+ var b = A * Math.sqrt(1 - e * e);
+ var f = e * A;
+
+ // 长轴辅助线
+ ctx.beginPath();
+ ctx.moveTo(cx - A - 20, cy);
+ ctx.lineTo(cx + A + 20, cy);
+ ctx.strokeStyle = '#30363d';
+ ctx.lineWidth = 0.5;
+ ctx.setLineDash([4, 3]);
+ ctx.stroke();
+ ctx.setLineDash([]);
+
+ // 椭圆轨道(中心在 cx+f,左焦点=cx 为地球)
+ ctx.beginPath();
+ ctx.ellipse(cx + f, cy, A, b, 0, 0, Math.PI * 2);
+ ctx.strokeStyle = '#7ee787';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+
+ // 半长轴 a(标注线,从椭圆中心到右顶点)
+ var aY = cy + 28;
+ ctx.beginPath();
+ ctx.moveTo(cx + f, aY);
+ ctx.lineTo(cx + f + A, aY);
+ ctx.strokeStyle = '#c9d1d9';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.moveTo(cx + f + 6, aY - 4);
+ ctx.lineTo(cx + f, aY);
+ ctx.lineTo(cx + f + 6, aY + 4);
+ ctx.strokeStyle = '#c9d1d9';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.moveTo(cx + f + A - 6, aY - 4);
+ ctx.lineTo(cx + f + A, aY);
+ ctx.lineTo(cx + f + A - 6, aY + 4);
+ ctx.strokeStyle = '#c9d1d9';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.fillStyle = '#c9d1d9';
+ ctx.font = '13px "Segoe UI", Arial, sans-serif';
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'top';
+ ctx.fillText('a = ' + A.toFixed(0), cx + f + A/2, aY + 6);
+
+ // 偏心距 c = ea(从左焦点=地球 到椭圆中心)
+ var cY = cy - b - 20;
+ ctx.beginPath();
+ ctx.moveTo(cx, cY);
+ ctx.lineTo(cx + f, cY);
+ ctx.strokeStyle = '#d29922';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.moveTo(cx + 5, cY - 4);
+ ctx.lineTo(cx, cY);
+ ctx.lineTo(cx + 5, cY + 4);
+ ctx.strokeStyle = '#d29922';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.moveTo(cx + f - 5, cY - 4);
+ ctx.lineTo(cx + f, cY);
+ ctx.lineTo(cx + f - 5, cY + 4);
+ ctx.strokeStyle = '#d29922';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.fillStyle = '#d29922';
+ ctx.font = '13px "Segoe UI", Arial, sans-serif';
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'bottom';
+ ctx.fillText('c = ea = ' + f.toFixed(1), cx + f/2, cY - 4);
+
+ // 半短轴 b 标注(从椭圆中心到上顶点)
+ var bX = cx + f + A + 18;
+ ctx.beginPath();
+ ctx.moveTo(bX, cy);
+ ctx.lineTo(bX, cy - b);
+ ctx.strokeStyle = '#3fb950';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.moveTo(bX - 4, cy - 6);
+ ctx.lineTo(bX, cy);
+ ctx.lineTo(bX + 4, cy - 6);
+ ctx.strokeStyle = '#3fb950';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.moveTo(bX - 4, cy - b + 6);
+ ctx.lineTo(bX, cy - b);
+ ctx.lineTo(bX + 4, cy - b + 6);
+ ctx.strokeStyle = '#3fb950';
+ ctx.lineWidth = 1.5;
+ ctx.stroke();
+ ctx.fillStyle = '#3fb950';
+ ctx.font = '13px "Segoe UI", Arial, sans-serif';
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'middle';
+ ctx.fillText('b = ' + b.toFixed(1), bX + 8, cy - b/2);
+
+ // 地球(左焦点)
+ ctx.beginPath();
+ ctx.arc(cx, cy, 8, 0, Math.PI * 2);
+ ctx.fillStyle = '#58a6ff';
+ ctx.fill();
+ ctx.strokeStyle = '#1f6feb';
+ ctx.lineWidth = 1;
+ ctx.stroke();
+ ctx.fillStyle = '#f0f6fc';
+ ctx.font = '13px "Segoe UI", Arial, sans-serif';
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'bottom';
+ ctx.fillText('地球(左焦点)', cx, cy - 14);
+
+ // 近地点(左顶点:距地球最近)
+ var periX = cx + f - A;
+ ctx.fillStyle = '#7ee787';
+ ctx.beginPath();
+ ctx.arc(periX, cy, 4, 0, Math.PI * 2);
+ ctx.fill();
+ ctx.fillStyle = '#8b949e';
+ ctx.font = '12px "Segoe UI", Arial, sans-serif';
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'top';
+ ctx.fillText('近地点 r = a(1-e) = ' + (A * (1 - e)).toFixed(1), periX, cy + 12);
+
+ // 远地点(右顶点:距地球最远)
+ var apX = cx + f + A;
+ ctx.fillStyle = '#7ee787';
+ ctx.beginPath();
+ ctx.arc(apX, cy, 4, 0, Math.PI * 2);
+ ctx.fill();
+ ctx.fillStyle = '#8b949e';
+ ctx.font = '12px "Segoe UI", Arial, sans-serif';
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'top';
+ ctx.fillText('远地点 r = a(1+e) = ' + (A * (1 + e)).toFixed(1), apX, cy + 12);
+
+ // 月球(轨道上的点)
+ var angle = 0.6;
+ var mx = cx + f + A * Math.cos(angle);
+ var my = cy - b * Math.sin(angle);
+ ctx.beginPath();
+ ctx.arc(mx, my, 4, 0, Math.PI * 2);
+ ctx.fillStyle = '#e2e8f0';
+ ctx.fill();
+ ctx.strokeStyle = '#8b949e';
+ ctx.lineWidth = 0.5;
+ ctx.stroke();
+ ctx.fillStyle = '#e2e8f0';
+ ctx.font = '12px "Segoe UI", Arial, sans-serif';
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'bottom';
+ ctx.fillText('月球', mx + 8, my);
+
+ // 速度矢量
+ var vlen = 32;
+ var vx = -A * Math.sin(angle) * 0.7;
+ var vy = b * Math.cos(angle) * 0.7;
+ var vl = Math.sqrt(vx*vx + vy*vy);
+ if (vl > 0) { vx = vx/vl*vlen; vy = vy/vl*vlen; }
+ ctx.beginPath();
+ ctx.moveTo(mx, my);
+ ctx.lineTo(mx + vx, my + vy);
+ ctx.strokeStyle = '#3fb950';
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ var tipX = mx + vx, tipY = my + vy;
+ ctx.beginPath();
+ ctx.moveTo(tipX, tipY);
+ ctx.lineTo(tipX - vx*0.3 + vy*0.15, tipY - vy*0.3 - vx*0.15);
+ ctx.lineTo(tipX - vx*0.3 - vy*0.15, tipY - vy*0.3 + vx*0.15);
+ ctx.closePath();
+ ctx.fillStyle = '#3fb950';
+ ctx.fill();
+
+ // 信息面板
+ var roundE = Math.round(e * 10000) / 10000;
+ infoDiv.innerHTML =
+ '椭圆轨道 e = ' + roundE.toFixed(4) + '' +
+ '偏心距 c = ' + f.toFixed(1) + '' +
+ 'b/a = ' + (b / A).toFixed(4) + '' +
+ '近地点 ' + (A * (1 - e)).toFixed(1) + ' / 远地点 ' + (A * (1 + e)).toFixed(1) + '';
+ }
+
+ function update() {
+ var val = parseInt(slider.value);
+ var e = val / 1000;
+ eDisplay.textContent = e.toFixed(4);
+ draw(e);
+ }
+
+ slider.addEventListener('input', update);
+ update();
+})();