1 /** 2 * \file NETGeographicLib\SphericalHarmonicsPanel.cs 3 * \brief NETGeographicLib Spherical Harmonics example 4 * 5 * NETGeographicLib.CircularEngine, 6 * NETGeographicLib.SphericalHarmonic, 7 * NETGeographicLib.SphericalHarmonic1, and 8 * NETGeographicLib.SphericalHarmonic2 example. 9 * 10 * NETGeographicLib is copyright (c) Scott Heiman (2013) 11 * GeographicLib is Copyright (c) Charles Karney (2010-2012) 12 * <charles@karney.com> and licensed under the MIT/X11 License. 13 * For more information, see 14 * https://geographiclib.sourceforge.io/ 15 **********************************************************************/ 16 using System; 17 using System.Collections.Generic; 18 using System.ComponentModel; 19 using System.Drawing; 20 using System.Data; 21 using System.Linq; 22 using System.Text; 23 using System.Windows.Forms; 24 using NETGeographicLib; 25 26 namespace Projections 27 { 28 public partial class SphericalHarmonicsPanel : UserControl 29 { 30 int N = 3, N1 = 2, N2 = 1; // The maxium degrees 31 double[] C = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients 32 double[] S = {6, 5, 4, 3, 2, 1}; // sine coefficients 33 double[] C1 = {1, 2, 3, 4, 5, 6}; 34 double[] S1 = {3, 2, 1}; 35 double[] C2 = {1, 2, 3}; 36 double[] S2 = {1}; 37 double a = 1; 38 39 SphericalHarmonic m_sh0 = null; 40 SphericalHarmonic1 m_sh1 = null; 41 SphericalHarmonic2 m_sh2 = null; 42 SphericalHarmonicsPanel()43 public SphericalHarmonicsPanel() 44 { 45 InitializeComponent(); 46 try 47 { 48 m_sh0 = new SphericalHarmonic(C, S, N, a, SphericalHarmonic.Normalization.SCHMIDT); 49 m_sh1 = new SphericalHarmonic1(C, S, N, C1, S1, N1, a, SphericalHarmonic1.Normalization.FULL); 50 m_sh2 = new SphericalHarmonic2(C, S, N, C1, S1, N1, C2, S2, N2, a, SphericalHarmonic2.Normalization.FULL); 51 } 52 catch (Exception xcpt) 53 { 54 MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 55 } 56 m_classComboBox.SelectedIndex = 0; 57 } 58 OnClass(object sender, EventArgs e)59 private void OnClass(object sender, EventArgs e) 60 { 61 switch (m_classComboBox.SelectedIndex) 62 { 63 case 0: 64 m_tau1TextBox.ReadOnly = m_tau2TextBox.ReadOnly = true; 65 break; 66 case 1: 67 m_tau1TextBox.ReadOnly = false; 68 m_tau2TextBox.ReadOnly = true; 69 break; 70 case 2: 71 m_tau1TextBox.ReadOnly = m_tau2TextBox.ReadOnly = false; 72 break; 73 } 74 } 75 OnCompute(object sender, EventArgs e)76 private void OnCompute(object sender, EventArgs e) 77 { 78 try 79 { 80 double sum = 0.0, gradx = 0.0, grady = 0.0, gradz = 0.0; 81 double x = Double.Parse(m_xTextBox.Text); 82 double y = Double.Parse(m_yTextBox.Text); 83 double z = Double.Parse(m_zTextBox.Text); 84 switch (m_classComboBox.SelectedIndex) 85 { 86 case 0: 87 sum = m_sh0.HarmonicSum(x, y, z, out gradx, out grady, out gradz); 88 break; 89 case 1: 90 double tau1 = Double.Parse(m_tau1TextBox.Text); 91 sum = m_sh1.HarmonicSum(tau1, x, y, z, out gradx, out grady, out gradz); 92 break; 93 case 2: 94 tau1 = Double.Parse(m_tau1TextBox.Text); 95 double tau2 = Double.Parse(m_tau2TextBox.Text); 96 sum = m_sh2.HarmonicSum(tau1, tau2, x, y, z, out gradx, out grady, out gradz); 97 break; 98 } 99 m_sumTextBox.Text = sum.ToString(); 100 m_gradXTextBox.Text = gradx.ToString(); 101 m_gradYTextBox.Text = grady.ToString(); 102 m_gradZTextBox.Text = gradz.ToString(); 103 } 104 catch (Exception xcpt) 105 { 106 MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 107 } 108 } 109 OnCircularEngine(object sender, EventArgs e)110 private void OnCircularEngine(object sender, EventArgs e) 111 { 112 try 113 { 114 CircularEngine ce = null; 115 double p = Double.Parse(m_circleRadiusTextBox.Text); 116 double z = Double.Parse(m_circleHeightTextBox.Text); 117 double longitude = Double.Parse(m_longitudeTextBox.Text); 118 119 switch (m_classComboBox.SelectedIndex) 120 { 121 case 0: 122 ce = m_sh0.Circle(p, z, true); 123 break; 124 case 1: 125 double tau1 = Double.Parse(m_tau1TextBox.Text); 126 ce = m_sh1.Circle(tau1, p, z, true); 127 break; 128 case 2: 129 tau1 = Double.Parse(m_tau1TextBox.Text); 130 double tau2 = Double.Parse(m_tau2TextBox.Text); 131 ce = m_sh2.Circle(tau1, tau2, p, z, true); 132 break; 133 } 134 double gradx, grady, gradz; 135 m_sumTextBox.Text = ce.LongitudeSum(longitude, out gradx, out grady, out gradz).ToString(); 136 m_gradXTextBox.Text = gradx.ToString(); 137 m_gradYTextBox.Text = grady.ToString(); 138 m_gradZTextBox.Text = gradz.ToString(); 139 } 140 catch (Exception xcpt) 141 { 142 MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 143 } 144 } 145 OnValidate(object sender, EventArgs e)146 private void OnValidate(object sender, EventArgs e) 147 { 148 try 149 { 150 const double DEG_TO_RAD = 3.1415926535897932384626433832795 / 180.0; 151 double gradx, grady, gradz; 152 SphericalHarmonic s0 = new SphericalHarmonic(C, S, N, N - 1, 0, a, SphericalHarmonic.Normalization.SCHMIDT); 153 s0 = new SphericalHarmonic(C, S, N, a, SphericalHarmonic.Normalization.SCHMIDT); 154 double sum = s0.HarmonicSum(1.0, 2.0, 3.0); 155 double test = s0.HarmonicSum(1.0, 2.0, 3.0, out gradx, out grady, out grady); 156 if (sum != test) 157 throw new Exception("Error in SphericalHarmonic.HarmonicSum"); 158 SphericalCoefficients sc = s0.Coefficients(); 159 CircularEngine ce = s0.Circle(1.0, 0.5, true); 160 sum = ce.LongitudeSum(60.0); 161 test = ce.LongitudeSum(Math.Cos(60.0 * DEG_TO_RAD), Math.Sin(60.0 * DEG_TO_RAD)); 162 if ( sum != test ) 163 throw new Exception("Error in CircularEngine.LongitudeSum 1"); 164 test = ce.LongitudeSum(60.0, out gradx, out grady, out gradz); 165 if ( sum != test ) 166 throw new Exception("Error in CircularEngine.LongitudeSum 2"); 167 ce.LongitudeSum(Math.Cos(60.0 * DEG_TO_RAD), Math.Sin(60.0 * DEG_TO_RAD), out gradx, out grady, out gradz); 168 if (sum != test) 169 throw new Exception("Error in CircularEngine.LongitudeSum 3"); 170 SphericalHarmonic1 s1 = new SphericalHarmonic1(C, S, N, N - 1, 1, C1, S1, N1, N1 - 1, 0, a, SphericalHarmonic1.Normalization.SCHMIDT); 171 s1 = new SphericalHarmonic1(C, S, N, C1, S1, N1, a, SphericalHarmonic1.Normalization.SCHMIDT); 172 sum = s1.HarmonicSum(0.95, 1.0, 2.0, 3.0); 173 test = s1.HarmonicSum(0.95, 1.0, 2.0, 3.0, out gradx, out grady, out gradz); 174 if (sum != test) 175 throw new Exception("Error in SphericalHarmonic1.HarmonicSum 3"); 176 ce = s1.Circle(0.95, 1.0, 0.5, true); 177 sc = s1.Coefficients(); 178 sc = s1.Coefficients1(); 179 SphericalHarmonic2 s2 = new SphericalHarmonic2(C, S, N, N - 1, 2, C1, S1, N1, N1 - 1, 1, 180 C2, S2, N2, N2 - 1, 0, a, SphericalHarmonic2.Normalization.SCHMIDT); 181 s2 = new SphericalHarmonic2(C, S, N, C1, S1, N1, C2, S2, N2, a, SphericalHarmonic2.Normalization.SCHMIDT); 182 sum = s2.HarmonicSum(0.95, 0.8, 1.0, 2.0, 3.0); 183 test = s2.HarmonicSum(0.95, 0.8, 1.0, 2.0, 3.0, out gradx, out grady, out gradz); 184 if (sum != test) 185 throw new Exception("Error in SphericalHarmonic2.HarmonicSum 3"); 186 ce = s2.Circle(0.95, 0.8, 1.0, 0.5, true); 187 sc = s2.Coefficients(); 188 sc = s2.Coefficients1(); 189 sc = s2.Coefficients2(); 190 } 191 catch (Exception xcpt) 192 { 193 MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 194 return; 195 } 196 MessageBox.Show("No errors found", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information); 197 } 198 } 199 } 200