from manim import *
import numpy as np
config.background_color='#10263d'
FONT='Microsoft YaHei'
class EkmanExplanation(Scene):
 def label(self,zh,en,size=28,color=WHITE):
  return VGroup(Text(zh,font=FONT,font_size=size,color=color),Text(en,font=FONT,font_size=size*.56,color='#bcd5ed')).arrange(DOWN,buff=.13)
 def title(self,zh,en):
  t=self.label(zh,en,34).to_edge(UP,buff=.3);self.play(FadeIn(t));return t
 def caption(self,zh,en):
  c=self.label(zh,en,24).to_edge(DOWN,buff=.3);self.play(FadeIn(c));return c
 def clear_scene(self):self.play(*[FadeOut(m) for m in list(self.mobjects)],run_time=.6)
 def construct(self):
  self.title('艾克曼：风怎样推动海洋？','Ekman dynamics: how does wind drive the ocean?')
  ocean=Rectangle(width=11,height=2.7,fill_color=BLUE_E,fill_opacity=.5,stroke_color=BLUE_B).shift(DOWN*.4)
  wind=Arrow(LEFT*3+UP*1.5,RIGHT*3+UP*1.5,color=YELLOW,buff=0)
  w=self.label('风应力 →','Wind stress',25,YELLOW).next_to(wind,UP,buff=.15)
  self.play(Create(ocean),GrowArrow(wind),FadeIn(w))
  arrows=VGroup(*[Arrow(LEFT*3+DOWN*(.1+i*.5),LEFT*3+RIGHT*(3-i*.55)+DOWN*(.1+i*.5),color=BLUE_A,buff=0) for i in range(4)])
  self.play(LaggedStart(*[GrowArrow(a) for a in arrows],lag_ratio=.3))
  self.caption('风输入动量；湍流应力把动量向下传递','Wind supplies momentum; turbulent stress transfers it downward.')
  self.wait(5)
  self.clear_scene()
  self.title('不同深度，不同流向','Different depths, different current directions')
  origin=LEFT*3+DOWN*.2
  circle=Circle(radius=2,color='#35536c').move_to(origin)
  wind=Arrow(origin,origin+UP*2.3,color=YELLOW,buff=0)
  self.play(Create(circle),GrowArrow(wind))
  self.add(self.label('北 / N','Wind northward',18,YELLOW).move_to(origin+UP*2.55))
  info=self.label('北半球 · 俯视图','Northern Hemisphere · top view',25).move_to(RIGHT*3+UP*1.6);self.play(FadeIn(info))
  arrows=VGroup()
  for i,d in enumerate(np.linspace(0,2.5,9)):
   theta=PI/4-d;end=origin+2.3*np.exp(-d)*np.array([np.cos(theta),np.sin(theta),0])
   a=Arrow(origin,end,buff=0,color=interpolate_color(TEAL_A,BLUE_E,i/8),max_tip_length_to_length_ratio=.22,stroke_width=5)
   arrows.add(a);self.play(GrowArrow(a),run_time=.45)
  expl=self.label('越深：流速越弱，方向逐渐右转','Deeper: weaker speed and clockwise rotation',23).move_to(RIGHT*3+UP*.1)
  note=self.label('表层约偏右 45°','Surface: about 45° right of wind',24,TEAL_A).move_to(RIGHT*3+DOWN*1.25)
  self.play(FadeIn(expl),FadeIn(note))
  self.caption('箭头代表不同深度的速度，不是粒子的螺旋轨迹','Arrows show velocity at different depths, not a spiralling particle path.')
  self.wait(6);self.clear_scene()
  self.title('把整层流动相加：艾克曼输运','Depth-integrated flow: Ekman transport')
  for x,sign,zh,en in [(-3,1,'北半球：偏右 90°','Northern Hemisphere: 90° right'),(3,-1,'南半球：偏左 90°','Southern Hemisphere: 90° left')]:
   org=np.array([x,-.5,0]);wind=Arrow(org,org+UP*2,color=YELLOW,buff=0);net=Arrow(org,org+RIGHT*sign*2,color=GREEN_A,buff=0)
   self.play(GrowArrow(wind));self.play(GrowArrow(net))
   self.add(self.label(zh,en,23).move_to([x,-1.6,0]))
  f=self.label('M = ∫ u dz     |M| = |τ| / (ρ |f|)','Volume transport per unit width: m²/s',26).move_to(UP*1.9);self.play(FadeIn(f))
  self.caption('黄色：向北的风应力；绿色：净输运方向','Yellow: northward wind stress. Green: net transport.')
  self.wait(7);self.clear_scene()
  self.title('近岸应用：离岸输运与上升流','Coastal application: offshore transport and upwelling')
  land=Rectangle(width=1.5,height=3.4,fill_color='#b7a582',fill_opacity=1,stroke_width=0).move_to(RIGHT*4)
  sea=Rectangle(width=8,height=3.4,fill_color=BLUE_E,fill_opacity=.5,stroke_width=0).move_to(LEFT*.75)
  self.play(FadeIn(sea),FadeIn(land))
  self.add(self.label('海洋','Ocean',22).move_to(LEFT*3+DOWN),self.label('陆地','Land',22).move_to(RIGHT*4))
  transport=Arrow(RIGHT*2.8+UP*.9,LEFT*2+UP*.9,color=GREEN_A,buff=0)
  up=Arrow(RIGHT*2+DOWN*1.4,RIGHT*2+UP*.6,color=TEAL_A,buff=0)
  self.play(GrowArrow(transport));self.play(GrowArrow(up))
  self.add(self.label('离岸输运','Offshore transport',22,GREEN_A).move_to(LEFT*.5+UP*1.5))
  self.caption('沿岸风使表层水离岸，深层水上升补充（剖面示意）','Alongshore winds drive offshore flow; deeper water rises to replace it.')
  self.wait(6);self.clear_scene()
  self.title('记住方向，也记住条件','Remember the directions—and the assumptions')
  lines=VGroup(self.label('北半球右偏；南半球左偏','Right in the Northern Hemisphere; left in the Southern Hemisphere',26),self.label('经典螺旋：定常、深水、恒定涡黏性、远离赤道','Classical spiral: steady, deep water, constant eddy viscosity, away from equator',24),self.label('真实表层偏角会变化；净输运与单层速度不同','Real surface angles vary; integrated transport differs from layer velocity',24)).arrange(DOWN,buff=.55).shift(DOWN*.1)
  self.play(LaggedStart(*[FadeIn(m) for m in lines],lag_ratio=.4))
  self.caption('理想化教学动画 · 作者：邹乔木','Idealized teaching animation · Author: Zou Qiaomu')
  self.wait(7)
