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