1 /*
2  *  This library is free software; you can redistribute it and/or
3  *  modify it under the terms of the GNU Lesser General Public
4  *  License as published by the Free Software Foundation; either
5  *  version 2 of the License, or (at your option) any later version.
6  *
7  *  This library is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  *  Lesser General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  *
16  *  Copyright (C) 2000 - 2005 Petr Kubanek
17  *  Copyright (C) 2011 Petr Kubanek, Institute of Physics <kubanek@fzu.cz>
18  */
19 
20 module nova.airmass;
21 
22 import std.math;
23 import nova.airmass;
24 import nova.utility;
25 
26 extern (C) {
27 
28 /*
29 ** Airmass
30 */
31 
32 /*! \fn double ln_get_airmass (double alt, double airmass_scale)
33 * \param alt            Altitude in degrees
34 * \param airmass_scale  Airmass scale - usually 750.
35 * \return  Airmass for give altitude.
36 */
37 @nogc double ln_get_airmass(double alt, double airmass_scale) nothrow
38 {
39     double a;
40 
41     a = airmass_scale * sin(ln_deg_to_rad(alt));
42     return sqrt(a * a + 2 * airmass_scale + 1) - a;
43 }
44 
45 unittest {
46     auto res = ln_get_airmass(90, 750.0);
47     assert(res == 1, "(Airmass) Airmass at Zenith");
48 
49 }
50 
51 unittest {
52     import std.conv : to;
53     auto res = ln_get_airmass(10, 750.0);
54     assert(fabs(res - 5.64) < 0.1, "(Airmass) Airmass at 10 degrees altitude " ~ to!string(res));
55 }
56 
57 /*! \fn double ln_get_alt_from_airmass (double X, double airmass_scale)
58  * \param X              Airmass
59  * \param airmass_scale  Airmass scale - usually 750.
60  * \return  Altitude for give airmass.
61  */
62 double ln_get_alt_from_airmass(double X, double airmass_scale)
63 {
64     return ln_rad_to_deg(asin((2 * airmass_scale + 1 - X * X) /
65                 (2 * X * airmass_scale)));
66 }
67 
68 unittest {
69     auto res = ln_get_alt_from_airmass(1, 750.0);
70     assert(res == 90, "(Airmass) Altitude at airmass 1");
71 }
72 
73 unittest {
74     import std.format : format;
75     for (double x = -10; x < 90; x += 10.54546456) {
76         auto res = ln_get_alt_from_airmass(ln_get_airmass(x, 750.0), 750.0);
77         assert(fabs(res - x) < 0.000000001, "(Airmass) Altitude->Airmass->Altitude at 10 degrees "
78                 ~ format("%.12f", res) ~ " != " ~ format("%.12f", x));
79     }
80 }
81 
82 }