func TestMathAtanh(t *testing.T) { // This is just an interface to Go's function, so just a quick simple test ctx := runtime.NewCtx(nil, nil) mm := new(MathMod) mm.SetCtx(ctx) val := 0.12 ret := mm.math_Atanh(runtime.Number(val)) exp := math.Atanh(val) if ret.Float() != exp { t.Errorf("expected %f, got %f", exp, ret.Float()) } }
// AtanH function calculates the inverse hyperbolic tangent of a supplied number func AtanH(number float64) (float64, error) { // Validate Number - Common Errors if number <= -1 || number >= 1 { return 0.0, errors.New("#NUM! - Occurred because the supplied number argument is ≤ -1 or ≥ 1") } if math.IsNaN(number) { return 0.0, errors.New("#VALUE! - Occurred because the supplied number argument is non-numeric") } return math.Atanh(number), nil }
//GeodeticToGrid converts WGS84 coordinates to RT90 func GeodeticToGrid(lat, lon float64) (x, y float64) { // Prepare ellipsoid-based stuff. e2 := Flattening * (2.0 - Flattening) n := Flattening / (2.0 - Flattening) a_roof := Axis / (1.0 + n) * (1.0 + n*n/4.0 + n*n*n*n/64.0) A := e2 B := (5.0*e2*e2 - e2*e2*e2) / 6.0 C := (104.0*e2*e2*e2 - 45.0*e2*e2*e2*e2) / 120.0 D := (1237.0 * e2 * e2 * e2 * e2) / 1260.0 beta1 := n/2.0 - 2.0*n*n/3.0 + 5.0*n*n*n/16.0 + 41.0*n*n*n*n/180.0 beta2 := 13.0*n*n/48.0 - 3.0*n*n*n/5.0 + 557.0*n*n*n*n/1440.0 beta3 := 61.0*n*n*n/240.0 - 103.0*n*n*n*n/140.0 beta4 := 49561.0 * n * n * n * n / 161280.0 // Convert. DegToRad := math.Pi / 180.0 phi := lat * DegToRad lambd := lon * DegToRad lambda_zero := CentralMeridian * DegToRad phi_star := phi - math.Sin(phi)*math.Cos(phi)*(A+ B*math.Pow(math.Sin(phi), 2)+ C*math.Pow(math.Sin(phi), 4)+ D*math.Pow(math.Sin(phi), 6)) delta_lambda := lambd - lambda_zero xi_prim := math.Atan(math.Tan(phi_star) / math.Cos(delta_lambda)) eta_prim := math.Atanh(math.Cos(phi_star) * math.Sin(delta_lambda)) x = Scale*a_roof*(xi_prim+ beta1*math.Sin(2.0*xi_prim)*math.Cosh(2.0*eta_prim)+ beta2*math.Sin(4.0*xi_prim)*math.Cosh(4.0*eta_prim)+ beta3*math.Sin(6.0*xi_prim)*math.Cosh(6.0*eta_prim)+ beta4*math.Sin(8.0*xi_prim)*math.Cosh(8.0*eta_prim)) + FalseNorthing y = Scale*a_roof*(eta_prim+ beta1*math.Cos(2.0*xi_prim)*math.Sinh(2.0*eta_prim)+ beta2*math.Cos(4.0*xi_prim)*math.Sinh(4.0*eta_prim)+ beta3*math.Cos(6.0*xi_prim)*math.Sinh(6.0*eta_prim)+ beta4*math.Cos(8.0*xi_prim)*math.Sinh(8.0*eta_prim)) + FalseEasting return x, y }
// Inverse transverse mercator projection: Projection of an cylinder onto the surface of // of an ellipsoid. Also known as reverse Gauss-Krüger projection. Input parameters: // // pt *GeoPoint: Easting(Y) and Northing(X) of map point to be projected; in meters // latO, longO: Shifted origin of latitude and longitude in decimal degrees // fe, fn: False easting and northing respectively in meters // scale: Projection scaling; Dimensionless, typically 1 or little bellow // // This algorithm uses the algorithm described by Redfearn // http://en.wikipedia.org/wiki/Transverse_Mercator:_Redfearn_series // // Taken from "OGP Publication 373-7-2 – Surveying and Positioning Guidance Note number 7, part 2 – November 2010", // pp. 48 - 51 // // More accurate, iterative but slower algorithmic implementation func InverseTransverseMercator(pt *GeoPoint, latO, longO, scale, fe, fn float64) *PolarCoord { var gc PolarCoord el := pt.El latOrad := degtorad(latO) longOrad := degtorad(longO) f := 1 - el.b/el.a esq := math.Sqrt(2.0*f - f*f) n := f / (2.0 - f) B := (el.a / (1 + n)) * (1 + n*n/4.0 + n*n*n*n/64.0) var SO float64 if latOrad != 0.0 { h1 := n/2.0 - (2.0/3.0)*n*n + (5.0/16.0)*n*n*n + (41.0/180.0)*n*n*n*n h2 := (13.0/48.0)*n*n - (3.0/5.0)*n*n*n + (557.0/1440.0)*n*n*n*n h3 := (61.0/240.0)*n*n*n - (103.0/140.0)*n*n*n*n h4 := (49561.0 / 161280.0) * n * n * n * n QO := math.Asinh(math.Tan(latOrad)) - (esq * math.Atanh(esq*math.Sin(latOrad))) bO := math.Atan(math.Sinh(QO)) xiO0 := bO // math.Asin(math.Sin(bO)) xiO1 := h1 * math.Sin(2.0*xiO0) xiO2 := h2 * math.Sin(4.0*xiO0) xiO3 := h3 * math.Sin(6.0*xiO0) xiO4 := h4 * math.Sin(8.0*xiO0) xiO := xiO0 + xiO1 + xiO2 + xiO3 + xiO4 SO = B * xiO } h1i := n/2.0 - (2.0/3.0)*n*n + (37.0/96.0)*n*n*n - (1.0/360.0)*n*n*n*n h2i := (1.0/48.0)*n*n + (1.0/15.0)*n*n*n - (437.0/1440.0)*n*n*n*n h3i := (17.0/480.0)*n*n*n - (37.0/840.0)*n*n*n*n h4i := (4397.0 / 161280.0) * n * n * n * n etai := (pt.X - fe) / (B * scale) xii := ((pt.Y - fn) + scale*SO) / (B * scale) xi1i := h1i * math.Sin(2*xii) * math.Cosh(2*etai) xi2i := h2i * math.Sin(4*xii) * math.Cosh(4*etai) xi3i := h3i * math.Sin(6*xii) * math.Cosh(6*etai) xi4i := h4i * math.Sin(8*xii) * math.Cosh(8*etai) eta1i := h1i * math.Cos(2*xii) * math.Sinh(2*etai) eta2i := h2i * math.Cos(4*xii) * math.Sinh(4*etai) eta3i := h3i * math.Cos(6*xii) * math.Sinh(6*etai) eta4i := h4i * math.Cos(8*xii) * math.Sinh(8*etai) xi0i := xii - (xi1i + xi2i + xi3i + xi4i) eta0i := etai - (eta1i + eta2i + eta3i + eta4i) bi := math.Asin(math.Sin(xi0i) / math.Cosh(eta0i)) Qi := math.Asinh(math.Tan(bi)) Qiiold := Qi + (esq * math.Atanh(esq*math.Tanh(Qi))) Qii := Qi + (esq * math.Atanh(esq*math.Tanh(Qiiold))) for math.Abs(Qiiold-Qii) > 1e-12 { Qiiold = Qii Qii = Qi + (esq * math.Atanh(esq*math.Tanh(Qiiold))) } gc.Latitude = radtodeg(math.Atan(math.Sinh(Qii))) gc.Longitude = radtodeg(longOrad + math.Asin(math.Tanh(eta0i)/math.Cos(bi))) gc.El = el return &gc }
// Direct transverse mercator projection: Projection of an ellipsoid onto the surface of // of a cylinder. Also known as Gauss-Krüger projection. Input parameters: // // gc *PolarCoord: Latitude and Longitude or point to be projected; in decimal degrees // latO, longO: Shifted origin of latitude and longitude in decimal degrees // fe, fn: False easting and northing respectively in meters // scale: Projection scaling; Dimensionless, typically 1 or little bellow // // This algorithm uses the algorithm described by Redfearn // http://en.wikipedia.org/wiki/Transverse_Mercator:_Redfearn_series // // Taken from "OGP Publication 373-7-2 – Surveying and Positioning Guidance Note number 7, part 2 – November 2010", // pp. 48 - 51 func DirectTransverseMercator(gc *PolarCoord, latO, longO, scale, fe, fn float64) *GeoPoint { var pt GeoPoint el := gc.El latOrad := degtorad(latO) longOrad := degtorad(longO) latrad := degtorad(gc.Latitude) longrad := degtorad(gc.Longitude) f := 1 - el.b/el.a esq := math.Sqrt(2.0*f - f*f) n := f / (2.0 - f) B := (el.a / (1 + n)) * (1 + n*n/4.0 + n*n*n*n/64.0) h1 := n/2.0 - (2.0/3.0)*(n*n) + (5.0/16.0)*(n*n*n) + (41.0/180.0)*(n*n*n*n) h2 := (13.0/48.0)*(n*n) - (3.0/5.0)*(n*n*n) + (557.0/1440.0)*(n*n*n*n) h3 := (61.0/240.0)*(n*n*n) - (103.0/140.0)*(n*n*n*n) h4 := (49561.0 / 161280.0) * (n * n * n * n) var SO float64 if latOrad != 0.0 { QO := math.Asinh(math.Tan(latOrad)) - (esq * math.Atanh(esq*math.Sin(latOrad))) bO := math.Atan(math.Sinh(QO)) xiO0 := bO // math.Asin(math.Sin(bO)) xiO1 := h1 * math.Sin(2.0*xiO0) xiO2 := h2 * math.Sin(4.0*xiO0) xiO3 := h3 * math.Sin(6.0*xiO0) xiO4 := h4 * math.Sin(8.0*xiO0) xiO := xiO0 + xiO1 + xiO2 + xiO3 + xiO4 SO = B * xiO } Q := math.Asinh(math.Tan(latrad)) - (esq * math.Atanh(esq*math.Sin(latrad))) b := math.Atan(math.Sinh(Q)) eta0 := math.Atanh(math.Cos(b) * math.Sin(longrad-longOrad)) xi0 := math.Asin(math.Sin(b) * math.Cosh(eta0)) xi1 := h1 * math.Sin(2*xi0) * math.Cosh(2*eta0) xi2 := h2 * math.Sin(4*xi0) * math.Cosh(4*eta0) xi3 := h3 * math.Sin(6*xi0) * math.Cosh(6*eta0) xi4 := h4 * math.Sin(8*xi0) * math.Cosh(8*eta0) xi := xi0 + xi1 + xi2 + xi3 + xi4 eta1 := h1 * math.Cos(2*xi0) * math.Sinh(2*eta0) eta2 := h2 * math.Cos(4*xi0) * math.Sinh(4*eta0) eta3 := h3 * math.Cos(6*xi0) * math.Sinh(6*eta0) eta4 := h4 * math.Cos(8*xi0) * math.Sinh(8*eta0) eta := eta0 + eta1 + eta2 + eta3 + eta4 pt.X = fe + scale*B*eta pt.Y = fn + scale*(B*xi-SO) pt.El = el return &pt }
func init() { _a = WGS84_a _f = WGS84_f _f1 = 1 - _f _e2 = _f * (2 - _f) _ep2 = _e2 / (_f1 * _f1) _n = _f / (2 - _f) _b = _a * _f1 _c2 = _b * _b switch { case _e2 > 0: _c2 *= math.Atanh(math.Sqrt(_e2)) / math.Sqrt(math.Abs(_e2)) case _e2 < 0: _c2 *= math.Atan(math.Sqrt(-_e2)) / math.Sqrt(math.Abs(_e2)) } _c2 += _a * _a _c2 /= 2 if math.Abs(_e2) < 0.01 { _etol2 = _tol2 / 0.1 } else { _etol2 = _tol2 / math.Sqrt(math.Abs(_e2)) } _A3x[0] = 1. _A3x[1] = (_n - 1) / 2. _A3x[2] = (_n*(3*_n-1) - 2) / 8. _A3x[3] = (_n*(_n*(5*_n-1)-3) - 1) / 16. _A3x[4] = (_n*((-5*_n-20)*_n-4) - 6) / 128. _A3x[5] = ((-5*_n-10)*_n - 6) / 256. _A3x[6] = (-15*_n - 20) / 1024. _A3x[7] = -25. / 2048. _C3x[0] = (1 - _n) / 4. _C3x[1] = (1 - _n*_n) / 8. _C3x[2] = (_n*((-5*_n-1)*_n+3) + 3) / 64. _C3x[3] = (_n*((2-2*_n)*_n+2) + 5) / 128. _C3x[4] = (_n*(3*_n+11) + 12) / 512. _C3x[5] = (10*_n + 21) / 1024. _C3x[6] = 243. / 16384. _C3x[7] = ((_n-3)*_n + 2) / 32. _C3x[8] = (_n*(_n*(2*_n-3)-2) + 3) / 64. _C3x[9] = (_n*((-6*_n-9)*_n+2) + 6) / 256. _C3x[10] = ((1-2*_n)*_n + 5) / 256. _C3x[11] = (69*_n + 108) / 8192. _C3x[12] = 187. / 16384. _C3x[13] = (_n*((5-_n)*_n-9) + 5) / 192. _C3x[14] = (_n*(_n*(10*_n-6)-10) + 9) / 384. _C3x[15] = ((-77*_n-8)*_n + 42) / 3072. _C3x[16] = (12 - _n) / 1024. _C3x[17] = 139. / 16384. _C3x[18] = (_n*((20-7*_n)*_n-28) + 14) / 1024. _C3x[19] = ((-7*_n-40)*_n + 28) / 2048. _C3x[20] = (72 - 43*_n) / 8192. _C3x[21] = 127 / 16384. _C3x[22] = (_n*(75*_n-90) + 42) / 5120. _C3x[23] = (9 - 15*_n) / 1024. _C3x[24] = 99. / 16384. _C3x[25] = (44 - 99*_n) / 8192. _C3x[26] = 99. / 16384. _C3x[27] = 429. / 114688. _C4x[0] = (_ep2*(_ep2*(_ep2*(_ep2*(_ep2*((8704-7168*_ep2)*_ep2-10880)+14144)-19448)+29172)-51051) + 510510) / 765765. _C4x[1] = (_ep2*(_ep2*(_ep2*(_ep2*((8704-7168*_ep2)*_ep2-10880)+14144)-19448)+29172) - 51051) / 1021020. _C4x[2] = (_ep2*(_ep2*(_ep2*((2176-1792*_ep2)*_ep2-2720)+3536)-4862) + 7293) / 306306. _C4x[3] = (_ep2*(_ep2*((1088-896*_ep2)*_ep2-1360)+1768) - 2431) / 175032. _C4x[4] = (_ep2*((136-112*_ep2)*_ep2-170) + 221) / 24310. _C4x[5] = ((68-56*_ep2)*_ep2 - 85) / 13260. _C4x[6] = (17 - 14*_ep2) / 3570. _C4x[7] = -1. / 272. _C4x[8] = (_ep2*(_ep2*(_ep2*(_ep2*(_ep2*(7168*_ep2-8704)+10880)-14144)+19448)-29172) + 51051) / 9189180. _C4x[9] = (_ep2*(_ep2*(_ep2*(_ep2*(1792*_ep2-2176)+2720)-3536)+4862) - 7293) / 1837836. _C4x[10] = (_ep2*(_ep2*(_ep2*(896*_ep2-1088)+1360)-1768) + 2431) / 875160. _C4x[11] = (_ep2*(_ep2*(112*_ep2-136)+170) - 221) / 109395. _C4x[12] = (_ep2*(56*_ep2-68) + 85) / 55692. _C4x[13] = (14*_ep2 - 17) / 14280. _C4x[14] = 7. / 7344. _C4x[15] = (_ep2*(_ep2*(_ep2*((2176-1792*_ep2)*_ep2-2720)+3536)-4862) + 7293) / 15315300. _C4x[16] = (_ep2*(_ep2*((1088-896*_ep2)*_ep2-1360)+1768) - 2431) / 4375800. _C4x[17] = (_ep2*((136-112*_ep2)*_ep2-170) + 221) / 425425. _C4x[18] = ((68-56*_ep2)*_ep2 - 85) / 185640. _C4x[19] = (17 - 14*_ep2) / 42840. _C4x[20] = -7. / 20400. _C4x[21] = (_ep2*(_ep2*(_ep2*(896*_ep2-1088)+1360)-1768) + 2431) / 42882840. _C4x[22] = (_ep2*(_ep2*(112*_ep2-136)+170) - 221) / 2382380. _C4x[23] = (_ep2*(56*_ep2-68) + 85) / 779688. _C4x[24] = (14*_ep2 - 17) / 149940. _C4x[25] = 1. / 8976. _C4x[26] = (_ep2*((136-112*_ep2)*_ep2-170) + 221) / 27567540. _C4x[27] = ((68-56*_ep2)*_ep2 - 85) / 5012280. _C4x[28] = (17 - 14*_ep2) / 706860. _C4x[29] = -7. / 242352. _C4x[30] = (_ep2*(56*_ep2-68) + 85) / 67387320. _C4x[31] = (14*_ep2 - 17) / 5183640. _C4x[32] = 7. / 1283568. _C4x[33] = (17 - 14*_ep2) / 79639560. _C4x[34] = -1. / 1516944. _C4x[35] = 1. / 26254800. }
// float32 version of math.Atanhf func Atanh(x float32) float32 { return float32(math.Atanh(float64(x))) }
// 緯度をメルカトルY座標に変換する func (lat Lat) ToMy() My { return My(math.Atanh(math.Sin(float64(lat)*DEG2RAD)) / math.Pi) }
func (m *MathMod) math_Atanh(args ...runtime.Val) runtime.Val { runtime.ExpectAtLeastNArgs(1, args) return runtime.Number(math.Atanh(args[0].Float())) }
func FunctionVal(f Function, x float64) float64 { // switch f { case Floor: i, _ := math.Modf(x) return i case Fract: _, f := math.Modf(x) return f case Chs: return -x case Rec: if x == 0 { // TODO return math.NaN() } return 1 / x case Sqr: return x * x case Sqrt: return math.Sqrt(x) case Exp: return math.Exp(x) case Exp10: return math.Exp(x * math.Ln10) case Exp2: return math.Exp(x * math.Ln2) case Log: return math.Log(x) case Lg: return math.Log10(x) case Ld: return math.Log2(x) case Sin: return math.Sin(x) case Cos: return math.Cos(x) case Tan: return math.Tan(x) case Cot: return 1 / math.Tan(x) case Arcsin: return math.Asin(x) case Arccos: return math.Acos(x) case Arctan: return math.Atan(x) case Arccot: return math.Atan(x) case Sinh: return math.Sinh(x) case Cosh: return (math.Exp(x) + math.Exp(-x)) / 2 case Tanh: return math.Tanh(x) case Coth: return (math.Exp(x) + math.Exp(-x)) / (math.Exp(x) - math.Exp(-x)) case Arsinh: return math.Asinh(x) case Arcosh: return math.Log(x + math.Sqrt(x*x-1)) case Artanh: return math.Atanh(x) case Arcoth: return math.Log((x+1)/(x-1)) / 2 case Gamma: return math.Gamma(x) } return math.NaN() }