ADD: new track message, Entity class and Position class
This commit is contained in:
220
libs/geographiclib/maxima/tmseries.mac
Normal file
220
libs/geographiclib/maxima/tmseries.mac
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
Compute series approximations for Transverse Mercator Projection
|
||||
|
||||
Copyright (c) Charles Karney (2009-2010) <charles@karney.com> and
|
||||
licensed under the MIT/X11 License. For more information, see
|
||||
https://geographiclib.sourceforge.io/
|
||||
|
||||
Reference:
|
||||
|
||||
Charles F. F. Karney,
|
||||
Transverse Mercator with an accuracy of a few nanometers,
|
||||
J. Geodesy 85(8), 475-485 (Aug. 2011).
|
||||
DOI 10.1007/s00190-011-0445-3
|
||||
preprint https://arxiv.org/abs/1002.1417
|
||||
resource page https://geographiclib.sourceforge.io/tm.html
|
||||
|
||||
Compute coefficient for forward and inverse trigonometric series for
|
||||
conversion from conformal latitude to rectifying latitude. This prints
|
||||
out assignments which with minor editing are suitable for insertion into
|
||||
C++ code. (N.B. n^3 in the output means n*n*n; 3/5 means 0.6.)
|
||||
|
||||
To run, start maxima and enter
|
||||
|
||||
writefile("tmseries.out")$
|
||||
load("tmseries.mac")$
|
||||
closefile()$
|
||||
|
||||
With maxpow = 6, the output (after about 5 secs) is
|
||||
|
||||
A=a/(n+1)*(1+n^2/4+n^4/64+n^6/256);
|
||||
alpha[1]=n/2-2*n^2/3+5*n^3/16+41*n^4/180-127*n^5/288+7891*n^6/37800;
|
||||
alpha[2]=13*n^2/48-3*n^3/5+557*n^4/1440+281*n^5/630-1983433*n^6/1935360;
|
||||
alpha[3]=61*n^3/240-103*n^4/140+15061*n^5/26880+167603*n^6/181440;
|
||||
alpha[4]=49561*n^4/161280-179*n^5/168+6601661*n^6/7257600;
|
||||
alpha[5]=34729*n^5/80640-3418889*n^6/1995840;
|
||||
alpha[6]=+212378941*n^6/319334400;
|
||||
beta[1]=n/2-2*n^2/3+37*n^3/96-n^4/360-81*n^5/512+96199*n^6/604800;
|
||||
beta[2]=n^2/48+n^3/15-437*n^4/1440+46*n^5/105-1118711*n^6/3870720;
|
||||
beta[3]=17*n^3/480-37*n^4/840-209*n^5/4480+5569*n^6/90720;
|
||||
beta[4]=4397*n^4/161280-11*n^5/504-830251*n^6/7257600;
|
||||
beta[5]=4583*n^5/161280-108847*n^6/3991680;
|
||||
beta[6]=+20648693*n^6/638668800;
|
||||
|
||||
Notation of output matches that of
|
||||
|
||||
L. Krueger,
|
||||
Konforme Abbildung des Erdellipsoids in der Ebene
|
||||
Royal Prussian Geodetic Institute, New Series 52, 172 pp. (1912).
|
||||
|
||||
with gamma replaced by alpha.
|
||||
|
||||
Alter maxpow to generate more or less terms for the series
|
||||
approximations to the forward and reverse projections. This has been
|
||||
tested out to maxpow = 30; but this takes a long time (see below).
|
||||
|
||||
*/
|
||||
|
||||
/* Timing:
|
||||
maxpow time
|
||||
4 2s
|
||||
6 5s
|
||||
8 11s
|
||||
10 24s
|
||||
12 52s
|
||||
20 813s = 14m
|
||||
30 13535s = 226m
|
||||
*/
|
||||
|
||||
maxpow:8$ /* Max power for forward and reverse projections */
|
||||
/* Notation
|
||||
|
||||
e = eccentricity
|
||||
e2 = e^2 = f*(2-f)
|
||||
n = third flattening = f/(2-f)
|
||||
phi = (complex) geodetic latitude
|
||||
zetap = Gauss-Schreiber TM = complex conformal latitude
|
||||
psi = Mercator = complex isometric latitude
|
||||
zeta = scaled UTM projection = complex rectifying latitude
|
||||
*/
|
||||
|
||||
taylordepth:6$
|
||||
triginverses:'all$
|
||||
/*
|
||||
revert
|
||||
var2 = expr(var1) = series in eps
|
||||
to
|
||||
var1 = revertexpr(var2) = series in eps
|
||||
|
||||
Require that expr(var1) = var1 to order eps^0. This throws in a
|
||||
trigreduce to convert to multiple angle trig functions.
|
||||
*/
|
||||
reverta(expr,var1,var2,eps,pow):=block([tauacc:1,sigacc:0,dsig],
|
||||
dsig:ratdisrep(taylor(expr-var1,eps,0,pow)),
|
||||
dsig:subst([var1=var2],dsig),
|
||||
for n:1 thru pow do (tauacc:trigreduce(ratdisrep(taylor(
|
||||
-dsig*tauacc/n,eps,0,pow))),
|
||||
sigacc:sigacc+expand(diff(tauacc,var2,n-1))),
|
||||
var2+sigacc)$
|
||||
|
||||
/* Expansion for atan(x+eps) for small eps. Equivalent to
|
||||
taylor(atan(x + eps), eps, 0, maxpow) but tidied up a bit.
|
||||
*/
|
||||
atanexp(x,eps):=''(ratdisrep(taylor(atan(x+eps),eps,0,maxpow)))$
|
||||
|
||||
/* Convert from n to e^2 */
|
||||
e2:4*n/(1+n)^2$
|
||||
|
||||
/* zetap in terms of phi. The expansion of
|
||||
atan(sinh( asinh(tan(phi)) + e * atanh(e * sin(phi)) ))
|
||||
*/
|
||||
zetap_phi:block([psiv,tanzetap,zetapv,qq,e],
|
||||
/* Here qq = atanh(sin(phi)) = asinh(tan(phi)) */
|
||||
psiv:qq-e*atanh(e*tanh(qq)),
|
||||
psiv:subst([e=sqrt(e2),qq=atanh(sin(phi))],
|
||||
ratdisrep(taylor(psiv,e,0,2*maxpow)))
|
||||
+asinh(sin(phi)/cos(phi))-atanh(sin(phi)),
|
||||
tanzetap:subst([abs(cos(phi))=cos(phi),sqrt(sin(phi)^2+cos(phi)^2)=1],
|
||||
ratdisrep(taylor(sinh(psiv),n,0,maxpow)))+tan(phi)-sin(phi)/cos(phi),
|
||||
zetapv:atanexp(tan(phi),tanzetap-tan(phi)),
|
||||
zetapv:subst([cos(phi)=sqrt(1-sin(phi)^2),
|
||||
tan(phi)=sin(phi)/sqrt(1-sin(phi)^2)],
|
||||
(zetapv-phi)/cos(phi))*cos(phi)+phi,
|
||||
zetapv:ratdisrep(taylor(zetapv,n,0,maxpow)),
|
||||
expand(trigreduce(zetapv)))$
|
||||
|
||||
/* phi in terms of zetap */
|
||||
phi_zetap:reverta(zetap_phi,phi,zetap,n,maxpow)$
|
||||
|
||||
/* Mean radius of meridian */
|
||||
a1:expand(integrate(
|
||||
ratdisrep(taylor((1+n)*(1-e2)/(1-e2*sin(phi)^2)^(3/2),
|
||||
n,0,maxpow)),
|
||||
phi, 0, %pi/2)/(%pi/2))/(1+n)$
|
||||
|
||||
/* zeta in terms of phi. The expansion of
|
||||
zeta = pi/(2*a1) * int( (1-e^2)/(1-e^2*sin(phi)^2)^(3/2) )
|
||||
*/
|
||||
zeta_phi:block([zetav],
|
||||
zetav:integrate(trigreduce(ratdisrep(taylor(
|
||||
(1-e2)/(1-e2*sin(phi)^2)^(3/2)/a1,
|
||||
n,0,maxpow))),phi),
|
||||
expand(zetav))$
|
||||
|
||||
/* phi in terms of zeta */
|
||||
phi_zeta:reverta(zeta_phi,phi,zeta,n,maxpow)$
|
||||
|
||||
/* zeta in terms of zetap */
|
||||
/* This is slow. The next version speeds it up a little.
|
||||
zeta_zetap:expand(trigreduce(ratdisrep(
|
||||
taylor(subst([phi=phi_zetap],zeta_phi),n,0,maxpow))))$
|
||||
*/
|
||||
zeta_zetap:block([phiv:phi_zetap,zetav:expand(zeta_phi),acc:0],
|
||||
for i:0 thru maxpow do (
|
||||
phiv:ratdisrep(taylor(phiv,n,0,maxpow-i)),
|
||||
acc:acc + expand(n^i * trigreduce(ratdisrep(taylor(
|
||||
subst([phi=phiv],coeff(zetav,n,i)),n,0,maxpow-i))))),
|
||||
acc)$
|
||||
|
||||
/* zetap in terms of zeta */
|
||||
/* This is slow. The next version speeds it up a little.
|
||||
zetap_zeta:expand(trigreduce(ratdisrep(
|
||||
taylor(subst([phi=phi_zeta],zetap_phi),n,0,maxpow))))$
|
||||
*/
|
||||
zetap_zeta:block([phiv:phi_zeta,zetapv:expand(zetap_phi),acc:0],
|
||||
for i:0 thru maxpow do (
|
||||
phiv:ratdisrep(taylor(phiv,n,0,maxpow-i)),
|
||||
acc:acc + expand(n^i * trigreduce(ratdisrep(taylor(
|
||||
subst([phi=phiv],coeff(zetapv,n,i)),n,0,maxpow-i))))),
|
||||
acc)$
|
||||
|
||||
printa1():=block([],
|
||||
print(concat("A=",string(a/(n+1)),"*(",
|
||||
string(taylor(a1*(1+n),n,0,maxpow)),");")),
|
||||
0)$
|
||||
printtxf():=block([alpha:zeta_zetap,t],
|
||||
for i:1 thru maxpow do (t:coeff(alpha,sin(2*i*zetap)),
|
||||
print(concat("alpha[",i,"]=",string(taylor(t,n,0,maxpow)),";")),
|
||||
alpha:alpha-expand(t*sin(2*i*zetap))),
|
||||
/* should return zero */
|
||||
alpha:alpha-zetap)$
|
||||
printtxr():=block([beta:zetap_zeta,t],
|
||||
for i:1 thru maxpow do (t:coeff(beta,sin(2*i*zeta)),
|
||||
print(concat("beta[",i,"]=",string(taylor(-t,n,0,maxpow)),";")),
|
||||
beta:beta-expand(t*sin(2*i*zeta))),
|
||||
/* should return zero */
|
||||
beta:beta-zeta)$
|
||||
|
||||
printseries():=[printa1(),printtxf(),printtxr()]$
|
||||
|
||||
/* Define array functions which are be read by tm.mac */
|
||||
defarrayfuns():=block([aa:a1*(1+n),alpha:zeta_zetap,beta:zetap_zeta,t],
|
||||
for i:1 thru maxpow do (
|
||||
define(a1_a[i](n),ratdisrep(taylor(aa,n,0,i))/(1+n)),
|
||||
t:expand(ratdisrep(taylor(alpha,n,0,i))),
|
||||
define(zeta_a[i](zp,n),
|
||||
zp+sum(coeff(t,sin(2*k*zetap))*sin(2*k*zp),k,1,i)),
|
||||
t:diff(t,zetap),
|
||||
define(zeta_d[i](zp,n),
|
||||
1+sum(coeff(t,cos(2*k*zetap))*cos(2*k*zp),k,1,i)),
|
||||
t:expand(ratdisrep(taylor(beta,n,0,i))),
|
||||
define(zetap_a[i](z,n),
|
||||
z+sum(coeff(t,sin(2*k*zeta))*sin(2*k*z),k,1,i)),
|
||||
t:diff(t,zeta),
|
||||
define(zetap_d[i](z,n),
|
||||
1+sum(coeff(t,cos(2*k*zeta))*cos(2*k*z),k,1,i))))$
|
||||
|
||||
printseries()$
|
||||
(b1:a1,
|
||||
for i:1 thru maxpow do (alp[i]:coeff(zeta_zetap,sin(2*i*zetap)),
|
||||
bet[i]:coeff(expand(-zetap_zeta),sin(2*i*zeta))))$
|
||||
load("polyprint.mac")$
|
||||
printtm():=block([macro:GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER],
|
||||
value1('(b1*(1+n)),'n,2,0),
|
||||
array1('alp,'n,1,0),
|
||||
array1('bet,'n,1,0))$
|
||||
printtm()$
|
||||
/*
|
||||
defarrayfuns()$
|
||||
save("tmseries.lsp",maxpow,arrays)$
|
||||
*/
|
||||
Reference in New Issue
Block a user