More accurate, more symmetrical computation of tangent vector.
This commit is contained in:
parent
02f42b8816
commit
214919da20
1 changed files with 27 additions and 18 deletions
|
@ -61,28 +61,37 @@ static double sawtooth(double xx)
|
|||
return 4.0 * fabs(xx/4.0 + 0.25 - floor(xx/4.0 + 0.75)) - 1.0;
|
||||
}
|
||||
|
||||
// Calculate a unit vector in the horizontal tangent plane
|
||||
// starting at the given "tail" of the vector and going off
|
||||
// with the given heading.
|
||||
static SGVec3d tangentVector(const SGGeod& tail, const SGVec3d& tail_xyz,
|
||||
const double heading)
|
||||
// Calculate a Cartesian unit vector in the
|
||||
// local horizontal plane, i.e. tangent to the
|
||||
// surface of the earth at the local ground zero.
|
||||
// The tangent vector passes through the given <midpoint>
|
||||
// and points forward along the given <heading>.
|
||||
// The <heading> is given in degrees.
|
||||
static SGVec3d tangentVector(const SGGeod& midpoint, const double heading)
|
||||
{
|
||||
// The fudge factor here is presumably intended to improve
|
||||
// numerical stability. I don't know if it is necessary.
|
||||
// It gets divided out later.
|
||||
double fudge(100.0);
|
||||
SGGeod head;
|
||||
double az2; // ignored
|
||||
SGGeodesy::direct(tail, heading, fudge, head, az2);
|
||||
head.setElevationM(tail.getElevationM());
|
||||
// The size of the delta is presumably chosen to give
|
||||
// numerical stability. I don't know how the value was chosen.
|
||||
// It probably doesn't matter much. It gets divided out.
|
||||
double delta(100.0); // in meters
|
||||
SGGeod head, tail;
|
||||
double az2; // ignored
|
||||
SGGeodesy::direct(midpoint, heading, delta, head, az2);
|
||||
SGGeodesy::direct(midpoint, 180+heading, delta, tail, az2);
|
||||
head.setElevationM(midpoint.getElevationM());
|
||||
tail.setElevationM(midpoint.getElevationM());
|
||||
SGVec3d head_xyz = SGVec3d::fromGeod(head);
|
||||
return (head_xyz - tail_xyz) * (1.0/fudge);
|
||||
SGVec3d tail_xyz = SGVec3d::fromGeod(tail);
|
||||
// Awkward formula here, needed because vector-by-scalar
|
||||
// multiplication is defined, but not vector-by-scalar division.
|
||||
return (head_xyz - tail_xyz) * (0.5/delta);
|
||||
}
|
||||
|
||||
// Create a "serviceable" node with a default value of "true"
|
||||
SGPropertyNode_ptr createServiceableProp(SGPropertyNode* aParent, const char* aName)
|
||||
SGPropertyNode_ptr createServiceableProp(SGPropertyNode* aParent,
|
||||
const char* aName)
|
||||
{
|
||||
SGPropertyNode_ptr n = (aParent->getChild(aName, 0, true)->getChild("serviceable", 0, true));
|
||||
SGPropertyNode_ptr n =
|
||||
aParent->getChild(aName, 0, true)->getChild("serviceable", 0, true);
|
||||
simgear::props::Type typ = n->getType();
|
||||
if ((typ == simgear::props::NONE) || (typ == simgear::props::UNSPECIFIED)) {
|
||||
n->setBoolValue(true);
|
||||
|
@ -945,11 +954,11 @@ void FGNavRadio::search()
|
|||
|
||||
// GS axis unit tangent vector
|
||||
// (along the runway):
|
||||
_gsAxis = tangentVector(_gs->geod(), _gsCart, gs_radial);
|
||||
_gsAxis = tangentVector(_gs->geod(), gs_radial);
|
||||
|
||||
// GS baseline unit tangent vector
|
||||
// (perpendicular to the runay along the ground)
|
||||
SGVec3d baseline = tangentVector(_gs->geod(), _gsCart, gs_radial + 90.0);
|
||||
SGVec3d baseline = tangentVector(_gs->geod(), gs_radial + 90.0);
|
||||
_gsVertical = cross(baseline, _gsAxis);
|
||||
} // of have glideslope
|
||||
} // of found LOC or ILS
|
||||
|
|
Loading…
Add table
Reference in a new issue