earth globe

天文算法9

第十一章 地球球体 The Earth’s Globe

1. 椭球体

  天文学上,通常我们将地球看做一个近似的椭球体。如下图, 所以子午圈截面为一个椭圆。如下图,   假设上图中$C$为地心,$N$为北极,$S$为南极,$CF$为赤道半径,$NC = b, CF = a$,$O$为观察点,$HK$为地平面,$OP\perp HK$,$OM//SN$,$OM$与$OH$的夹角是$φ$,$CF$与$CO$的夹角是$φ’$,$CO$的长度为$\rho$
  则$φ$为$O$点的地理纬度,$\angle OPF = φ$,$φ’$为$O$点的地心纬度,$\rho$为$O$点的地心半径,在极点和赤道上$φ=φ′$,在其它纬度上$|φ′|<|φ|$
  地心纬度$φ’$与地理纬度$φ$的关系为:$\tan φ′=\frac {b^2}{a^2} \tan φ,$(推导)
  由椭球体扁率$f=\frac {a-b}a$,可知$b=a(1-f)$,子午圈椭圆离心率 \begin{align} e &= \frac ca\\[2ex] & = \frac {\sqrt {a^2-b^2}}{a}\\[2ex] & = \sqrt {2f-f^2} \end{align}   地心纬度$φ’$对应的归化纬度$u$,有 \begin{cases} \tan φ’ = \frac ba \tan u\\[2ex] \tan u = \frac ba \tan φ\\[2ex] \end{cases} 且 \begin{cases} \rho \cos φ’ = a\cos u, \ (相当于子午圈椭圆上观察点O的x坐标)\\[2ex] \rho \sin φ’ = b\sin u, \ (相当于子午圈椭圆上观察点O的y坐标) \end{cases}   如果观察点的海拔高度为$H$,且$\rho$以赤道半径$a$为单位,则有 \begin{cases} \rho \cos φ’ = cos u + \frac Ha\cos φ\\[2ex] \rho \sin φ’ = \frac ba\sin u + \frac Ha\sin φ \end{cases}

// Ellipsoid represents an ellipsoid of revolution.
//
// Typical unit for Er is Km.
// 地球椭球体
type Ellipsoid struct {
	Er float64 // equatorial radius 赤道半径
	Fl float64 // flattening 地球扁率
}

// IAU 1976 values.  Radius in Km.
var Earth76 = Ellipsoid{Er: 6378.14, Fl: 1 / 298.257}

// A returns equatorial radius in units of e.Er.
//
// A is a common identifier for equatorial radius.
// 子午圈椭圆长半轴(赤道半径)
func (e Ellipsoid) A() float64 {
	return e.Er
}

// B returns polar radius in units of e.ER.
//
// B is a common identifier for polar radius.
//
// 子午圈椭圆短半轴(地心到极点的距离)
func (e Ellipsoid) B() float64 {
	return e.Er * (1 - e.Fl)
}

// Eccentricity of a meridian.
// 子午圈椭圆离心率
func (e Ellipsoid) Eccentricity() float64 {
	return math.Sqrt((2 - e.Fl) * e.Fl)
}

// ParallaxConstants computes parallax constants ρ sin φ′ and ρ cos φ′.
//
// Arguments are geographic latitude φ and height h above the ellipsoid.
// For e.Er in Km, h must be in meters.
// 海拔为h的观察点对应的ρ sin φ′,ρ cos φ′
func (e Ellipsoid) ParallaxConstants(φ unit.Angle, h float64) (s, c float64) {
	boa := 1 - e.Fl
	su, cu := math.Sincos(math.Atan(boa * φ.Tan()))
	s, c = φ.Sincos()
	hoa := h * 1e-3 / e.Er
	return su*boa + hoa*s, cu + hoa*c
}

2. 其他椭球公式

  在椭球上给定的一点,地理纬度与地心纬度的差值为:$φ - φ′ = 692”.73sin(2φ) - 1”.16sin(4φ)$
  当$u=45°$时,$φ-φ′$达到最大值。 如果$φ_0$和$φ_0′$是此时相应的地理纬度和地心纬度,我们有:$$tan(φ_0) = a/b,tan(φ_0′) = b/a, φ_0+φ_0′=90°$$ 对于IAU1976($a = 6378.14km,b = 6356.755km,f=\frac {1}{298.257}$) 有 \begin{align} φ_0 = 45°05′46”.36,\\[2ex] φ_0′ = 44°54′13”.64,\\[2ex] φ_0 - φ_0′ = 11′32”.73 \end{align}   海平面上,$$\rho =0.9983271+0.0016764\cos {2φ}-0.0000035\cos {4φ}$$   同纬度$φ$的圆的半径:$$R_p = \frac {a\cos φ}{\sqrt{(1-e^2\sin^2φ)}}$$   因此,在同一纬度$φ$上,经度变化1度,相应的长度变化为$(π/180)R_p$,线速度为$ωR_p$,其中$ω = 7.292114992*10^{-5}(弧度/秒)$
  地球子午圈的曲率半径,在纬度$φ$:$$R_m=\frac {a(1-e^2)}{(1-e^2\sin ^2 φ)^{\frac 32}}$$ 且纬度变化1度,相应的长度变化:$(π/180)R_m$,在赤道时,$R_m$达到最小值,值为$a(1-e^2)=6335.44km$, 在极点时达到最大值,值为$\frac {a}{\sqrt {1-e^2}}=6399.60km$

// Rho is distance from Earth center to a point on the ellipsoid at latitude φ.
//
// Result unit is fraction of the equatorial radius.
// 海平面上,ρ值计算
func Rho(φ unit.Angle) float64 {
	// Magic numbers...
	return .9983271 + .0016764*φ.Mul(2).Cos() - .0000035*φ.Mul(4).Cos()
}

// RadiusAtLatitude returns the radius of the circle that is the parallel of
// latitude φ.
//
// Result unit is same as e.Er (typically Km.)
// 同纬度圆半径
func (e Ellipsoid) RadiusAtLatitude(φ unit.Angle) float64 {
	s, c := φ.Sincos()
	return e.A() * c / math.Sqrt(1-(2-e.Fl)*e.Fl*s*s)
}

// OneDegreeOfLongitude returns the length of one degree of longitude.
//
// Argument rp is the radius of a circle that is a parallel of latitude
// (as returned by Ellipsoid.RadiusAtLatitude.)
//
// Result is distance along one degree of the circle, in same units as rp.
// 同纬度,计算经度变化1度时长度变化的值
func OneDegreeOfLongitude(rp float64) float64 {
	return rp * math.Pi / 180
}

// RotationRate1996_5 is the rotational angular velocity of the Earth
// with respect to the stars at the epoch 1996.5.
//
// Unit is radian/second.
const RotationRate1996_5 = 7.292114992e-5

// RadiusOfCurvature of meridian at latitude φ.
//
// Result in units of e.ER, typically Km.
// 纬度为φ,子午圈曲率半径
func (e Ellipsoid) RadiusOfCurvature(φ unit.Angle) float64 {
	s := φ.Sin()
	e2 := (2 - e.Fl) * e.Fl
	return e.A() * (1 - e2) / math.Pow(1-e2*s*s, 1.5)
}

// OneDegreeOfLatitude returns the length of one degree of latitude.
//
// Argument rm is the radius of curvature along a meridian.
// (as returned by Ellipsoid.RadiusOfCurvature.)
// Result is distance in units of rm along one degree of the meridian.
// 同经度,计算纬度变化1度时长度变化的值
func OneDegreeOfLatitude(rm float64) float64 {
	return rm * math.Pi / 180
}

3. 地表两点间的距离

  假设经纬度是分别是$(L_1,φ_1),(L_2,φ_2)$,且这两点在海平面。   如果精度要求不高,可以把地球看作球形,平均半径为6371km。使用下式可得到两点间的角距离:$$\cos d=\sin φ_1\sin φ_2 +\cos φ_1\cos φ_2\cos(L_1-L_2)$$ 那么$$s = \frac {6371πd}{180}$$   高精度计算可使用以下方法: $$F=\frac {φ_1+φ_2}{2},G=\frac {φ_1-φ_2}{2},\lambda = \frac {L_1-L_2}{2}$$ $$S = \sin^2G\cos^2\lambda+\cos^2F\sin^2\lambda$$ $$C = \cos^2G\cos^2\lambda+\sin^2F\sin^2\lambda$$ $$\tan ω = \sqrt{\frac SC}$$ $$R=\frac{\sqrt{SC}}{ω}$$ $$D=2ωa,H_1=\frac{3R-1}{2C},H_2=\frac{3R+1}{2S}$$ $$s=D(1+fH_1\sin^2F\cos^2G-fH_2\cos^2F\sin^2G)$$

// Distance is distance between two points measured along the surface
// of an ellipsoid.
//
// Accuracy is much better than that of ApproxAngularDistance or
// ApproxLinearDistance.
//
// Result unit is units of e.Er, typically Km.
// 地表两点距离
func (e Ellipsoid) Distance(c1, c2 Coord) float64 {
	// From AA, ch 11, p 84.
	s2f, c2f := sincos2((c1.Lat + c2.Lat) / 2)
	s2g, c2g := sincos2((c1.Lat - c2.Lat) / 2)
	s2λ, c2λ := sincos2((c1.Lon - c2.Lon) / 2)
	s := s2g*c2λ + c2f*s2λ
	c := c2g*c2λ + s2f*s2λ
	ω := math.Atan(math.Sqrt(s / c))
	r := math.Sqrt(s*c) / ω
	d := 2 * ω * e.Er
	h1 := (3*r - 1) / (2 * c)
	h2 := (3*r + 1) / (2 * s)
	return d * (1 + e.Fl*(h1*s2f*c2g-h2*c2f*s2g))
}

func sincos2(x unit.Angle) (s2, c2 float64) {
	s, c := x.Sincos()
	return s * s, c * c
}

相关

下一页
上一页
comments powered by Disqus