]> Pileus Git - ~andy/rsl/blob - range.c
Changes from Bart (2009-10-28)
[~andy/rsl] / range.c
1 /*
2     NASA/TRMM, Code 910.1.
3     This is the TRMM Office Radar Software Library.
4     Copyright (C) 1996, 1997
5             John H. Merritt
6             Space Applications Corporation
7             Vienna, Virginia
8
9     This library is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Library General Public
11     License as published by the Free Software Foundation; either
12     version 2 of the License, or (at your option) any later version.
13
14     This library is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17     Library General Public License for more details.
18
19     You should have received a copy of the GNU Library General Public
20     License along with this library; if not, write to the Free
21     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23 #include <stdio.h>
24 #include <math.h>
25 #include "rsl.h"
26
27 #  define M_PI          3.14159265358979323846
28 #  define M_PI_2        1.57079632679489661923
29 /* Earth radius in km. */
30 double Re = (6374.0*4.0/3.0);
31
32 /********************************************************************/
33 /*                                                                  */
34 /*               RSL_set_earth_rad(double new_Re)                   */
35 /*                                                                  */
36 /*  By: Dennis Flanigan                                             */
37 /*      Applied Research Corporation                                */
38 /*      August 26, 1994                                             */
39 /********************************************************************/
40 void RSL_set_earth_radius(double new_Re)
41 {
42   Re = new_Re;
43 }
44
45 /*********************************************************************/
46 /*                                                                   */
47 /*         void RSL_get_gr_slantr_h                                  */
48 /*   *gr     - ground range in KM.                                   */
49 /*   *slantr - slant range in  KM.                                   */
50 /*   *h      - height in KM.                                         */
51 /*                                                                   */
52 /*  By: John Merritt                                                 */
53 /*      June  7, 1995                                                */
54 /*********************************************************************/
55 void RSL_get_gr_slantr_h(Ray *ray, int i, float *gr, float *slantr, float *h)
56 {
57   *gr = *slantr = *h = 0.0;
58   if (ray == NULL) return;
59   *slantr = i * ray->h.gate_size + ray->h.range_bin1;
60   *slantr /= 1000; /* meters to km */
61   RSL_get_groundr_and_h(*slantr, ray->h.elev, gr, h);
62   return;
63 }
64
65 /*********************************************************************/
66 /*                                                                   */
67 /*         RSL_get_groundr_and_h(sr, elev, &gr, &h)                  */
68 /*                                                                   */
69 /*  By: John Merritt                                                 */
70 /*      Space Applications Corporation                               */
71 /*      July 23, 1994                                                */
72 /*********************************************************************/
73 void RSL_get_groundr_and_h(float slant_r, float elev, float *gr, float *h)
74 {
75 /* Input:
76  *   slant_r - slant range, along the beam, in km.
77  *   elev    - elevation angle, in degrees.
78  * 
79  * Output:
80  *   gr      - Ground range in km.
81  *   h       - Height of data point above earth, in km.
82  */
83   double GR;
84   double H;
85
86   if (slant_r == 0.0) {*h = 0; *gr = 0; return;}
87   elev += 90;
88   H = sqrt( pow(Re,2.0) + pow(slant_r,2.0) - 2*Re*slant_r*cos(elev*M_PI/180.0));
89   if (H != 0.0) {
90         GR = Re * acos( ( pow(Re,2.0) + pow(H,2.0) - pow(slant_r,2.0)) / (2 * Re * H));
91   } else {
92         GR = slant_r;
93         H = Re;
94   }
95   H -= Re;
96   *h = H;
97   *gr = GR;
98
99 }
100
101
102 /*********************************************************************/
103 /*                                                                   */
104 /*          RSL_get_slantr_and_elev(gr, h, &r, &e)                   */
105 /*                                                                   */
106 /*  By: John Merritt                                                 */
107 /*      Space Applications Corporation                               */
108 /*      July 23, 1994                                                */
109 /*                                                                   */
110 /*********************************************************************/
111 void RSL_get_slantr_and_elev(float gr, float h, float *slant_r, float *elev)
112 {
113 /* Input:
114  *   gr      - Ground range in km.
115  *   h       - Height of data point above earth, in km.
116  * 
117  * Output:
118  *   slant_r - slant range, along the beam, in km.
119  *   elev    - elevation angle, in degrees.
120  */
121
122 /* This equation lifted from Dennis Flanigan's rsph.c code. */
123
124   double slant_r_2; /* Slant range squared. */
125   double ELEV;
126   double SLANTR;
127
128   if (gr == 0) {*slant_r = 0; *elev = 0; return;}
129
130   h += Re;
131   
132   slant_r_2 = pow(Re,2.0) + pow(h,2.0) - (2*Re*h*cos(gr/Re));
133   SLANTR = sqrt(slant_r_2);
134
135   ELEV = acos( (pow(Re,2.0) + slant_r_2 - pow(h,2.0)) / (2*Re*(SLANTR)));
136   ELEV *= 180.0/M_PI;
137   ELEV -= 90.0;
138
139   *slant_r = SLANTR;
140   *elev = ELEV;
141 }
142
143
144 /*********************************************************************/
145 /*                                                                   */
146 /*          RSL_get_slantr_and_h(gr, elev, &sr, &h)                  */
147 /*                                                                   */
148 /*  By: John Merritt                                                 */
149 /*      Space Applications Corporation                               */
150 /*      July 23, 1994                                                */
151 /*                                                                   */
152 /*********************************************************************/
153 void RSL_get_slantr_and_h(float gr, float elev, float *slant_r, float *h)
154 {
155 /* Input:
156  *   gr      - Ground range in km.
157  *   elev    - elevation angle, in degrees.
158  * 
159  * Output:
160  *   slant_r - slant range, along the beam, in km.
161  *   h       - Height of data point above earth, in km.
162  */
163
164   double ELEV;
165   double SLANTR;
166   double ALPHA;
167   double BETA;
168   double GAMMA;
169   double A;
170
171   if (gr == 0) {*slant_r = 0; *h = 0; return;}
172
173   ELEV = elev*M_PI/180.0;
174   ALPHA = ELEV + M_PI_2;    /* Elev angle + 90 */
175   GAMMA = gr/Re;
176   BETA = M_PI - (ALPHA + GAMMA);  /* Angle made by Re+h and slant */
177   SLANTR = Re*(sin(GAMMA)/sin(BETA));
178   A = Re*sin(ALPHA)/sin(BETA);
179
180   *h = (float) (A - Re);
181   *slant_r = (float)SLANTR;  
182 }
183