地球上の夜の領域をGeoJSON化するにおいて、
kが0以外のときはニュートン法やはさみうち法で求めることになる。
としたが、それだとうまくいかないケースに遭遇したので、解き方を見直す。
薄明方程式の再掲
f=sin(δ)sin(ϕ)+cos(δ)cos(ϕ)cos(t)−sin(k)=0
δは太陽の赤緯で、境界線を求める時刻により決まる。
ϕは境界線上の点の緯度。
tは境界線上の点の時角で、経度によりで決まる。
kは太陽の出没高度で、夜側に光がどれくらい回り込むかを決める変数。
この方程式を、経度を-180degから180degまで変化させながら緯度ϕを計算することで、昼と夜の境界線を求めることができる。
k=0のとき
k=0 のときは式変形すると、
ϕ=arctan(−cos(t)/arctan(δ))
となり解析解が求まる。
なお、δ=0 のとき薄明方程式は cos(ϕ)cos(t)=0 となり、ϕ=0 に定まる。
それ以外
kが0以外のときは、ニュートン法やはさみうち法で求めることになる。 としていたが、数値解析ではうまくいかない場合がある。

例えばこういうときで、影の領域が円を描く=1つの経度に対して解が2つある。
数値解析の代わりに sin(ϕ) か cos(ϕ) を x として ax2+bx+c=0 の二次方程式の解を求める。
−90deg<=ϕ<=90deg なことから x=sin(ϕ) 、 1−x2=cos(ϕ) とすれば、薄明方程式は次の形になる。
cos(δ)cos(t)1−x2=−sin(δ)x+sin(k)
よって、A=cos(δ)cos(t)、B=−sin(δ)、C=sin(k)、D=A2+B2−C2 とすれば
x=(−B∗C±A∗D)/(A2+B2)
となる。
ただし、δ=±90deg(A=0) かつ (Bx+C)/A>0 を満たすものとする。
なお、δ=±90deg(A=0) のときは、 x=−C/B となる。
他の考慮点
影の領域が円を描く場合は、180度線をまたぐ際に分割されるため、PolygonではなくMultiPolygonを求めるようにする。
高度k は厳密には大気屈折 E=0.035°H と 視差 Π=0.0024°/r を考慮する必要がある。
市民薄明の例
k=−6°−E+Π
しかし大気屈折は高度Hの関数で、高度を考慮しない場合は0となる。
視差は地球と太陽の距離の天文単位rの関数だが、ほぼ1であり視差は十分に小さいものであり、考慮しないでよいケースがほとんどだろう。
https://github.com/yonda-yonda/geo4326/blob/master/src/terminator.ts
Discussion