1
0
Fork 0

Convert apt_math functions and runway polygon creation to SGGeod/SGVec3

This commit is contained in:
Christian Schmitt 2012-10-16 17:53:55 +02:00
parent bda3ee3a91
commit 8a12f010f5
8 changed files with 66 additions and 113 deletions

View file

@ -27,12 +27,12 @@
using std::string;
TGPolygon gen_wgs84_area( Point3D origin,
double length_m,
double displ1, double displ2,
double width_m,
double heading_deg,
bool add_mid )
TGPolygon gen_wgs84_area( SGGeod origin,
double length_m,
double displ1, double displ2,
double width_m,
double heading_deg,
bool add_mid )
{
TGPolygon result_list;
double length_hdg = heading_deg;
@ -40,66 +40,44 @@ TGPolygon gen_wgs84_area( Point3D origin,
if ( left_hdg < 0 ) { left_hdg += 360.0; }
// move to the +l end/center of the runway
Point3D ref = origin;
double lon = 0, lat = 0, r = 0;
geo_direct_wgs_84 ( ref.lat(), ref.lon(), length_hdg,
length_m / 2.0 - displ2, &lat, &lon, &r );
ref = Point3D( lon, lat, 0.0 );
SGGeod ref = SGGeodesy::direct( origin, length_hdg, length_m / 2.0 - displ2 );
// move to the l,-w corner (then we add points in a clockwise direction)
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
-width_m / 2.0, &lat, &lon, &r );
Point3D p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
SGGeod p = SGGeodesy::direct( ref, left_hdg, -width_m / 2.0) ;
result_list.add_node( 0, Point3D::fromSGGeod(p) );
// move to the l,w corner
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
p = SGGeodesy::direct( ref, left_hdg, width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
if ( add_mid ) {
// move to the 0,w point (then we add points in a clockwise direction)
ref = origin;
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
p = SGGeodesy::direct( origin, left_hdg, width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
}
// move to the -l end/center of the runway
ref = origin;
geo_direct_wgs_84 ( ref.lat(), ref.lon(), length_hdg,
displ1 - length_m/2.0, &lat, &lon, &r );
ref = Point3D( lon, lat, 0.0 );
ref = SGGeodesy::direct( origin, length_hdg, displ1 - length_m/2.0);
// move to the -l,w corner (then we add points in a clockwise direction)
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
p = SGGeodesy::direct( ref, left_hdg, width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
// move to the -l,-w corner
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
-width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
p = SGGeodesy::direct( ref, left_hdg, -width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
if ( add_mid ) {
// move to the 0,-w point (then we add points in a clockwise direction)
ref = origin;
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
-width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
p = SGGeodesy::direct( origin, left_hdg, -width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
}
return result_list;
}
TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
TGPolygon gen_wgs84_area( SGGeod end1, SGGeod end2,
double length_m,
double displ1, double displ2,
double width_m,
@ -110,61 +88,42 @@ TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
double left_hdg = heading_deg - 90.0;
if ( left_hdg < 0 ) { left_hdg += 360.0; }
// move from end2 to the displaced threshold
Point3D ref = end2;
double lon = 0, lat = 0, r = 0;
geo_direct_wgs_84 ( ref.lat(), ref.lon(), heading_deg,
length_m / 2.0 - displ2, &lat, &lon, &r );
ref = Point3D( lon, lat, 0.0 );
double course1, course2, distance;
SGGeodesy::inverse(end1, end2, course1, course2, distance);
SGGeod center = SGGeodesy::direct(end1, course1, distance/2 );
// move to the l,-w corner (then we add points in a clockwise direction)
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
-width_m / 2.0, &lat, &lon, &r );
Point3D p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
// move from end2 to the displaced threshold
SGGeod ref = SGGeodesy::direct( end2, heading_deg, length_m / 2.0 - displ2);
// move to the l,-w corner
SGGeod p = SGGeodesy::direct(ref, left_hdg, -width_m / 2.0);
result_list.add_node( 0, Point3D::fromSGGeod(p) );
// move to the l,w corner
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
p = SGGeodesy::direct(ref, left_hdg, width_m / 2.0);
result_list.add_node( 0, Point3D::fromSGGeod(p) );
if ( add_mid ) {
// move to the 0,w point (then we add points in a clockwise direction)
ref = Point3D( (end1.lon()+end2.lon())/2.0f, (end1.lat()+end2.lat())/2.0f, 0.0f);
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
// move to the 0,w point
p = SGGeodesy::direct( center, left_hdg, width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
}
// move to the end1 center to the displ. threshold
ref = end1;
geo_direct_wgs_84 ( ref.lat(), ref.lon(), heading_deg,
displ1 - length_m / 2.0, &lat, &lon, &r );
ref = Point3D( lon, lat, 0.0 );
ref = SGGeodesy::direct( end1, heading_deg, displ1 - length_m / 2.0 );
// move to the -l,w corner (then we add points in a clockwise direction)
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
// move to the -l,w corner
p = SGGeodesy::direct( ref, left_hdg, width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
// move to the -l,-w corner
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
-width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
p = SGGeodesy::direct( ref, left_hdg, -width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
if ( add_mid ) {
// move to the 0,-w point (then we add points in a clockwise direction)
ref = Point3D( (end1.lon()+end2.lon())/2.0f, (end1.lat()+end2.lat())/2.0f, 0.0f);
geo_direct_wgs_84 ( ref.lat(), ref.lon(), left_hdg,
-width_m / 2.0, &lat, &lon, &r );
p = Point3D( lon, lat, 0.0 );
result_list.add_node( 0, p );
// move to the 0,-w point
p = SGGeodesy::direct( center, left_hdg, -width_m / 2.0 );
result_list.add_node( 0, Point3D::fromSGGeod(p) );
}
return result_list;

View file

@ -12,18 +12,17 @@
using std::string;
TGPolygon gen_wgs84_area( Point3D origin,
double length_m,
double displ1,
double displ2,
double width_m,
double heading_deg,
TGPolygon gen_wgs84_area( SGGeod origin,
double length_m,
double displ1,
double displ2,
double width_m,
double heading_deg,
bool add_mid );
// This function uses the 2 runway end points for calculation, which
// yields a higher precision
TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
TGPolygon gen_wgs84_area( SGGeod end1, SGGeod end2,
double length_m,
double displ1, double displ2,
double width_m,

View file

@ -135,7 +135,7 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys,
area_side = true;
}
TGPolygon helipad = gen_wgs84_area( Point3D::fromSGGeod(GetLoc()), maxsize, 0, 0, maxsize, heli.heading, false);
TGPolygon helipad = gen_wgs84_area( GetLoc(), maxsize, 0, 0, maxsize, heli.heading, false);
helipad = snap( helipad, gSnap );
string material, shoulder_mat;
if (heli.surface == 1)

View file

@ -66,7 +66,7 @@ private:
// (return result points in degrees)
TGPolygon gen_runway_area_w_extend( double alt_m, double length_extend, double displ1, double displ2, double width_extend )
{
return ( gen_wgs84_area( Point3D::fromSGGeod(GetLoc()), heli.length + 2.0*length_extend, displ1, displ2, heli.width + 2.0*width_extend, heli.heading, false) );
return ( gen_wgs84_area( GetLoc(), heli.length + 2.0*length_extend, displ1, displ2, heli.width + 2.0*width_extend, heli.heading, false) );
}
superpoly_list gen_helipad_lights(double maxsize);

View file

@ -447,21 +447,16 @@ superpoly_list Runway::gen_runway_center_line_lights( bool recip )
Point3D inc;
Point3D pt1, pt2;
double length_hdg;
double lon, lat, r;
if ( recip ) {
length_hdg = rwy.heading + 180.0;
if ( length_hdg > 360.0 ) { length_hdg -= 360.0; }
geo_direct_wgs_84 ( GetEnd().lat(), GetEnd().lon(), length_hdg,
rwy.threshold[get_thresh0(recip)], &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
pt2 = GetStart();
pt1 = Point3D::fromSGGeod( SGGeodesy::direct( GetEnd(), length_hdg, rwy.threshold[get_thresh0(recip)]) );
pt2 = Point3D::fromSGGeod( GetStart() );
} else {
length_hdg = rwy.heading;
geo_direct_wgs_84 ( GetStart().lat(), GetStart().lon(), length_hdg,
rwy.threshold[get_thresh0(recip)], &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
pt2 = GetEnd();
pt1 = Point3D::fromSGGeod( SGGeodesy::direct(GetStart(), length_hdg, rwy.threshold[get_thresh0(recip)]) );
pt2 = Point3D::fromSGGeod( GetEnd() );
}
inc = (pt2 - pt1) / divs;

View file

@ -68,11 +68,11 @@ point_list WaterRunway::GetNodes()
if (buoys){
double heading, az2, length;
// calculate runway heading and length
geo_inverse_wgs_84( lat[0], lon[0], lat[1], lon[1], &heading, &az2, &length );
SGGeodesy::inverse(GetStart().toSGGeod(), GetEnd().toSGGeod(), heading, az2, length);
// create a polygon for the outline and use it to calculate the point list
int divs = (int)(length / 100.0);
TGPolygon area = gen_wgs84_area(Point3D( (lon[0] + lon[1]) / 2 , (lat[0] + lat[1]) / 2, 0),
TGPolygon area = gen_wgs84_area(GetStart().toSGGeod(), GetEnd().toSGGeod(),
length, 0, 0, width, heading, false);
Point3D pt, inc;

View file

@ -19,14 +19,14 @@ public:
Runway(char* def);
Point3D GetStart(void)
SGGeod GetStart()
{
return ( Point3D( rwy.lon[0], rwy.lat[0], 0.0f ));
return SGGeod::fromDeg(rwy.lon[0], rwy.lat[0]);
}
Point3D GetEnd(void)
SGGeod GetEnd()
{
return ( Point3D( rwy.lon[1], rwy.lat[1], 0.0f ));
return SGGeod::fromDeg(rwy.lon[1], rwy.lat[1]);
}
Point3D GetMidpoint(void)

View file

@ -676,8 +676,8 @@ bool Scheduler::AddAirports( long start_pos, float min_lat, float min_lon, float
// we have a winner
{
Runway* runway = new Runway(def);
Point3D start = runway->GetStart();
Point3D end = runway->GetEnd();
Point3D start = Point3D::fromSGGeod(runway->GetStart());
Point3D end = Point3D::fromSGGeod(runway->GetEnd());
if ( (start.x() >= min_lon ) &&
(start.y() >= min_lat ) &&
(start.x() <= max_lon ) &&