]> git.mxchange.org Git - flightgear.git/blob - GenAirports/area.cxx
cfefd744d1635d853a03c0d842854fbeb0379a8b
[flightgear.git] / GenAirports / area.cxx
1 // area.c -- routines to assist with inserting "areas" into FG terrain
2 //
3 // Written by Curtis Olson, started March 1998.
4 //
5 // Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22 // (Log is kept at end of this file)
23 //
24
25
26 #include <math.h>
27 #include <stdio.h>
28
29 #include <Include/fg_constants.h>
30
31 #include "area.hxx"
32
33
34 // calc new x, y for a rotation
35 double rot_x(double x, double y, double theta) {
36     return ( x * cos(theta) + y * sin(theta) );
37 }
38
39
40 // calc new x, y for a rotation
41 double rot_y(double x, double y, double theta) {
42     return ( -x * sin(theta) + y * cos(theta) );
43 }
44
45
46 // calc new lon/lat given starting lon/lat, and offset radial, and
47 // distance.  NOTE: distance is specified in meters (and converted
48 // internally to radians)
49 point2d calc_lon_lat( point2d orig, point2d offset ) {
50     point2d result;
51
52     // printf("calc_lon_lat()  offset.theta = %.2f offset.dist = %.2f\n",
53     //        offset.theta, offset.dist);
54
55     offset.dist *= METER_TO_NM * NM_TO_RAD;
56
57     result.lat = asin( sin(orig.lat) * cos(offset.dist) + 
58                        cos(orig.lat) * sin(offset.dist) * cos(offset.theta) );
59
60     if ( cos(result.lat) < FG_EPSILON ) {
61         result.lon = orig.lon;      // endpoint a pole
62     } else {
63         result.lon = 
64             fmod(orig.lon - asin( sin(offset.theta) * sin(offset.dist) / 
65                                   cos(result.lat) ) + FG_PI, FG_2PI) - FG_PI;
66     }
67
68     return(result);
69 }
70
71
72 point2d cart_to_polar_2d(point2d in) {
73     point2d result;
74     result.dist = sqrt( in.x * in.x + in.y * in.y );
75     result.theta = atan2(in.y, in.x);    
76
77     return(result);
78 }
79
80
81 list < point2d >
82 batch_cart_to_polar_2d( list < point2d > in_list)
83 {
84     list < point2d > out_list;
85     list < point2d > :: iterator current;                          
86     list < point2d > :: iterator last;                    
87     point2d p;
88
89     current = in_list.begin();
90     last = in_list.end();
91     while ( current != last ) {
92         p = cart_to_polar_2d( *current );
93         out_list.push_back(p);
94         current++;
95     }
96
97     return out_list;
98 }
99
100
101 // given a set of 2d coordinates relative to a center point, and the
102 // lon, lat of that center point (specified in degrees), as well as a
103 // potential orientation angle, generate the corresponding lon and lat
104 // of the original 2d verticies.
105 list < point2d >
106 gen_area(point2d origin, double angle, list < point2d > cart_list)
107 {
108     list < point2d > rad_list;
109     list < point2d > result_list;
110     list < point2d > :: iterator current;                          
111     list < point2d > :: iterator last;                    
112     point2d origin_rad, p;
113
114     origin_rad.lon = origin.lon * DEG_TO_RAD;
115     origin_rad.lat = origin.lat * DEG_TO_RAD;
116         
117     // convert to polar coordinates
118     rad_list = batch_cart_to_polar_2d(cart_list);
119
120     /*
121     // display points
122     printf("converted to polar\n");
123     current = rad_list.begin();
124     last = rad_list.end();
125     while ( current != last ) {
126         printf("(%.2f, %.2f)\n", current->theta, current->dist);
127         current++;
128     }
129     printf("\n");
130     */
131
132     // rotate by specified angle
133     // printf("Rotating points by %.2f\n", angle);
134     current = rad_list.begin();
135     last = rad_list.end();
136     while ( current != last ) {
137         current->theta -= angle;
138         while ( current->theta > FG_2PI ) {
139             current->theta -= FG_2PI;
140         }
141         // printf("(%.2f, %.2f)\n", current->theta, current->dist);
142         current++;
143     }
144     // printf("\n");
145
146     // find actual lon,lat of coordinates
147     // printf("convert to lon, lat relative to %.2f %.2f\n", 
148     //        origin.lon, origin.lat);
149     current = rad_list.begin();
150     last = rad_list.end();
151     while ( current != last ) {
152         p = calc_lon_lat(origin_rad, *current);
153         // printf("(%.8f, %.8f)\n", p.lon, p.lat);
154         result_list.push_back(p);
155         current++;
156     }
157     // printf("\n");
158
159     return result_list;
160 }
161
162
163 // generate an area for a runway
164 list < point2d >
165 gen_runway_area( double lon, double lat, double heading, 
166                       double length, double width) 
167 {
168     list < point2d > result_list;
169     list < point2d > tmp_list;
170     list < point2d > :: iterator current;                          
171     list < point2d > :: iterator last;                    
172
173     point2d p;
174     point2d origin;
175     double l, w;
176     int i;
177
178     /*
179     printf("runway: lon = %.2f lat = %.2f hdg = %.2f len = %.2f width = %.2f\n",
180            lon, lat, heading, length, width);
181     */
182
183     origin.lon = lon;
184     origin.lat = lat;
185     l = length / 2.0;
186     w = width / 2.0;
187
188     // generate untransformed runway area vertices
189     p.x =  l; p.y =  w; tmp_list.push_back(p);
190     p.x =  l; p.y = -w; tmp_list.push_back(p);
191     p.x = -l; p.y = -w; tmp_list.push_back(p);
192     p.x = -l; p.y =  w; tmp_list.push_back(p);
193
194     /*
195     // display points
196     printf("Untransformed, unrotated runway\n");
197     current = tmp_list.begin();
198     last = tmp_list.end();
199     while ( current != last ) {
200         printf("(%.2f, %.2f)\n", current->x, current->y);
201         current++;
202     }
203     printf("\n");
204     */
205
206     // rotate, transform, and convert points to lon, lat
207     result_list = gen_area(origin, heading, tmp_list);
208
209     /*
210     // display points
211     printf("Results in radians.\n");
212     current = result_list.begin();
213     last = result_list.end();
214     while ( current != last ) {
215         printf("(%.8f, %.8f)\n", current->lon, current->lat);
216         current++;
217     }
218     printf("\n");
219     */
220
221     return result_list;
222 }
223
224
225 // $Log$
226 // Revision 1.1  1998/09/01 19:34:33  curt
227 // Initial revision.
228 //
229 // Revision 1.1  1998/07/20 12:54:05  curt
230 // Initial revision.
231 //
232 //