static void Main(string[] args) { try { EllipticFunction ell = new EllipticFunction(0.1, 1.0); // parameter m = 0.1 // See Abramowitz and Stegun, table 17.1 Console.WriteLine( String.Format( "{0} {1}", ell.K(), ell.E())); double phi = 20 * Math.Acos(-1.0) / 180.0;; // See Abramowitz and Stegun, table 17.6 with // alpha = asin(sqrt(m)) = 18.43 deg and phi = 20 deg Console.WriteLine( String.Format("{0} {1}", ell.E(phi), ell.E(Math.Sin(phi), Math.Cos(phi), Math.Sqrt(1 - ell.k2 * Math.Sin(phi) * Math.Sin(phi))) ) ); // See Carlson 1995, Sec 3. Console.WriteLine(String.Format("RF(1,2,0) = {0}", EllipticFunction.RF(1,2))); Console.WriteLine(String.Format("RF(2,3,4) = {0}", EllipticFunction.RF(2,3,4))); Console.WriteLine(String.Format("RC(0,1/4) = {0}", EllipticFunction.RC(0,0.25))); Console.WriteLine(String.Format("RC(9/4,2) = {0}", EllipticFunction.RC(2.25,2))); Console.WriteLine(String.Format("RC(1/4,-2) = {0}", EllipticFunction.RC(0.25,-2))); Console.WriteLine(String.Format("RJ(0,1,2,3) = {0}", EllipticFunction.RJ(0,1,2,3))); Console.WriteLine(String.Format("RJ(2,3,4,5) = {0}", EllipticFunction.RJ(2,3,4,5))); Console.WriteLine(String.Format("RD(0,2,1) = {0}", EllipticFunction.RD(0,2,1))); Console.WriteLine(String.Format("RD(2,3,4) = {0}", EllipticFunction.RD(2,3,4))); Console.WriteLine(String.Format("RG(0,16,16) = {0}", EllipticFunction.RG(16,16))); Console.WriteLine(String.Format("RG(2,3,4) = {0}", EllipticFunction.RG(2,3,4))); Console.WriteLine(String.Format("RG(0,0.0796,4) = {0}", EllipticFunction.RG(0.0796, 4))); } catch (GeographicErr e) { Console.WriteLine( String.Format( "Caught exception: {0}", e.Message ) ); } }
/// <summary> /// Initialize a new <see cref="TransverseMercatorExact"/> instance with specified equatorial radius, flattening and central scale factor. /// </summary> /// <param name="a">equatorial radius (meters).</param> /// <param name="f">flattening of ellipsoid.</param> /// <param name="k0">central scale factor.</param> /// <param name="extendp">use extended domain.</param> /// <remarks> /// <para> /// The transverse Mercator projection has a branch point singularity at <i>lat</i> = 0 and <i>lon</i> − <i>lon0</i> = 90 (1 − <i>e</i>) /// or (for <see cref="UTM"/>) <i>x</i> = 18381 km, <i>y</i> = 0m. The <paramref name="extendp"/> argument governs where the branch cut is placed. /// With <paramref name="extendp"/> = <see langword="false"/>, the "standard" convention is followed, namely the cut is placed along /// <i>x</i> > 18381 km, <i>y</i> = 0m. /// <see cref="Forward(double, double, double)"/> can be called with any <i>lat</i> and <i>lon</i> then produces the transformation shown /// in Lee, Fig 46. /// <see cref="Reverse(double, double, double)"/> analytically continues this in the ± <i>x</i> direction. /// As a consequence, Reverse may map multiple points to the same geographic location; for example, for <see cref="UTM"/>, /// <i>x</i> = 22051449.037349 m, <i>y</i> = −7131237.022729 m and <i>x</i> = 29735142.378357 m, <i>y</i> = 4235043.607933 m both map to /// <i>lat</i> = −2°, <i>lon</i> = 88°. /// </para> /// <para> /// With <paramref name="extendp"/> = <see langword="true"/>, the branch cut is moved to the lower left quadrant. /// The various symmetries of the transverse Mercator projection can be used to explore the projection on any sheet. /// In this mode the domains of <i>lat</i>, <i>lon</i>, <i>x</i>, and <i>y</i> are restricted to /// <list type="bullet"> /// <item> /// the union of /// <list type="bullet"> /// <item><i>lat</i> in [0, 90] and <i>lon</i> − <i>lon0</i> in [0, 90]</item> /// <item><i>lat</i> in (-90, 0] and <i>lon</i> − <i>lon0</i> in [90 (1 − e), 90]</item> /// </list> /// </item> /// <item> /// the union of /// <list type="bullet"> /// <item><i>x</i>/(<i>k0</i> <i>a</i>) in [0, ∞) and <i>y</i>/(<i>k0</i> <i>a</i>) in [0, E(e2)]</item> /// <item><i>x</i>/(<i>k0</i> <i>a</i>) in [K(1 − <i>e</i>^2) − E(1 − <i>e</i>^2), ∞) and <i>y</i>/(<i>k0</i> <i>a</i>) in (−∞, 0]</item> /// </list> /// </item> /// </list> /// See Sec. 5 of <a href="https://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for a full discussion of the treatment of the branch cut. /// </para> /// <para> /// The method will work for all ellipsoids used in terrestrial geodesy. /// The method cannot be applied directly to the case of a sphere (<i>f</i> = 0) because some the constants characterizing this method diverge in /// that limit, and in practice, <i>f</i> should be larger than about <see cref="DBL_EPSILON"/>. /// However, <see cref="TransverseMercator"/> treats the sphere exactly. /// </para> /// </remarks> public TransverseMercatorExact(double a, double f, double k0, bool extendp = false) { _a = a; _f = f; _k0 = k0; _mu = _f * (2 - _f); _mv = 1 - _mu; _e = Sqrt(_mu); _extendp = extendp; _Eu = new EllipticFunction(_mu); _Ev = new EllipticFunction(_mv); if (!(IsFinite(_a) && _a > 0)) { throw new GeographicException("Equatorial radius is not positive"); } if (!(_f > 0)) { throw new GeographicException("Flattening is not positive"); } if (!(_f < 1)) { throw new GeographicException("Polar semi-axis is not positive"); } if (!(IsFinite(_k0) && _k0 > 0)) { throw new GeographicException("Scale is not positive"); } }
private void OnSet(object sender, EventArgs e) { try { double k2 = Double.Parse(m_k2TextBox.Text); double alpha2 = Double.Parse(m_alpha2TextBox.Text); if (m_constructorComboBox.SelectedIndex == 0) { m_func = new EllipticFunction(k2, alpha2); } else { double kp2 = Double.Parse(m_kp2TextBox.Text); double alphap2 = Double.Parse(m_alphap2TextBox.Text); m_func = new EllipticFunction(k2, alpha2, kp2, alphap2); } m_KtextBox.Text = m_func.K().ToString(); m_EtextBox.Text = m_func.E().ToString(); m_DtextBox.Text = m_func.D().ToString(); m_KEtextBox.Text = m_func.KE().ToString(); m_PItextBox.Text = m_func.Pi().ToString(); m_GtextBox.Text = m_func.G().ToString(); m_HtextBox.Text = m_func.H().ToString(); } catch (Exception xcpt) { MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
static void Main(string[] args) { try { EllipticFunction ell = new EllipticFunction(0.1, 1.0); // parameter m = 0.1 // See Abramowitz and Stegun, table 17.1 Console.WriteLine(String.Format("{0} {1}", ell.K(), ell.E())); double phi = 20 * Math.Acos(-1.0) / 180.0;; // See Abramowitz and Stegun, table 17.6 with // alpha = asin(sqrt(m)) = 18.43 deg and phi = 20 deg Console.WriteLine(String.Format("{0} {1}", ell.E(phi), ell.E(Math.Sin(phi), Math.Cos(phi), Math.Sqrt(1 - ell.k2 * Math.Sin(phi) * Math.Sin(phi))))); // See Carlson 1995, Sec 3. Console.WriteLine(String.Format("RF(1,2,0) = {0}", EllipticFunction.RF(1, 2))); Console.WriteLine(String.Format("RF(2,3,4) = {0}", EllipticFunction.RF(2, 3, 4))); Console.WriteLine(String.Format("RC(0,1/4) = {0}", EllipticFunction.RC(0, 0.25))); Console.WriteLine(String.Format("RC(9/4,2) = {0}", EllipticFunction.RC(2.25, 2))); Console.WriteLine(String.Format("RC(1/4,-2) = {0}", EllipticFunction.RC(0.25, -2))); Console.WriteLine(String.Format("RJ(0,1,2,3) = {0}", EllipticFunction.RJ(0, 1, 2, 3))); Console.WriteLine(String.Format("RJ(2,3,4,5) = {0}", EllipticFunction.RJ(2, 3, 4, 5))); Console.WriteLine(String.Format("RD(0,2,1) = {0}", EllipticFunction.RD(0, 2, 1))); Console.WriteLine(String.Format("RD(2,3,4) = {0}", EllipticFunction.RD(2, 3, 4))); Console.WriteLine(String.Format("RG(0,16,16) = {0}", EllipticFunction.RG(16, 16))); Console.WriteLine(String.Format("RG(2,3,4) = {0}", EllipticFunction.RG(2, 3, 4))); Console.WriteLine(String.Format("RG(0,0.0796,4) = {0}", EllipticFunction.RG(0.0796, 4))); } catch (GeographicErr e) { Console.WriteLine(String.Format("Caught exception: {0}", e.Message)); } }
private void OnSet(object sender, EventArgs e) { try { double k2 = Double.Parse(m_k2TextBox.Text); double alpha2 = Double.Parse(m_alpha2TextBox.Text); if (m_constructorComboBox.SelectedIndex == 0) m_func = new EllipticFunction(k2, alpha2); else { double kp2 = Double.Parse(m_kp2TextBox.Text); double alphap2 = Double.Parse(m_alphap2TextBox.Text); m_func = new EllipticFunction(k2, alpha2, kp2, alphap2); } m_KtextBox.Text = m_func.K().ToString(); m_EtextBox.Text = m_func.E().ToString(); m_DtextBox.Text = m_func.D().ToString(); m_KEtextBox.Text = m_func.KE().ToString(); m_PItextBox.Text = m_func.Pi().ToString(); m_GtextBox.Text = m_func.G().ToString(); m_HtextBox.Text = m_func.H().ToString(); } catch (Exception xcpt) { MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void OnValidate(object sender, EventArgs e) { try { double phi = 0.8; EllipticFunction f = new EllipticFunction(0.3, 0.4, 0.7, 0.6); f.Reset(0.2, 0.3, 0.8, 0.7); f = new EllipticFunction(0.3, 0.4); f.Reset(0.2, 0.3); double cn, sn, dn; f.sncndn(0.3, out sn, out cn, out dn); f.Delta(sn, cn); f.D(); f.D(phi); f.D(sn, cn, dn); f.Pi(); f.Pi(phi); f.Pi(sn, cn, dn); f.KE(); f.K(); f.H(); f.H(phi); f.H(sn, cn, dn); f.G(); f.G(phi); f.G(sn, cn, dn); f.F(phi); f.F(sn, cn, dn); f.Einv(0.75); f.Ed(60.0); f.E(); f.E(phi); f.E(sn, cn, dn); double tau = 3.1415927 / 10.0; f.deltaEinv(Math.Sin(tau), Math.Cos(tau)); f.deltaD(sn, cn, dn); f.deltaE(sn, cn, dn); f.deltaF(sn, cn, dn); f.deltaG(sn, cn, dn); f.deltaH(sn, cn, dn); f.deltaPi(sn, cn, dn); } catch (Exception xcpt) { MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } MessageBox.Show("No errors detected", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information); }