1
0
Fork 0

Implement two runway end designations for precision runway

This commit is contained in:
Christian Schmitt 2011-09-13 13:38:30 +02:00
parent 0e83e180fc
commit 8ac29ac8a8
12 changed files with 59 additions and 1288 deletions

View file

@ -3,7 +3,6 @@
add_executable(genapts850
apt_surface.hxx apt_surface.cxx
build.cxx build.hxx
convex_hull.cxx convex_hull.hxx
elevations.cxx elevations.hxx
global.hxx
lights.hxx lights.cxx
@ -12,10 +11,8 @@ add_executable(genapts850
poly_extra.cxx poly_extra.hxx
runway.cxx runway.hxx
rwy_common.cxx rwy_common.hxx
rwy_nonprec.cxx rwy_nonprec.hxx
rwy_gen.cxx rwy_gen.hxx
rwy_simple.cxx rwy_simple.hxx
rwy_visual.cxx rwy_visual.hxx
taxiway.cxx taxiway.hxx
texparams.hxx
)

View file

@ -57,17 +57,14 @@
#include <Triangulate/trieles.hxx>
#include "apt_surface.hxx"
#include "convex_hull.hxx"
#include "elevations.hxx"
#include "lights.hxx"
#include "point2d.hxx"
#include "poly_extra.hxx"
#include "runway.hxx"
#include "rwy_common.hxx"
#include "rwy_nonprec.hxx"
#include "rwy_gen.hxx"
#include "rwy_simple.hxx"
#include "rwy_visual.hxx"
#include "taxiway.hxx"
#include "texparams.hxx"
@ -291,19 +288,19 @@ static void build_runway( const TGRunway& rwy_info,
rwy_polys, texparams, accum );
} else if ( rwy_info.marking_code == 3 /* Precision */ ) {
// precision runway markings
gen_precision_rwy( rwy_info, alt_m, material,
gen_rwy( rwy_info, alt_m, material,
rwy_polys, texparams, accum );
} else if ( rwy_info.marking_code == 2 /* Non-precision */ ) {
// non-precision runway markings
gen_non_precision_rwy( rwy_info, alt_m, material,
gen_rwy( rwy_info, alt_m, material,
rwy_polys, texparams, accum );
} else if ( rwy_info.marking_code == 1 /* Visual */ ) {
// visual runway markings
gen_visual_rwy( rwy_info, alt_m, material,
gen_rwy( rwy_info, alt_m, material,
rwy_polys, texparams, accum );
} else if ( rwy_info.marking_code == 0 /* No known markings, lets assume Visual */ ) {
// visual runway markings
gen_visual_rwy( rwy_info, alt_m, material,
gen_rwy( rwy_info, alt_m, material,
rwy_polys, texparams, accum );
} else if ( surface_code == 13 /* Water buoys */ ) {
// do nothing for now.
@ -675,9 +672,6 @@ void build_airport( string airport_id, float alt_m,
return;
}
// generate convex hull (no longer)
// TGPolygon hull = convex_hull(apt_pts);
TGPolygon filled_base = tgPolygonStripHoles( apt_base );
// write_polygon( filled_base, "base" );
TGPolygon divided_base = tgPolygonSplitLongEdges( filled_base, 200.0 );

View file

@ -1,252 +0,0 @@
// convex_hull.cxx -- calculate the convex hull of a set of points
//
// Written by Curtis Olson, started September 1998.
//
// Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: convex_hull.cxx,v 1.12 2004-11-19 22:25:49 curt Exp $
//
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <math.h>
#include <stdio.h>
#include <map>
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/structure/exception.hxx>
#include <simgear/constants.h>
#include "convex_hull.hxx"
#include "point2d.hxx"
using std::less;
using std::map;
// stl map typedefs
typedef map < double, double, less<double> > map_container;
typedef map_container::iterator map_iterator;
// Calculate theta of angle (a, b, c)
double calc_angle(Point3D a, Point3D b, Point3D c) {
Point3D u, v;
double udist, vdist, uv_dot, tmp;
// u . v = ||u|| * ||v|| * cos(theta)
u.setx( b.x() - a.x() );
u.sety( b.y() - a.y() );
udist = sqrt( u.x() * u.x() + u.y() * u.y() );
// printf("udist = %.6f\n", udist);
v.setx( b.x() - c.x() );
v.sety( b.y() - c.y() );
vdist = sqrt( v.x() * v.x() + v.y() * v.y() );
// printf("vdist = %.6f\n", vdist);
uv_dot = u.x() * v.x() + u.y() * v.y();
// printf("uv_dot = %.6f\n", uv_dot);
tmp = uv_dot / (udist * vdist);
// printf("tmp = %.6f\n", tmp);
return acos(tmp);
}
// Test to see if angle(Pa, Pb, Pc) < 180 degrees
bool test_point(Point3D Pa, Point3D Pb, Point3D Pc) {
double a1, a2;
Point3D origin( 0.0 );
Point3D a( cos(Pa.y()) * Pa.x(),
sin(Pa.y()) * Pa.x(), 0 );
Point3D b( cos(Pb.y()) * Pb.x(),
sin(Pb.y()) * Pb.x(), 0 );
Point3D c( cos(Pc.y()) * Pc.x(),
sin(Pc.y()) * Pc.x(), 0 );
// printf("a is %.6f %.6f\n", a.x, a.y);
// printf("b is %.6f %.6f\n", b.x, b.y);
// printf("c is %.6f %.6f\n", c.x, c.y);
a1 = calc_angle(a, b, origin);
a2 = calc_angle(origin, b, c);
// printf("a1 = %.2f a2 = %.2f\n", a1 * SGD_RADIANS_TO_DEGREES, a2 * SGD_RADIANS_TO_DEGREES);
return ( (a1 + a2) < SGD_PI );
}
// calculate the convex hull of a set of points, return as a list of
// point2d. The algorithm description can be found at:
// http://riot.ieor.berkeley.edu/riot/Applications/ConvexHull/CHDetails.html
TGPolygon convex_hull( const point_list& input_list ) {
int i;
map_iterator map_current, map_next, map_next_next, map_last;
// list of translated points
point_list trans_list;
// points sorted by radian degrees
map_container radians_map;
// will contain the convex hull
TGPolygon con_hull;
Point3D p, Pa, Pb, Pc, result;
double sum_x, sum_y;
int in_count, last_size;
// STEP ONE: Find an average midpoint of the input set of points
in_count = input_list.size();
sum_x = sum_y = 0.0;
for ( i = 0; i < in_count; ++i ) {
sum_x += input_list[i].x();
sum_y += input_list[i].y();
}
Point3D average( sum_x / in_count, sum_y / in_count, 0 );
// printf("Average center point is %.4f %.4f\n", average.x, average.y);
// STEP TWO: Translate input points so average is at origin
trans_list.clear();
for ( i = 0; i < in_count; ++i ) {
p = Point3D( input_list[i].x() - average.x(),
input_list[i].y() - average.y(), 0 );
// printf("%.6f %.6f\n", p.x, p.y);
trans_list.push_back( p );
}
// STEP THREE: convert to radians and sort by theta
radians_map.clear();
for ( i = 0; i < in_count; ++i ) {
p = cart_to_polar_2d( trans_list[i] );
if ( p.x() > radians_map[p.y()] ) {
radians_map[p.y()] = p.x();
}
}
/*
// printf("Sorted list\n");
map_current = radians_map.begin();
map_last = radians_map.end();
for ( ; map_current != map_last ; ++map_current ) {
p.setx( (*map_current).first );
p.sety( (*map_current).second );
printf("p is %.6f %.6f\n", p.x(), p.y());
}
*/
// STEP FOUR: traverse the sorted list and eliminate everything
// not on the perimeter.
// printf("Traversing list\n");
// double check list size ... this should never fail because a
// single runway will always generate four points.
if ( radians_map.size() < 3 ) {
throw sg_exception("convex hull not possible with < 3 points");
}
// ensure that we run the while loop at least once
last_size = radians_map.size() + 1;
while ( last_size > (int)radians_map.size() ) {
// printf("Running an iteration of the graham scan algorithm\n");
last_size = radians_map.size();
map_current = radians_map.begin();
while ( map_current != radians_map.end() ) {
// get first element
Pa.sety( (*map_current).first );
Pa.setx( (*map_current).second );
// get second element
map_next = map_current;
++map_next;
if ( map_next == radians_map.end() ) {
map_next = radians_map.begin();
}
Pb.sety( (*map_next).first );
Pb.setx( (*map_next).second );
// get third element
map_next_next = map_next;
++map_next_next;
if ( map_next_next == radians_map.end() ) {
map_next_next = radians_map.begin();
}
Pc.sety( (*map_next_next).first );
Pc.setx( (*map_next_next).second );
// printf("Pa is %.6f %.6f\n", Pa.y(), Pa.x());
// printf("Pb is %.6f %.6f\n", Pb.y(), Pb.x());
// printf("Pc is %.6f %.6f\n", Pc.y(), Pc.x());
if ( test_point(Pa, Pb, Pc) ) {
// printf("Accepted a point\n");
// accept point, advance Pa, Pb, and Pc.
++map_current;
} else {
// printf("REJECTED A POINT\n");
// reject point, delete it and advance only Pb and Pc
map_next = map_current;
++map_next;
if ( map_next == radians_map.end() ) {
map_next = radians_map.begin();
}
radians_map.erase( map_next );
}
}
}
// translate back to correct lon/lat
// printf("Final sorted convex hull\n");
con_hull.erase();
map_current = radians_map.begin();
map_last = radians_map.end();
for ( ; map_current != map_last ; ++map_current ) {
p.sety( (*map_current).first );
p.setx( (*map_current).second );
result.setx( cos(p.y()) * p.x() + average.x() );
result.sety( sin(p.y()) * p.x() + average.y() );
// printf("%.6f %.6f\n", result.x, result.y);
con_hull.add_node(0, result);
}
return con_hull;
}

View file

@ -1,47 +0,0 @@
// convex_hull.hxx -- calculate the convex hull of a set of points
//
// Written by Curtis Olson, started September 1998.
//
// Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: convex_hull.hxx,v 1.5 2004-11-19 22:25:49 curt Exp $
//
#ifndef _CONVEX_HULL_HXX
#define _CONVEX_HULL_HXX
#include <list>
#include <simgear/math/sg_types.hxx>
#include <Polygon/polygon.hxx>
#include "point2d.hxx"
// calculate the convex hull of a set of points, return as a list of
// point2d. The algorithm description can be found at:
// http://riot.ieor.berkeley.edu/riot/Applications/ConvexHull/CHDetails.html
TGPolygon convex_hull( const point_list& input_list );
#endif // _CONVEX_HULL_HXX

View file

@ -52,7 +52,6 @@
#include <Geometry/util.hxx>
#include "build.hxx"
#include "convex_hull.hxx"
using std::vector;
using std::cout;

View file

@ -1,4 +1,4 @@
// rwy_prec.cxx -- Build a precision runway
// rwy_gen.cxx -- Build a runway
//
// Written by Curtis Olson, started February 2002.
//
@ -18,7 +18,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: rwy_prec.cxx,v 1.18 2004-11-19 22:25:49 curt Exp $
// $Id: rwy_gen.cxx,v 1.18 2004-11-19 22:25:49 curt Exp $
//
#include <simgear/compiler.h>
@ -26,26 +26,25 @@
#include <simgear/debug/logstream.hxx>
#include "rwy_common.hxx"
#include "rwy_nonprec.hxx"
#include <stdlib.h>
using std::string;
// generate a precision approach runway. The routine modifies
// generate a runway. The routine modifies
// rwy_polys, texparams, and accum. For specific details and
// dimensions of precision runway markings, please refer to FAA
// document AC 150/5340-1H
void gen_precision_rwy( const TGRunway& rwy_info,
void gen_rwy( const TGRunway& rwy_info,
double alt_m,
const string& material,
superpoly_list *rwy_polys,
texparams_list *texparams,
TGPolygon *accum )
{
SG_LOG( SG_GENERAL, SG_INFO, "Building runway = " << rwy_info.rwy_no1 << rwy_info.rwy_no2);
SG_LOG( SG_GENERAL, SG_INFO, "Building runway = " << rwy_info.rwy_no1 << " / " << rwy_info.rwy_no2);
//
// Generate the basic runway outlines
@ -242,26 +241,38 @@ void gen_precision_rwy( const TGRunway& rwy_info,
//
int len = rwy_info.rwy_no1.length();
string letter = "";
string rev_letter = "";
string letter1 = "";
string letter2 = "";
for ( i = 0; i < len; ++i ) {
string tmp = rwy_info.rwy_no1.substr(i, 1);
if ( tmp == "L" ) {
letter = "L";
rev_letter = "R";
letter1 = "L";
} else if ( tmp == "R" ) {
letter = "R";
rev_letter = "L";
letter1 = "R";
} else if ( tmp == "C" ) {
letter = "C";
rev_letter = "C";
letter1 = "C";
}
}
len = rwy_info.rwy_no2.length();
for ( i = 0; i < len; ++i ) {
string tmp = rwy_info.rwy_no2.substr(i, 1);
if ( tmp == "L" ) {
letter2 = "L";
} else if ( tmp == "R" ) {
letter2 = "R";
} else if ( tmp == "C" ) {
letter2 = "C";
}
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation = " << rwy_info.rwy_no1);
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation letter = " << letter);
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation1 = " << rwy_info.rwy_no1);
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation letter1 = " << letter1);
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation2 = " << rwy_info.rwy_no2);
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation letter2 = " << letter2);
if ( !letter.empty() ) {
//TODO: add empty airport end generation
if ( !letter1.empty() && !letter2.empty() ) {
start1_pct = end1_pct;
end1_pct = start1_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_a,
@ -269,7 +280,7 @@ void gen_precision_rwy( const TGRunway& rwy_info,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, rev_letter,
material, letter2,
rwy_polys, texparams, accum );
start2_pct = end2_pct;
@ -279,7 +290,7 @@ void gen_precision_rwy( const TGRunway& rwy_info,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, letter,
material, letter1,
rwy_polys, texparams, accum );
}
@ -288,33 +299,44 @@ void gen_precision_rwy( const TGRunway& rwy_info,
//
len = rwy_info.rwy_no1.length();
string snum = rwy_info.rwy_no1;
string snum1 = rwy_info.rwy_no1;
for ( i = 0; i < len; ++i ) {
string tmp = rwy_info.rwy_no1.substr(i, 1);
if ( tmp == "L" || tmp == "R" || tmp == "C" || tmp == " " ) {
snum = rwy_info.rwy_no1.substr(0, i);
snum1 = rwy_info.rwy_no1.substr(0, i);
}
}
SG_LOG(SG_GENERAL, SG_INFO, "Runway num = '" << snum << "'");
int num = atoi( snum.c_str() );
while ( num <= 0 ) {
num += 36;
len = rwy_info.rwy_no2.length();
string snum2 = rwy_info.rwy_no2;
for ( i = 0; i < len; ++i ) {
string tmp = rwy_info.rwy_no2.substr(i, 1);
if ( tmp == "L" || tmp == "R" || tmp == "C" || tmp == " " ) {
snum2 = rwy_info.rwy_no2.substr(0, i);
}
}
SG_LOG(SG_GENERAL, SG_INFO, "Runway num1 = '" << snum1 << "'");
SG_LOG(SG_GENERAL, SG_INFO, "Runway num2 = '" << snum2 << "'");
int num1 = atoi( snum1.c_str() );
int num2 = atoi( snum2.c_str() );
while ( num1 <= 0 ) {
num1 += 36;
}
start2_pct = end2_pct;
end2_pct = start2_pct + ( 80.0 / length );
gen_number_block( rwy_info, material, runway_b, rwy_info.heading + 180.0,
num, start2_pct, end2_pct, rwy_polys, texparams, accum );
num1, start2_pct, end2_pct, rwy_polys, texparams, accum );
num += 18;
while ( num > 36 ) {
num -= 36;
while ( num2 <= 0 ) {
num2 += 36;
}
start1_pct = end1_pct;
end1_pct = start1_pct + ( 80.0 / length );
gen_number_block( rwy_info, material, runway_a, rwy_info.heading,
num, start1_pct, end1_pct, rwy_polys, texparams, accum );
num2, start1_pct, end1_pct, rwy_polys, texparams, accum );
//
// Touch down zone x3

View file

@ -1,4 +1,4 @@
// rwy_prec.hxx -- Build a precision runway
// rwy_gen.hxx -- Build a runway
//
// Written by Curtis Olson, started February 2002.
//
@ -33,12 +33,12 @@
#include "texparams.hxx"
// generate a precision approach runway. The routine modifies
// generate a runway. The routine modifies
// rwy_polys, texparams, and accum. For specific details and
// dimensions of precision runway markings, please refer to FAA
// document AC 150/5340-1H
void gen_precision_rwy( const TGRunway& rwy_info,
void gen_rwy( const TGRunway& rwy_info,
double alt_m,
const std::string& material,
superpoly_list *rwy_polys,

View file

@ -1,417 +0,0 @@
// rwy_nonprec.cxx -- Build a non-precision runway
//
// Written by Curtis Olson, started February 2002.
//
// Copyright (C) 2002 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: rwy_nonprec.cxx,v 1.16 2004-11-19 22:25:49 curt Exp $
//
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include "rwy_common.hxx"
#include "rwy_nonprec.hxx"
#include <stdlib.h>
using std::string;
// generate a non-precision approach runway. The routine modifies
// rwy_polys, texparams, and accum. For specific details and
// dimensions of precision runway markings, please refer to FAA
// document AC 150/5340-1H
void gen_non_precision_rwy( const TGRunway& rwy_info,
double alt_m,
const string& material,
superpoly_list *rwy_polys,
texparams_list *texparams,
TGPolygon *accum )
{
int i, j;
//
// Generate the basic runway outlines
//
TGPolygon runway = gen_runway_w_mid( rwy_info, alt_m,
2 * SG_FEET_TO_METER,
2 * SG_FEET_TO_METER );
// runway half "a"
TGPolygon runway_a;
runway_a.erase();
runway_a.add_node( 0, runway.get_pt(0, 0) );
runway_a.add_node( 0, runway.get_pt(0, 1) );
runway_a.add_node( 0, runway.get_pt(0, 2) );
runway_a.add_node( 0, runway.get_pt(0, 5) );
// runway half "b"
TGPolygon runway_b;
runway_b.erase();
runway_b.add_node( 0, runway.get_pt(0, 3) );
runway_b.add_node( 0, runway.get_pt(0, 4) );
runway_b.add_node( 0, runway.get_pt(0, 5) );
runway_b.add_node( 0, runway.get_pt(0, 2) );
Point3D p;
SG_LOG(SG_GENERAL, SG_DEBUG, "raw runway pts (a half)");
for ( j = 0; j < runway_a.contour_size( 0 ); ++j ) {
p = runway_a.get_pt(0, j);
SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p);
}
SG_LOG(SG_GENERAL, SG_DEBUG, "raw runway pts (b half)");
for ( j = 0; j < runway_b.contour_size( 0 ); ++j ) {
p = runway_b.get_pt(0, j);
SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p);
}
//
// Setup some variables and values to help us chop up the runway
// into its various sections
//
TGSuperPoly sp;
TGTexParams tp;
// we add 2' to the length for texture overlap. This puts the
// lines on the texture back to the edge of the runway where they
// belong.
double length = rwy_info.length / 2.0 + 2.0;
if ( length < 1150 ) {
SG_LOG(SG_GENERAL, SG_ALERT,
"This runway is not long enough for non-precision markings!");
}
double start1_pct = 0.0;
double start2_pct = 0.0;
double end1_pct = 0.0;
double end2_pct = 0.0;
//
// Displaced threshold if it exists
//
if ( rwy_info.disp_thresh1 > 0.0 ) {
SG_LOG( SG_GENERAL, SG_INFO, "Forward displaced threshold = "
<< rwy_info.disp_thresh1 );
// reserve 90' for final arrows
double thresh = rwy_info.disp_thresh1 - 90.0;
// number of full center arrows
int count = (int)(thresh / 200.0);
// length of starting partial arrow
double part_len = thresh - ( count * 200.0 );
double tex_pct = (200.0 - part_len) / 200.0;
// starting (possibly partial chunk)
start2_pct = end2_pct;
end2_pct = start2_pct + ( part_len / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, tex_pct, 1.0,
rwy_info.heading + 180.0,
material, "dspl_thresh",
rwy_polys, texparams, accum );
// main chunks
for ( i = 0; i < count; ++i ) {
start2_pct = end2_pct;
end2_pct = start2_pct + ( 200.0 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "dspl_thresh",
rwy_polys, texparams, accum );
}
// final arrows
start2_pct = end2_pct;
end2_pct = start2_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "dspl_arrows",
rwy_polys, texparams, accum );
}
if ( rwy_info.disp_thresh2 > 0.0 ) {
SG_LOG( SG_GENERAL, SG_INFO, "Reverse displaced threshold = "
<< rwy_info.disp_thresh2 );
// reserve 90' for final arrows
double thresh = rwy_info.disp_thresh2 - 90.0;
// number of full center arrows
int count = (int)(thresh / 200.0);
// length of starting partial arrow
double part_len = thresh - ( count * 200.0 );
double tex_pct = (200.0 - part_len) / 200.0;
// starting (possibly partial chunk)
start1_pct = end1_pct;
end1_pct = start1_pct + ( part_len / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, tex_pct, 1.0,
rwy_info.heading,
material, "dspl_thresh",
rwy_polys, texparams, accum );
// main chunks
for ( i = 0; i < count; ++i ) {
start1_pct = end1_pct;
end1_pct = start1_pct + ( 200.0 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "dspl_thresh",
rwy_polys, texparams, accum );
}
// final arrows
start1_pct = end1_pct;
end1_pct = start1_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "dspl_arrows",
rwy_polys, texparams, accum );
}
//
// Threshold
//
start1_pct = end1_pct;
end1_pct = start1_pct + ( 202.0 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "threshold",
rwy_polys, texparams, accum );
start2_pct = end2_pct;
end2_pct = start2_pct + ( 202.0 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "threshold",
rwy_polys, texparams, accum );
//
// Runway designation letter
//
int len = rwy_info.rwy_no.length();
string letter = "";
string rev_letter = "";
for ( i = 0; i < len; ++i ) {
string tmp = rwy_info.rwy_no.substr(i, 1);
if ( tmp == "L" ) {
letter = "L";
rev_letter = "R";
} else if ( tmp == "R" ) {
letter = "R";
rev_letter = "L";
} else if ( tmp == "C" ) {
letter = "C";
rev_letter = "C";
}
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation = " << rwy_info.rwy_no);
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation letter = " << letter);
if ( !letter.empty() ) {
start1_pct = end1_pct;
end1_pct = start1_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, rev_letter,
rwy_polys, texparams, accum );
start2_pct = end2_pct;
end2_pct = start2_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, letter,
rwy_polys, texparams, accum );
}
//
// Runway designation number(s)
//
len = rwy_info.rwy_no.length();
string snum = rwy_info.rwy_no;
for ( i = 0; i < len; ++i ) {
string tmp = rwy_info.rwy_no.substr(i, 1);
if ( tmp == "L" || tmp == "R" || tmp == "C" || tmp == " " ) {
snum = rwy_info.rwy_no.substr(0, i);
}
}
SG_LOG(SG_GENERAL, SG_INFO, "Runway num = '" << snum << "'");
int num = atoi( snum.c_str() );
while ( num <= 0 ) {
num += 36;
}
start2_pct = end2_pct;
end2_pct = start2_pct + ( 80.0 / length );
gen_number_block( rwy_info, material, runway_b, rwy_info.heading + 180.0,
num, start2_pct, end2_pct, rwy_polys, texparams, accum );
num += 18;
while ( num > 36 ) {
num -= 36;
}
start1_pct = end1_pct;
end1_pct = start1_pct + ( 80.0 / length );
gen_number_block( rwy_info, material, runway_a, rwy_info.heading,
num, start1_pct, end1_pct, rwy_polys, texparams, accum );
if ( true ) {
//
// Intermediate area before aiming point ...
//
for ( i = 0; i < 3; ++i ) {
start1_pct = end1_pct;
end1_pct = start1_pct + ( 200 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "centerline",
rwy_polys, texparams, accum );
start2_pct = end2_pct;
end2_pct = start2_pct + ( 200 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "centerline",
rwy_polys, texparams, accum );
}
//
// Aiming point
//
if ( end1_pct >= 1.0 ) {
return;
}
start1_pct = end1_pct;
end1_pct = start1_pct + ( 400 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "aim",
rwy_polys, texparams, accum );
if ( end2_pct >= 1.0 ) {
return;
}
start2_pct = end2_pct;
end2_pct = start2_pct + ( 400 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "aim",
rwy_polys, texparams, accum );
}
//
// The rest ...
//
// fit the 'rest' texture in as many times as will go evenly into
// the remaining distance so we don't end up with a super short
// section at the end.
double ideal_rest_inc = ( 200.0 / length );
int divs = (int)((1.0 - end1_pct) / ideal_rest_inc) + 1;
double rest1_inc = (1.0 - end1_pct) / divs;
while ( end1_pct < 1.0 ) {
start1_pct = end1_pct;
end1_pct = start1_pct + rest1_inc;
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "rest",
rwy_polys, texparams, accum );
}
ideal_rest_inc = ( 200.0 / length );
divs = (int)((1.0 - end2_pct) / ideal_rest_inc) + 1;
double rest2_inc = (1.0 - end2_pct) / divs;
while ( end2_pct < 1.0 ) {
start2_pct = end2_pct;
end2_pct = start2_pct + rest2_inc;
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "rest",
rwy_polys, texparams, accum );
}
gen_runway_stopway( rwy_info, runway_a, runway_b,
material,
rwy_polys, texparams, accum );
}

View file

@ -1,49 +0,0 @@
// rwy_nonprec.hxx -- Build a non-precision runway
//
// Written by Curtis Olson, started February 2002.
//
// Copyright (C) 2002 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: rwy_nonprec.hxx,v 1.5 2004-11-19 22:25:49 curt Exp $
//
#ifndef _RWY_NONPREC_HXX
#define _RWY_NONPREC_HXX
#include <Polygon/polygon.hxx>
#include <Polygon/superpoly.hxx>
#include "runway.hxx"
#include "texparams.hxx"
// generate a non-precision approach runway. The routine modifies
// rwy_polys, texparams, and accum. For specific details and
// dimensions of precision runway markings, please refer to FAA
// document AC 150/5340-1H
void gen_non_precision_rwy( const TGRunway& rwy_info,
double alt_m,
const std::string& material,
superpoly_list *rwy_polys,
texparams_list *texparams,
TGPolygon *accum );
#endif // _RWY_NONPREC_HXX

View file

@ -29,7 +29,6 @@
#include "poly_extra.hxx"
#include "rwy_common.hxx"
#include "texparams.hxx"
#include "rwy_nonprec.hxx"
using std::string;

View file

@ -1,426 +0,0 @@
// rwy_visual.cxx -- Build a visual approach runway
//
// Written by Curtis Olson, started February 2002.
//
// Copyright (C) 2002 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: rwy_visual.cxx,v 1.18 2004-11-19 22:25:49 curt Exp $
//
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include "rwy_common.hxx"
#include "rwy_visual.hxx"
#include <stdlib.h>
using std::string;
// generate a visual approach runway. The routine modifies rwy_polys,
// texparams, and accum. For specific details and dimensions of
// precision runway markings, please refer to FAA document AC
// 150/5340-1H
void gen_visual_rwy( const TGRunway& rwy_info,
double alt_m,
const string& material,
superpoly_list *rwy_polys,
texparams_list *texparams,
TGPolygon *accum )
{
int i, j;
//
// Generate the basic runway outlines
//
TGPolygon runway = gen_runway_w_mid( rwy_info, alt_m,
2 * SG_FEET_TO_METER,
2 * SG_FEET_TO_METER );
// runway half "a"
TGPolygon runway_a;
runway_a.erase();
runway_a.add_node( 0, runway.get_pt(0, 0) );
runway_a.add_node( 0, runway.get_pt(0, 1) );
runway_a.add_node( 0, runway.get_pt(0, 2) );
runway_a.add_node( 0, runway.get_pt(0, 5) );
// runway half "b"
TGPolygon runway_b;
runway_b.erase();
runway_b.add_node( 0, runway.get_pt(0, 3) );
runway_b.add_node( 0, runway.get_pt(0, 4) );
runway_b.add_node( 0, runway.get_pt(0, 5) );
runway_b.add_node( 0, runway.get_pt(0, 2) );
Point3D p;
SG_LOG(SG_GENERAL, SG_DEBUG, "raw runway pts (a half)");
for ( j = 0; j < runway_a.contour_size( 0 ); ++j ) {
p = runway_a.get_pt(0, j);
SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p);
}
SG_LOG(SG_GENERAL, SG_DEBUG, "raw runway pts (b half)");
for ( j = 0; j < runway_b.contour_size( 0 ); ++j ) {
p = runway_b.get_pt(0, j);
SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p);
}
//
// Setup some variables and values to help us chop up the runway
// into its various sections
//
TGSuperPoly sp;
TGTexParams tp;
// we add 2' to the length for texture overlap. This puts the
// lines on the texture back to the edge of the runway where they
// belong.
double length = rwy_info.length / 2.0 + 2.0;
if ( length < 1150 ) {
SG_LOG(SG_GENERAL, SG_ALERT,
"This runway is not long enough for visual markings = "
<< rwy_info.length );
}
double start1_pct = 0.0;
double start2_pct = 0.0;
double end1_pct = 0.0;
double end2_pct = 0.0;
//
// Displaced threshold if it exists
//
if ( rwy_info.disp_thresh1 > 0.0 ) {
SG_LOG( SG_GENERAL, SG_INFO, "Forward displaced threshold = "
<< rwy_info.disp_thresh1 );
// reserve 90' for final arrows
double thresh = rwy_info.disp_thresh1 - 90.0;
// number of full center arrows
int count = (int)(thresh / 200.0);
// length of starting partial arrow
double part_len = thresh - ( count * 200.0 );
double tex_pct = (200.0 - part_len) / 200.0;
// starting (possibly partial chunk)
start2_pct = end2_pct;
end2_pct = start2_pct + ( part_len / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, tex_pct, 1.0,
rwy_info.heading + 180.0,
material, "dspl_thresh",
rwy_polys, texparams, accum );
// main chunks
for ( i = 0; i < count; ++i ) {
start2_pct = end2_pct;
end2_pct = start2_pct + ( 200.0 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "dspl_thresh",
rwy_polys, texparams, accum );
}
// final arrows
start2_pct = end2_pct;
end2_pct = start2_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "dspl_arrows",
rwy_polys, texparams, accum );
}
if ( rwy_info.disp_thresh2 > 0.0 ) {
SG_LOG( SG_GENERAL, SG_INFO, "Reverse displaced threshold = "
<< rwy_info.disp_thresh2 );
// reserve 90' for final arrows
double thresh = rwy_info.disp_thresh2 - 90.0;
// number of full center arrows
int count = (int)(thresh / 200.0);
// length of starting partial arrow
double part_len = thresh - ( count * 200.0 );
double tex_pct = (200.0 - part_len) / 200.0;
// starting (possibly partial chunk)
start1_pct = end1_pct;
end1_pct = start1_pct + ( part_len / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, tex_pct, 1.0,
rwy_info.heading,
material, "dspl_thresh",
rwy_polys, texparams, accum );
// main chunks
for ( i = 0; i < count; ++i ) {
start1_pct = end1_pct;
end1_pct = start1_pct + ( 200.0 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "dspl_thresh",
rwy_polys, texparams, accum );
}
// final arrows
start1_pct = end1_pct;
end1_pct = start1_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "dspl_arrows",
rwy_polys, texparams, accum );
}
//
// Threshold
//
// mini threshold
// starting (possibly partial chunk)
start1_pct = end1_pct;
end1_pct = start1_pct + ( 14 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 0.07,
rwy_info.heading,
material, "threshold",
rwy_polys, texparams, accum );
// starting (possibly partial chunk)
start2_pct = end2_pct;
end2_pct = start2_pct + ( 14 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 0.07,
rwy_info.heading + 180.0,
material, "threshold",
rwy_polys, texparams, accum );
//
// Runway designation letter
//
int len = rwy_info.rwy_no.length();
string letter = "";
string rev_letter = "";
for ( i = 0; i < len; ++i ) {
string tmp = rwy_info.rwy_no.substr(i, 1);
if ( tmp == "L" ) {
letter = "L";
rev_letter = "R";
} else if ( tmp == "R" ) {
letter = "R";
rev_letter = "L";
} else if ( tmp == "C" ) {
letter = "C";
rev_letter = "C";
}
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation = " << rwy_info.rwy_no);
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation letter = " << letter);
if ( !letter.empty() ) {
start1_pct = end1_pct;
end1_pct = start1_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, rev_letter,
rwy_polys, texparams, accum );
start2_pct = end2_pct;
end2_pct = start2_pct + ( 90.0 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, letter,
rwy_polys, texparams, accum );
}
//
// Runway designation number(s)
//
len = rwy_info.rwy_no.length();
string snum = rwy_info.rwy_no;
for ( i = 0; i < len; ++i ) {
string tmp = rwy_info.rwy_no.substr(i, 1);
if ( tmp == "L" || tmp == "R" || tmp == "C" || tmp == " " ) {
snum = rwy_info.rwy_no.substr(0, i);
}
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway num = '" << snum << "'");
int num = atoi( snum.c_str() );
while ( num <= 0 ) {
num += 36;
}
start2_pct = end2_pct;
end2_pct = start2_pct + ( 80.0 / length );
gen_number_block( rwy_info, material, runway_b, rwy_info.heading + 180.0,
num, start2_pct, end2_pct, rwy_polys, texparams, accum );
num += 18;
while ( num > 36 ) {
num -= 36;
}
start1_pct = end1_pct;
end1_pct = start1_pct + ( 80.0 / length );
gen_number_block( rwy_info, material, runway_a, rwy_info.heading,
num, start1_pct, end1_pct, rwy_polys, texparams, accum );
if ( false ) {
//
// Intermediate area before aiming point ...
//
for ( i = 0; i < 3; ++i ) {
start1_pct = end1_pct;
end1_pct = start1_pct + ( 200 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "centerline",
rwy_polys, texparams, accum );
start2_pct = end2_pct;
end2_pct = start2_pct + ( 200 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "centerline",
rwy_polys, texparams, accum );
}
//
// Aiming point
//
if ( end1_pct >= 1.0 ) {
return;
}
start1_pct = end1_pct;
end1_pct = start1_pct + ( 400 / length );
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "aim",
rwy_polys, texparams, accum );
if ( end2_pct >= 1.0 ) {
return;
}
start2_pct = end2_pct;
end2_pct = start2_pct + ( 400 / length );
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "aim",
rwy_polys, texparams, accum );
}
//
// The rest ...
//
// fit the 'rest' texture in as many times as will go evenly into
// the remaining distance so we don't end up with a super short
// section at the end.
double ideal_rest_inc = ( 200.0 / length );
int divs = (int)((1.0 - end1_pct) / ideal_rest_inc) + 1;
double rest1_inc = (1.0 - end1_pct) / divs;
while ( end1_pct < 1.0 ) {
start1_pct = end1_pct;
end1_pct = start1_pct + rest1_inc;
SG_LOG(SG_GENERAL, SG_DEBUG, "start1 = " << start1_pct << " end1 = " << end1_pct);
gen_runway_section( rwy_info, runway_a,
start1_pct, end1_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading,
material, "rest",
rwy_polys, texparams, accum );
}
ideal_rest_inc = ( 200.0 / length );
divs = (int)((1.0 - end2_pct) / ideal_rest_inc) + 1;
double rest2_inc = (1.0 - end2_pct) / divs;
while ( end2_pct < 1.0 ) {
start2_pct = end2_pct;
end2_pct = start2_pct + rest2_inc;
gen_runway_section( rwy_info, runway_b,
start2_pct, end2_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
rwy_info.heading + 180.0,
material, "rest",
rwy_polys, texparams, accum );
}
gen_runway_stopway( rwy_info, runway_a, runway_b,
material,
rwy_polys, texparams, accum );
}

View file

@ -1,49 +0,0 @@
// rwy_visual.hxx -- Build a visual approach runway
//
// Written by Curtis Olson, started February 2002.
//
// Copyright (C) 2002 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: rwy_visual.hxx,v 1.5 2004-11-19 22:25:49 curt Exp $
//
#ifndef _RWY_VISUAL_HXX
#define _RWY_VISUAL_HXX
#include <Polygon/polygon.hxx>
#include <Polygon/superpoly.hxx>
#include "runway.hxx"
#include "texparams.hxx"
// generate a visual approach runway. The routine modifies rwy_polys,
// texparams, and accum. For specific details and dimensions of
// precision runway markings, please refer to FAA document AC
// 150/5340-1H
void gen_visual_rwy( const TGRunway& rwy_info,
double alt_m,
const std::string& material,
superpoly_list *rwy_polys,
texparams_list *texparams,
TGPolygon *accum );
#endif // _RWY_VISUAL_HXX