Sun position
Sun position algorithm
instead-of-math.h
Go to the documentation of this file.
1
#ifndef INSTEAD_OF_MATH_H
2
#define INSTEAD_OF_MATH_H
3
/*============================================================================*/
4
/*!\file
5
* \brief instead-of-math.h - header to be included instead of math.h
6
*
7
* \author David Hoadley <vcrumble@westnet.com.au>
8
*
9
* \details
10
* This header needs to be included instead of the standard C library
11
* header math.h, in order to provide some routines that are missing
12
* or possibly missing from math.h. This header will include math.h
13
* for you.
14
*
15
* The reason it must be included instead of math.h is a little
16
* obscure. One of the routines we want is the sincos() routine. Two
17
* versions of math.h actually do have it: The GNU C library does, and
18
* the Apple Clang library also has it, but under a different name.
19
*
20
* The problem is, to gain access to the function, we need to include
21
* the appropriate incantation BEFORE including math.h if we are using
22
* the GNU C library, but we need to add definitions AFTER including
23
* math.h if we are using the Apple Clang library.
24
*
25
* So use this header instead of math.h to look after this problem.
26
*
27
* This header also provides the following missing function:
28
* - normalize()
29
* A proper modulo function. Unlike fmod(), result is
30
* always positive. Used to to normalize a cyclic variable
31
* to a range, e.g. an angle in radian to the range
32
* [0, 2Pi), or an angle in degrees to the range [0, 360.0)
33
*
34
*
35
* \copyright
36
* \parblock
37
* Copyright (c) 2020, David Hoadley <vcrumble@westnet.com.au>
38
* All rights reserved.
39
*
40
* Redistribution and use in source and binary forms, with or without
41
* modification, are permitted provided that the following conditions are met:
42
*
43
* * Redistributions of source code must retain the above copyright notice, this
44
* list of conditions and the following disclaimer.
45
* * Redistributions in binary form must reproduce the above copyright notice,
46
* this list of conditions and the following disclaimer in the documentation
47
* and/or other materials provided with the distribution.
48
*
49
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
50
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
53
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
54
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
55
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
56
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
57
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59
* POSSIBILITY OF SUCH DAMAGE.
60
* \endparblock
61
*
62
*==============================================================================
63
*/
64
#include "
general.h
"
/* Is this a C99 or later compiler? */
65
66
/*
67
* Global #defines and typedefs
68
*/
69
70
71
/*
72
* Global functions available to be called by other modules
73
*/
74
#ifdef __cplusplus
75
extern
"C"
{
76
#endif
77
78
/* -------------- The possible missing sincos() function -------------- */
79
/*! Calculates sine and cosine of an angle. Where the math library supports it,
80
this is more efficient than calling \c sin() and \c cos() separately.
81
\param[in] angle_rad Angle whose sine and cosine is wanted (radian)
82
\param[out] sinA sine of angle \a angle_rad
83
\param[out] cosA cosine of angle \a angle_rad
84
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
85
#if defined(__APPLE__)
86
/* This is the CLANG compiler on an Apple computer (probably a mac). There
87
is a sincos() function available, but it is called __sincos() instead.
88
Re-direct all calls to sincos() to use __sincos() instead. */
89
# include <math.h>
/* Must be done before defining fn below */
90
# if defined (PREDEF_STANDARD_C_1999)
91
/* Compiler supports inline functions */
92
static
inline
void
sincos
(
double
angle_rad,
double
*sinA,
double
*cosA)
93
{
94
__sincos(angle_rad, sinA, cosA);
95
}
96
# else
97
/* C89/C90 compiler - no inline functions. Need macros instead */
98
#define sincos(angle_rad_, sinA_, cosA_) __sincos(angle_rad_, sinA_, cosA_)
99
# endif
100
101
#elif defined(__GNUC__)
102
/* This is the GNU C compiler. There is a sincos() function available in
103
the GNU C library, but it is only accessible if the following macro is
104
defined BEFORE including <math.h>. So do it here. */
105
# define _GNU_SOURCE
106
# include <math.h>
107
108
#else
109
/* No sincos() function available. Oh well. Get sine and cosine separately.
110
This is less efficient than a true sincos(), but at least it will work.*/
111
# include <math.h>
112
# if defined (PREDEF_STANDARD_C_1999)
113
/* Compiler supports inline functions */
114
static
inline
void
sincos
(
double
angle_rad,
double
*sinA,
double
*cosA)
115
{
116
*sinA = sin(angle_rad);
117
*cosA = cos(angle_rad);
118
}
119
# else
120
/* C89/C90 compiler - no inline functions. Need macros instead */
121
#define sincos(angle_rad_, sinA_, cosA_) \
122
{ *sinA_ = sin(angle_rad_); \
123
*cosA_ = cos(angle_rad_); }
124
# endif
125
#endif
126
127
128
/* -------------- The definitely missing normalize() function -------------- */
129
130
/*! Normalizes a cyclic double precision floating point variable \a x
131
to the interval [0, range), assuming \a range is > 0. (If \a range is
132
negative, this will normalize \a x to the interval (range, 0], but this is
133
not the main use case for this function.)
134
\returns The value of \a x, within the range [0, range)
135
\param[in] x The variable (e.g. an angle in degrees or radian)
136
\param[in] range The range to normalize \a x to (e.g. 2Pi or 360.0). It must
137
be non-zero.
138
139
This function returns the same results as \c fmod() for positive \a x and
140
\a range. Where it differs is in its handling of negative values of \a x.
141
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
142
#if defined (PREDEF_STANDARD_C_1999)
143
/* Compiler supports inline functions */
144
static
inline
double
normalize
(
double
x,
double
range)
145
{
146
return
x - floor(x / range) * range;
147
}
148
#else
149
/* C89/C90 compiler - no inline functions. Need macros instead */
150
#define normalize(x__, range__) ((x__) - floor((x__) / (range__)) * (range__))
151
#endif
152
153
154
/*
155
* Global variables accessible by other modules
156
*/
157
158
159
#ifdef __cplusplus
160
}
161
#endif
162
163
#endif
/* INSTEAD_OF_MATH_H */
164
general.h
general.h - definitions of general use to (standard) C programs
sincos
static void sincos(double angle_rad, double *sinA, double *cosA)
Calculates sine and cosine of an angle.
Definition:
instead-of-math.h:114
normalize
static double normalize(double x, double range)
Normalizes a cyclic double precision floating point variable x to the interval [0,...
Definition:
instead-of-math.h:144
src
instead-of-math.h
Generated by
1.8.17