diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/math/geodesy.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/math/geodesy.b')
| -rw-r--r-- | appl/math/geodesy.b | 849 |
1 files changed, 849 insertions, 0 deletions
diff --git a/appl/math/geodesy.b b/appl/math/geodesy.b new file mode 100644 index 00000000..7c4cd152 --- /dev/null +++ b/appl/math/geodesy.b @@ -0,0 +1,849 @@ +implement Geodesy; + +include "sys.m"; + sys: Sys; +include "math.m"; + maths: Math; + Pi: import Math; + sin, cos, tan, asin, acos, atan, atan2, sqrt, fabs: import maths; +include "math/geodesy.m"; + +Approx: con 0; + +Epsilon: con 0.000001; +Mperft: con 0.3048; +Earthrad: con 10800.0/Pi*6076.115*Mperft; # in feet (about 4000 miles) : now metres +Δt: con 16.0; # now-1989 + +# lalo0: con "53:57:45N 01:04:55W"; +# os0: con "SE6022552235"; + +# ellipsoids +Airy1830, Airy1830m, Int1924, GRS80: con iota; + +Ngrid: con 100000; # in metres + +Vector: adt{ + x, y, z: real; +}; + +Latlong: adt{ + la: real; # -Pi to Pi + lo: real; # -Pi to Pi + x: real; + y: real; +}; + +Ellipsoid: adt{ + name: string; + a: real; + b: real; +}; + +Datum: adt{ + name: string; + e: int; + # X, Y, Z axes etc +}; + +Mercator: adt{ + name: string; + F0: real; + φ0λ0: string; + E0: real; + N0: real; + e: int; +}; + +Helmert: adt{ + tx, ty, tz: real; # metres + s: real; # ppm + rx, ry, rz: real; # secs +}; + +Format: adt{ + dat: int; # datum + cdat: int; # converting datum + prj: int; # projection + tmp: ref Mercator; # actual projection + orig: Lalo; # origin of above projection + zone: int; # UTM zone +}; + +# ellipsoids +ells := array[] of { + Airy1830 => Ellipsoid("Airy1830", 6377563.396, 6356256.910), + Airy1830m => Ellipsoid("Airy1830 modified", 6377340.189, 6356034.447), + Int1924 => Ellipsoid("International 1924", 6378388.000, 6356911.946), + GRS80 => Ellipsoid("GRS80", 6378137.000, 6356752.3141), + }; + +# datums +dats := array[] of { + OSGB36 => Datum("OSGB36", Airy1830), + Ireland65 => Datum("Ireland65", Airy1830m), + ED50 => Datum("ED50", Int1924), + WGS84 => Datum("WGS84", GRS80), + ITRS2000 => Datum("ITRS2000", GRS80), + ETRS89 => Datum("ETRS89", GRS80), + }; + +# transverse Mercator projections +tmps := array[] of { + Natgrid => Mercator("National Grid", 0.9996012717, "49:00:00N 02:00:00W", real(4*Ngrid), real(-Ngrid), Airy1830), + IrishNatgrid => Mercator("Irish National Grid", 1.000035, "53:30:00N 08:00:00W", real(2*Ngrid), real(5*Ngrid/2), Airy1830m), + UTMEur => Mercator("UTM Europe", 0.9996, nil, real(5*Ngrid), real(0), Int1924), + UTM => Mercator("UTM", 0.9996, nil, real(5*Ngrid), real(0), GRS80), + }; + +# Helmert tranformations +HT_WGS84_OSGB36: con Helmert(-446.448, 125.157, -542.060, 20.4894, -0.1502, -0.2470, -0.8421); +HT_ITRS2000_ETRS89: con Helmert(0.054, 0.051, -0.048, 0.0, 0.000081*Δt, 0.00049*Δt, -0.000792*Δt); + +# Helmert matrices +HM_WGS84_OSGB36, HM_OSGB36_WGS84, HM_ITRS2000_ETRS89, HM_ETRS89_ITRS2000, HM_ETRS89_OSGB36, HM_OSGB36_ETRS89, HM_IDENTITY: array of array of real; + +fmt: ref Format; + +# latlong: ref Latlong; + +init(d: int, t: int, z: int) +{ + sys = load Sys Sys->PATH; + maths = load Math Math->PATH; + + helmertinit(); + format(d, t, z); + # (nil, (la, lo)) := str2lalo(lalo0); + # (nil, (E, N)) := os2en(os0); + # latlong = ref Latlong(la, lo, real E, real N); +} + +format(d: int, t: int, z: int) +{ + if(fmt == nil) + fmt = ref Format(WGS84, 0, Natgrid, nil, (0.0, 0.0), 30); + if(d >= 0 && d <= ETRS89) + fmt.dat = d; + if(t >= 0 && t <= UTM) + fmt.prj = t; + if(z >= 1 && z <= 60) + fmt.zone = z; + fmt.cdat = fmt.dat; + fmt.tmp = ref Mercator(tmps[fmt.prj]); + if(fmt.tmp.φ0λ0 == nil) + fmt.orig = utmlaloz(fmt.zone); + else + (nil, fmt.orig) = str2lalo(fmt.tmp.φ0λ0); + e := fmt.tmp.e; + if(e != dats[fmt.dat].e){ + for(i := 0; i <= ETRS89; i++) + if(e == dats[i].e){ + fmt.cdat = i; + break; + } + } +} + +str2en(s: string): (int, Eano) +{ + s = trim(s, " \t\n\r"); + if(s == nil) + return (0, (0.0, 0.0)); + os := s[0] >= 'A' && s[0] <= 'Z' || strchrs(s, "NSEW:") < 0; + en: Eano; + if(os){ + (ok, p) := os2en(s); + if(!ok) + return (0, (0.0, 0.0)); + en = p; + } + else{ + (ok, lalo) := str2lalo(s); + if(!ok) + return (0, (0.0, 0.0)); + en = lalo2en(lalo); + } + return (1, en); +} + +str2ll(s: string, pos: int, neg: int): (int, real) +{ + (n, ls) := sys->tokenize(s, ": \t"); + if(n < 1 || n > 3) + return (0, 0.0); + t := hd ls; ls = tl ls; + v := real t; + if(ls != nil){ + t = hd ls; ls = tl ls; + v += (real t)/60.0; + } + if(ls != nil){ + t = hd ls; ls = tl ls; + v += (real t)/3600.0; + } + c := t[len t-1]; + if(c == pos) + ; + else if(c == neg) + v = -v; + else + return (0, 0.0); + return (1, norm(deg2rad(v))); +} + +str2lalo(s: string): (int, Lalo) +{ + s = trim(s, " \t\n\r"); + p := strchr(s, 'N'); + if(p < 0) + p = strchr(s, 'S'); + if(p < 0) + return (0, (0.0, 0.0)); + (ok1, la) := str2ll(s[0: p+1], 'N', 'S'); + (ok2, lo) := str2ll(s[p+1: ], 'E', 'W'); + if(!ok1 || !ok2 || la < -Pi/2.0 || la > Pi/2.0) + return (0, (0.0, 0.0)); + return (1, (la, lo)); +} + +ll2str(ll: int, dir: string): string +{ + d := ll/360000; + ll -= 360000*d; + m := ll/6000; + ll -= 6000*m; + s := ll/100; + ll -= 100*s; + return d2(d) + ":" + d2(m) + ":" + d2(s) + "." + d2(ll) + dir; +} + +lalo2str(lalo: Lalo): string +{ + la := int(360000.0*rad2deg(lalo.la)); + lo := int(360000.0*rad2deg(lalo.lo)); + lad := "N"; + lod := "E"; + if(la < 0){ + lad = "S"; + la = -la; + } + if(lo < 0){ + lod = "W"; + lo = -lo; + } + return ll2str(la, lad) + " " + ll2str(lo, lod); +} + +en2os(p: Eano): string +{ + E := trunc(p.e); + N := trunc(p.n); + es := E/Ngrid; + ns := N/Ngrid; + e := E-Ngrid*es; + n := N-Ngrid*ns; + d1 := 5*(4-ns/5)+es/5+'A'-3; + d2 := 5*(4-ns%5)+es%5+'A'; + # now account for 'I' missing + if(d1 >= 'I') + d1++; + if(d2 >= 'I') + d2++; + return sys->sprint("%c%c%5.5d%5.5d", d1, d2, e, n); +} + +os2en(s: string): (int, Eano) +{ + s = trim(s, " \t\n\r"); + if((m := len s) != 4 && m != 6 && m != 8 && m != 10 && m != 12) + return (0, (0.0, 0.0)); + m = m/2-1; + u := Ngrid/10**m; + d1 := s[0]; + d2 := s[1]; + if(d1 < 'A' || d2 < 'A' || d1 > 'Z' || d2 > 'Z'){ + # error(sys->sprint("bad os reference %s", s)); + e := u*int s[0: 1+m]; + n := u*int s[1+m: 2+2*m]; + return (1, (real e, real n)); + } + e := u*int s[2: 2+m]; + n := u*int s[2+m: 2+2*m]; + if(d1 >= 'I') + d1--; + if(d2 >= 'I') + d2--; + d1 -= 'A'-3; + d2 -= 'A'; + es := 5*(d1%5)+d2%5; + ns := 5*(4-d1/5)+4-d2/5; + return (1, (real(Ngrid*es+e), real(Ngrid*ns+n))); +} + +utmlalo(lalo: Lalo): Lalo +{ + (nil, zn) := utmzone(lalo); + return utmlaloz(zn); +} + +utmlaloz(zn: int): Lalo +{ + return (0.0, deg2rad(real(6*zn-183))); +} + +utmzone(lalo: Lalo): (int, int) +{ + (la, lo) := lalo; + la = rad2deg(la); + lo = rad2deg(lo); + zlo := trunc(lo+180.0)/6+1; + if(la < -80.0) + zla := 'B'; + else if(la >= 84.0) + zla = 'Y'; + else if(la >= 72.0) + zla = 'X'; + else{ + zla = trunc(la+80.0)/8+'C'; + if(zla >= 'I') + zla++; + if(zla >= 'O') + zla++; + } + return (zla, zlo); +} + +helmertinit() +{ + (HM_WGS84_OSGB36, HM_OSGB36_WGS84) = helminit(HT_WGS84_OSGB36); + (HM_ITRS2000_ETRS89, HM_ETRS89_ITRS2000) = helminit(HT_ITRS2000_ETRS89); + HM_ETRS89_OSGB36 = mulmm(HM_WGS84_OSGB36, HM_ETRS89_ITRS2000); + HM_OSGB36_ETRS89 = mulmm(HM_ITRS2000_ETRS89, HM_OSGB36_WGS84); + HM_IDENTITY = m := matrix(3, 4); + m[0][0] = m[1][1] = m[2][2] = 1.0; + # mprint(HM_WGS84_OSGB36); + # mprint(HM_OSGB36_WGS84); +} + +helminit(h: Helmert): (array of array of real, array of array of real) +{ + m := matrix(3, 4); + + s := 1.0+h.s/1000000.0; + rx := sec2rad(h.rx); + ry := sec2rad(h.ry); + rz := sec2rad(h.rz); + + m[0][0] = s; + m[0][1] = -rz; + m[0][2] = ry; + m[0][3] = h.tx; + m[1][0] = rz; + m[1][1] = s; + m[1][2] = -rx; + m[1][3] = h.ty; + m[2][0] = -ry; + m[2][1] = rx; + m[2][2] = s; + m[2][3] = h.tz; + + return (m, inv(m)); +} + +trans(f: int, t: int): array of array of real +{ + case(f){ + WGS84 => + case(t){ + WGS84 => + return HM_IDENTITY; + OSGB36 => + return HM_WGS84_OSGB36; + ITRS2000 => + return HM_IDENTITY; + ETRS89 => + return HM_ITRS2000_ETRS89; + } + OSGB36 => + case(t){ + WGS84 => + return HM_OSGB36_WGS84; + OSGB36 => + return HM_IDENTITY; + ITRS2000 => + return HM_OSGB36_WGS84; + ETRS89 => + return HM_OSGB36_ETRS89; + } + ITRS2000 => + case(t){ + WGS84 => + return HM_IDENTITY; + OSGB36 => + return HM_WGS84_OSGB36; + ITRS2000 => + return HM_IDENTITY; + ETRS89 => + return HM_ITRS2000_ETRS89; + } + ETRS89 => + case(t){ + WGS84 => + return HM_ETRS89_ITRS2000; + OSGB36 => + return HM_ETRS89_OSGB36; + ITRS2000 => + return HM_ETRS89_ITRS2000; + ETRS89 => + return HM_IDENTITY; + } + } + return HM_IDENTITY; # Ireland65, ED50 not done +} + +datum2datum(lalo: Lalo, f: int, t: int): Lalo +{ + if(f == t) + return lalo; + (la, lo) := lalo; + v := laloh2xyz(la, lo, 0.0, dats[f].e); + v = mulmv(trans(f, t), v); + (la, lo, nil) = xyz2laloh(v, dats[t].e); + return (la, lo); +} + +laloh2xyz(φ: real, λ: real, H: real, e: int): Vector +{ + a := ells[e].a; + b := ells[e].b; + e2 := 1.0-(b/a)**2; + + s := sin(φ); + c := cos(φ); + + ν := a/sqrt(1.0-e2*s*s); + x := (ν+H)*c*cos(λ); + y := (ν+H)*c*sin(λ); + z := ((1.0-e2)*ν+H)*s; + + return (x, y, z); +} + +xyz2laloh(v: Vector, e: int): (real, real, real) +{ + x := v.x; + y := v.y; + z := v.z; + + a := ells[e].a; + b := ells[e].b; + e2 := 1.0-(b/a)**2; + + λ := atan2(y, x); + + p := sqrt(x*x+y*y); + φ := φ1 := atan(z/(p*(1.0-e2))); + ν := 0.0; + do{ + φ = φ1; + s := sin(φ); + ν = a/sqrt(1.0-e2*s*s); + φ1 = atan((z+e2*ν*s)/p); + }while(!small(fabs(φ-φ1))); + + φ = φ1; + H := p/cos(φ)-ν; + + return (φ, λ, H); +} + +lalo2en(lalo: Lalo): Eano +{ + (φ, λ) := lalo; + if(fmt.cdat != fmt.dat) + (φ, λ) = datum2datum(lalo, fmt.dat, fmt.cdat); + + s := sin(φ); + c := cos(φ); + t2 := tan(φ)**2; + + (nil, F0, φ0λ0, E0, N0, e) := *fmt.tmp; + a := ells[e].a; + b := ells[e].b; + e2 := 1.0-(b/a)**2; + + if(φ0λ0 == nil) # UTM + (φ0, λ0) := utmlalo((φ, λ)); # don't use fmt.zone here + else + (φ0, λ0) = fmt.orig; + + n := (a-b)/(a+b); + ν := a*F0/sqrt(1.0-e2*s*s); + ρ := ν*(1.0-e2)/(1.0-e2*s*s); + η2 := ν/ρ-1.0; + + φ1 := φ-φ0; + φ2 := φ+φ0; + M := b*F0*((1.0+n*(1.0+1.25*n*(1.0+n)))*φ1 - (3.0*n*(1.0+n*(1.0+0.875*n)))*sin(φ1)*cos(φ2) + 1.875*n*n*(1.0+n)*sin(2.0*φ1)*cos(2.0*φ2) - 35.0/24.0*n**3*sin(3.0*φ1)*cos(3.0*φ2)); + + I := M+N0; + II := ν*s*c/2.0; + III := ν*s*c**3*(5.0-t2+9.0*η2)/24.0; + IIIA := ν*s*c**5*(61.0+t2*(t2-58.0))/720.0; + IV := ν*c; + V := ν*c**3*(ν/ρ-t2)/6.0; + VI := ν*c**5*(5.0+14.0*η2+t2*(t2-18.0-58.0*η2))/120.0; + + λ -= λ0; + λ2 := λ*λ; + N := I+λ2*(II+λ2*(III+IIIA*λ2)); + E := E0+λ*(IV+λ2*(V+VI*λ2)); + + # if(E < 0.0 || E >= real(7*Ngrid)) + # E = 0.0; + # if(N < 0.0 || N >= real(13*Ngrid)) + # N = 0.0; + return (E, N); +} + +en2lalo(en: Eano): Lalo +{ + E := en.e; + N := en.n; + + (nil, F0, nil, E0, N0, e) := *fmt.tmp; + a := ells[e].a; + b := ells[e].b; + e2 := 1.0-(b/a)**2; + + (φ0, λ0) := fmt.orig; + + n := (a-b)/(a+b); + + M0 := 1.0+n*(1.0+1.25*n*(1.0+n)); + M1 := 3.0*n*(1.0+n*(1.0+0.875*n)); + M2 := 1.875*n*n*(1.0+n); + M3 := 35.0/24.0*n**3; + + N -= N0; + M := 0.0; + φ := φold := φ0; + do{ + φ = (N-M)/(a*F0)+φold; + φ1 := φ-φ0; + φ2 := φ+φ0; + M = b*F0*(M0*φ1 - M1*sin(φ1)*cos(φ2) + M2*sin(2.0*φ1)*cos(2.0*φ2) - M3*sin(3.0*φ1)*cos(3.0*φ2)); + φold = φ; + }while(fabs(N-M) >= 0.01); + + s := sin(φ); + c := cos(φ); + t := tan(φ); + t2 := t*t; + + ν := a*F0/sqrt(1.0-e2*s*s); + ρ := ν*(1.0-e2)/(1.0-e2*s*s); + η2 := ν/ρ-1.0; + + VII := t/(2.0*ρ*ν); + VIII := VII*(5.0+η2+3.0*t2*(1.0-3.0*η2))/(12.0*ν*ν); + IX := VII*(61.0+45.0*t2*(2.0+t2))/(360.0*ν**4); + X := 1.0/(ν*c); + XI := X*(ν/ρ+2.0*t2)/(6.0*ν*ν); + XII := X*(5.0+4.0*t2*(7.0+6.0*t2))/(120.0*ν**4); + XIIA := X*(61.0+2.0*t2*(331.0+60.0*t2*(11.0+6.0*t2)))/(5040.0*ν**6); + + E -= E0; + E2 := E*E; + φ = φ-E2*(VII-E2*(VIII-E2*IX)); + λ := λ0+E*(X-E2*(XI-E2*(XII-E2*XIIA))); + + if(fmt.cdat != fmt.dat) + (φ, λ) = datum2datum((φ, λ), fmt.cdat, fmt.dat); + return (φ, λ); +} + +mulmm(m1: array of array of real, m2: array of array of real): array of array of real +{ + m := matrix(3, 4); + mul3x3(m, m1, m2); + for(i := 0; i < 3; i++){ + sum := 0.0; + for(k := 0; k < 3; k++) + sum += m1[i][k]*m2[k][3]; + m[i][3] = sum+m1[i][3]; + } + return m; +} + +mulmv(m: array of array of real, v: Vector): Vector +{ + x := v.x; + y := v.y; + z := v.z; + v.x = m[0][0]*x + m[0][1]*y + m[0][2]*z + m[0][3]; + v.y = m[1][0]*x + m[1][1]*y + m[1][2]*z + m[1][3]; + v.z = m[2][0]*x + m[2][1]*y + m[2][2]*z + m[2][3]; + return v; +} + +inv(m: array of array of real): array of array of real +{ + n := matrix(3, 4); + inv3x3(m, n); + (n[0][3], n[1][3], n[2][3]) = mulmv(n, (-m[0][3], -m[1][3], -m[2][3])); + return n; +} + +mul3x3(m: array of array of real, m1: array of array of real, m2: array of array of real) +{ + for(i := 0; i < 3; i++){ + for(j := 0; j < 3; j++){ + sum := 0.0; + for(k := 0; k < 3; k++) + sum += m1[i][k]*m2[k][j]; + m[i][j] = sum; + } + } +} + +inv3x3(m: array of array of real, n: array of array of real) +{ + t00 := m[0][0]; + t01 := m[0][1]; + t02 := m[0][2]; + t10 := m[1][0]; + t11 := m[1][1]; + t12 := m[1][2]; + t20 := m[2][0]; + t21 := m[2][1]; + t22 := m[2][2]; + + n[0][0] = t11*t22-t12*t21; + n[1][0] = t12*t20-t10*t22; + n[2][0] = t10*t21-t11*t20; + n[0][1] = t02*t21-t01*t22; + n[1][1] = t00*t22-t02*t20; + n[2][1] = t01*t20-t00*t21; + n[0][2] = t01*t12-t02*t11; + n[1][2] = t02*t10-t00*t12; + n[2][2] = t00*t11-t01*t10; + + d := t00*n[0][0]+t01*n[1][0]+t02*n[2][0]; + for(i := 0; i < 3; i++) + for(j := 0; j < 3; j++) + n[i][j] /= d; +} + +matrix(rows: int, cols: int): array of array of real +{ + m := array[rows] of array of real; + for(i := 0; i < rows; i++) + m[i] = array[cols] of { * => 0.0 }; + return m; +} + +vprint(v: Vector) +{ + sys->print(" %f %f %f\n", v.x, v.y, v.z); +} + +mprint(m: array of array of real) +{ + for(i := 0; i < len m; i++){ + for(j := 0; j < len m[i]; j++) + sys->print(" %f", m[i][j]); + sys->print("\n"); + } +} + +# lalo2xy(la: real, lo: real, lalo: ref Latlong): Eano +# { +# x, y: real; +# +# la0 := lalo.la; +# lo0 := lalo.lo; +# if(Approx){ +# x = Earthrad*cos(la0)*(lo-lo0)+lalo.x; +# y = Earthrad*(la-la0)+lalo.y; +# } +# else{ +# x = Earthrad*cos(la)*sin(lo-lo0)+lalo.x; +# y = Earthrad*(sin(la)*cos(la0)-sin(la0)*cos(la)*cos(lo-lo0))+lalo.y; +# } +# return (x, y); +# } + +# lalo2xyz(la: real, lo: real, lalo: ref Latlong): (int, int, int) +# { +# z: real; +# +# la0 := lalo.la; +# lo0 := lalo.lo; +# (x, y) := lalo2xy(la, lo, lalo); +# if(Approx) +# z = Earthrad; +# else +# z = Earthrad*(sin(la)*sin(la0)+cos(la)*cos(la0)*cos(lo-lo0)); +# return (x, y, int z); +# } + +# xy2lalo(p: Eano, lalo: ref Latlong): (real, real) +# { +# la, lo: real; +# +# x := p.e; +# y := p.n; +# la0 := lalo.la; +# lo0 := lalo.lo; +# if(Approx){ +# la = la0 + (y-lalo.y)/Earthrad; +# lo = lo0 + (x-lalo.x)/(Earthrad*cos(la0)); +# } +# else{ +# a, b, c, d, bestd, r, r1, r2, lat, lon, tmp: real; +# i, n: int; +# +# bestd = -1.0; +# la = lo = 0.0; +# a = (x-lalo.x)/Earthrad; +# b = (y-lalo.y)/Earthrad; +# (n, r1, r2) = quad(1.0, -2.0*b*cos(la0), (a*a-1.0)*sin(la0)*sin(la0)+b*b); +# if(n == 0) +# return (la, lo); +# while(--n >= 0){ +# if(n == 1) +# r = r2; +# else +# r = r1; +# if(fabs(r) <= 1.0){ +# lat = asin(r); +# c = cos(lat); +# if(small(c)) +# tmp = 0.0; # lat = +90, -90, lon = lo0 +# else +# tmp = a/c; +# if(fabs(tmp) <= 1.0){ +# for(i = 0; i < 2; i++){ +# if(i == 0) +# lon = norm(asin(tmp)+lo0); +# else +# lon = norm(Pi-asin(tmp)+lo0); +# (X, Y, Z) := lalo2xyz(lat, lon, lalo); +# # eliminate non-roots by d, root on other side of earth by Z +# d = (real X-x)**2+(real Y-y)**2; +# if(Z >= 0 && (bestd < 0.0 || d < bestd)){ +# bestd = d; +# la = lat; +# lo = lon; +# } +# } +# } +# } +# } +# } +# return (la, lo); +# } + +# quad(a: real, b: real, c: real): (int, real, real) +# { +# r1, r2: real; +# +# D := b*b-4.0*a*c; +# if(small(a)){ +# if(small(b)) +# return (0, r1, r2); +# r1 = r2 = -c/b; +# return (1, r1, r2); +# } +# if(D < 0.0) +# return (0, r1, r2); +# D = sqrt(D); +# r1 = (-b+D)/(2.0*a); +# r2 = (-b-D)/(2.0*a); +# if(small(D)) +# return (1, r1, r2); +# else +# return (2, r1, r2); +# } + +d2(v: int): string +{ + s := string v; + if(v < 10) + s = "0" + s; + return s; +} + +trim(s: string, t: string): string +{ + while(s != nil && strchr(t, s[0]) >= 0) + s = s[1: ]; + while(s != nil && strchr(t, s[len s-1]) >= 0) + s = s[0: len s-1]; + return s; +} + +strchrs(s: string, t: string): int +{ + for(i := 0; i < len t; i++){ + p := strchr(s, t[i]); + if(p >= 0) + return p; + } + return -1; +} + +strchr(s: string, c: int): int +{ + for(i := 0; i < len s; i++) + if(s[i] == c) + return i; + return -1; +} + +deg2rad(d: real): real +{ + return d*Pi/180.0; +} + +rad2deg(r: real): real +{ + return r*180.0/Pi; +} + +sec2rad(s: real): real +{ + return deg2rad(s/3600.0); +} + +norm(r: real): real +{ + while(r > Pi) + r -= 2.0*Pi; + while(r < -Pi) + r += 2.0*Pi; + return r; +} + +small(r: real): int +{ + return r > -Epsilon && r < Epsilon; +} + +trunc(r: real): int +{ + # down : assumes r >= 0 + i := int r; + if(real i > r) + i--; + return i; +} + +abs(x: int): int +{ + if(x < 0) + return -x; + return x; +} |
