AstroLibrary
324 строки · 7.6 Кб
1//------------------------------------------------------------------------------
2//
3// File: Coco.cpp
4//
5// Coordinate transformations
6//
7// The original Fortran/Pascal/C++ codes is described in
8//
9// - Shampine, Gordon: "Computer solution of Ordinary Differential Equations",
10// Freeman and Comp., San Francisco (1975)
11// - Montenbruck O., Pfleger T.: Astronomie Mit Dem Personal Computer.
12// Springer-Verlag Berlin Heidelberg (1989).
13// - Montenbruck O., Pfleger T.: Astronomy on the Personal Computer.
14// Springer-Verlag Berlin Heidelberg (2000).
15//------------------------------------------------------------------------------
16
17#include <iomanip>
18//#include <stdio.h> // Header file for standard Input/Output
19
20#include "APC_Const.h"
21#include "APC_Math.h"
22#include "APC_PrecNut.h"
23#include "APC_Spheric.h"
24#include "APC_Sun.h"
25#include "APC_Time.h"
26#include "APC_VecMat3D.h"
27
28#ifdef __GNUC__ // GNU C++ Adaptations
29#include <ctype.h>
30#include "GNU_iomanip.h"
31#endif
32
33#pragma argsused
34
35using namespace std;
36
37//
38// Types
39//
40enum enOrigin { Heliocentric, Geocentric }; // Origin of coordinates
41enum enRefSys { Ecliptic, Equator }; // Reference system
42
43//
44// Definition of class "Position"
45//
46class Position
47{
48public:
49void Input(); // Query user for parameters
50void SetOrigin(enOrigin Origin);
51void SetRefSys(enRefSys RefSys);
52void SetEquinox(double T_Equinox);
53void Print();
54private:
55Vec3D m_R; // Coordinate vector
56enOrigin m_Origin; // Origin of coordinate system
57enRefSys m_RefSys; // Reference system
58double m_TEquinox; // Equinox (cent. since J2000)
59double m_MjdEpoch; // Epoch (Modif. Julian Date)
60};
61
62
63//
64// Data input
65//
66void Position::Input()
67{
68//
69// Variables
70//
71char c;
72
73
74// Header
75cout << endl << "New input:" << endl << endl;
76
77
78// Query reference system
79while (true) {
80
81cout << " Reference system (e=ecliptic,a=equator) ... ";
82cin >> c; cin.ignore(81,'\n'); c = tolower(c);
83
84if (c=='e') { m_RefSys=Ecliptic; break; };
85if (c=='a') { m_RefSys=Equator; break; };
86}
87
88
89// Query coordinates
90while (true) {
91
92cout << " Format (c=cartesian,p=polar) ... ";
93cin >> c; cin.ignore(81,'\n'); c = tolower(c);
94
95if (c=='c') {
96double x,y,z;
97cout << " Coordinates (x y z) ... ";
98cin >> x >> y >> z;
99m_R = Vec3D(x,y,z);
100break;
101};
102
103if (c=='p') {
104
105if (m_RefSys==Ecliptic) {
106
107int d,m;
108double s, L,B,R;
109cout << " Coordinates (L [o ' \"] B[o ' \"] R) ... ";
110cin >> d >> m >> s; L=Rad*Ddd(d,m,s);
111cin >> d >> m >> s; B=Rad*Ddd(d,m,s);
112cin >> R; cin.ignore(81,'\n');
113m_R = Vec3D(Polar(L,B,R));
114}
115
116else {
117
118int d,m;
119double s, Ra,Dec,R;
120cout << " Coordinates (Ra [h m s] Dec [o ' \"] R) ... ";
121cin >> d >> m >> s; Ra=15.0*Rad*Ddd(d,m,s);
122cin >> d >> m >> s; Dec=Rad*Ddd(d,m,s);
123cin >> R; cin.ignore(81,'\n');
124m_R = Vec3D(Polar(Ra,Dec,R));
125};
126break;
127};
128}
129
130
131// Query equinox
132double Year;
133
134cout << " Equinox (yyyy.y) ... ";
135cin >> Year; cin.ignore(81,'\n');
136
137m_TEquinox = (Year-2000.0)/100.0;
138
139// Query origin
140while (true) {
141
142cout << " Origin (h=heliocentric,g=geocentric) ... ";
143cin >> c; cin.ignore(81,'\n'); c = tolower(c);
144
145if (c=='g') { m_Origin=Geocentric; break; };
146if (c=='h') { m_Origin=Heliocentric; break; };
147}
148
149
150// Query epoch
151int year,month,day;
152double Hour;
153
154cout << " Epoch (yyyy mm dd hh.h) ... ";
155cin >> year >> month >> day >> Hour; cin.ignore(81,'\n');
156m_MjdEpoch = Mjd(year,month,day)+Hour/24.0;
157cout << endl; // Trailer
158}
159
160
161//
162// Change of origin
163//
164void Position::SetOrigin(enOrigin Origin)
165{
166//
167// Variables
168//
169double T_Epoch;
170Vec3D R_Sun;
171
172if (Origin!=m_Origin) {
173// Geocentric coordinates of the Sun at epoch w.r.t.
174// given reference system and equinox
175T_Epoch = (m_MjdEpoch-MJD_J2000)/36525.0;
176if (m_RefSys==Ecliptic)
177R_Sun = PrecMatrix_Ecl(T_Epoch,m_TEquinox) * SunPos(T_Epoch);
178else
179R_Sun = Ecl2EquMatrix(m_TEquinox) *
180PrecMatrix_Ecl(T_Epoch,m_TEquinox) * SunPos(T_Epoch);
181// Change origin
182if (m_Origin==Heliocentric) {
183m_R += R_Sun; m_Origin = Geocentric;
184}
185else {
186m_R -= R_Sun; m_Origin = Heliocentric;
187};
188};
189}
190
191//
192// Change of reference system
193//
194void Position::SetRefSys(enRefSys RefSys)
195{
196if (RefSys!=m_RefSys) {
197if (m_RefSys==Equator) {
198m_R = Equ2EclMatrix(m_TEquinox) * m_R; m_RefSys = Ecliptic;
199}
200else {
201m_R = Ecl2EquMatrix(m_TEquinox) * m_R; m_RefSys = Equator;
202}
203};
204}
205
206//
207// Change of equinox
208//
209void Position::SetEquinox(double T_Equinox)
210{
211if (T_Equinox!=m_TEquinox) {
212if (m_RefSys==Equator)
213m_R = PrecMatrix_Equ(m_TEquinox,T_Equinox) * m_R;
214else
215m_R = PrecMatrix_Ecl(m_TEquinox,T_Equinox) * m_R;
216m_TEquinox = T_Equinox;
217};
218}
219
220//
221// Output
222//
223void Position::Print()
224{
225cout << endl;
226cout << (( m_Origin==Heliocentric )? "Heliocentric " : "Geocentric ");
227cout << (( m_RefSys==Equator )? "equatorial " : "ecliptic ");
228cout << "coordinates" << endl;
229
230cout << "(Equinox J" << fixed << setprecision(1)
231<< 2000.0+m_TEquinox*100.0 << ", ";
232
233cout << "Epoch " << DateTime(m_MjdEpoch,HHh) << ")" << endl;
234cout << endl;
235
236cout << " (x,y,z) = " << fixed << setprecision(8) << setw(12) << m_R << endl;
237
238if ( m_RefSys==Equator ) {
239cout << " h m s o ' \"" << endl;
240cout << " Ra = " << setprecision(2) << setw(11)
241<< Angle(Deg*m_R[phi]/15.0,DMMSSs);
242cout << " Dec = " << setprecision(1) << showpos << setw(11)
243<< Angle(Deg*m_R[theta],DMMSSs) << noshowpos;
244}
245else {
246cout << " o ' \" o ' \"" << endl;
247cout << " L = " << setprecision(2) << setw(12)
248<< Angle(Deg*m_R[phi],DMMSSs);
249cout << " B = " << setprecision(1) << showpos << setw(11)
250<< Angle(Deg*m_R[theta],DMMSSs) << noshowpos;
251}
252cout << " R = " << setprecision(8) << setw(12)
253<< m_R[r] << endl;
254cout << endl << endl;
255}
256
257
258//------------------------------------------------------------------------------
259//
260// Main program
261//
262//------------------------------------------------------------------------------
263void main(int argc, _TCHAR* argv[]) {
264
265//
266// Variables
267//
268Position Pos;
269char c;
270bool End = false;
271double Year;
272
273// Header
274cout << endl
275<< " COCO: coordinate conversions " << endl
276<< " (c) 1999 Oliver Montenbruck, Thomas Pfleger" << endl
277<< endl;
278
279// Initialization
280Pos.Input();
281Pos.Print();
282
283
284// Command loop
285do {
286// Command input
287cout << "Enter command (?=Help) ... ";
288cin >> c; cin.ignore(81,'\n'); c=tolower(c);
289
290// Actions
291switch (c) {
292case 'x':
293End = true; break;
294case 'a':
295Pos.SetRefSys(Equator); Pos.Print(); break;
296case 'e':
297Pos.SetRefSys(Ecliptic); Pos.Print(); break;
298case 'g':
299Pos.SetOrigin(Geocentric); Pos.Print(); break;
300case 'h':
301Pos.SetOrigin(Heliocentric); Pos.Print(); break;
302case 'n':
303Pos.Input(); Pos.Print(); break;
304case 'p':
305cout << "New equinox (yyyy.y) ... ";
306cin >> Year; cin.ignore(81,'\n');
307Pos.SetEquinox( (Year-2000.0)/100.0 );
308Pos.Print();
309break;
310default:
311// Display help text
312cout << endl
313<< "Available commands" << endl
314<< " a=equatorial, e=ecliptic, p=precession, " << endl
315<< " g=geocentric, h=heliocentric, n=new input, " << endl
316<< " x=exit " << endl
317<< endl;
318break;
319}
320}
321while (!End);
322
323cout << endl;
324}
325