#include "vector.hxx"
+// Given a point p, and a line through p0 with direction vector d,
+// find the closest point (p1) on the line
+void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0,
+ const sgVec3 d ) {
+
+ sgVec3 u, u1;
+
+ // u = p - p0
+ sgSubVec3(u, p, p0);
+
+ // calculate the projection, u1, of u along d.
+ // u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
+ sgScaleVec3( u1, d, sgScalarProductVec3(u,d) / sgScalarProductVec3(d,d) );
+
+ // calculate the point p1 along the line that is closest to p
+ // p0 = p1 + u1
+ sgAddVec3(p1, p0, u1);
+}
+
+
+// Given a point p, and a line through p0 with direction vector d,
+// find the closest point (p1) on the line
+void sgdClosestPointToLine( sgdVec3 p1, const sgdVec3 p, const sgdVec3 p0,
+ const sgdVec3 d ) {
+
+ sgdVec3 u, u1;
+
+ // u = p - p0
+ sgdSubVec3(u, p, p0);
+
+ // calculate the projection, u1, of u along d.
+ // u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
+ double ud = sgdScalarProductVec3(u, d);
+ double dd = sgdScalarProductVec3(d, d);
+ double tmp = ud / dd;
+
+ sgdScaleVec3(u1, d, tmp);;
+
+ // calculate the point p1 along the line that is closest to p
+ // p0 = p1 + u1
+ sgdAddVec3(p1, p0, u1);
+}
+
+
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance (squared) from the point to the line
-double sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
- const sgVec3 d ) {
+double sgClosestPointToLineDistSquared( const sgVec3 p, const sgVec3 p0,
+ const sgVec3 d ) {
sgVec3 u, u1, v;
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance (squared) from the point to the line
-double sgdPointLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
- const sgdVec3 d ) {
+double sgdClosestPointToLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
+ const sgdVec3 d ) {
sgdVec3 u, u1, v;
- double ud, dd, tmp;
// u = p - p0
sgdSubVec3(u, p, p0);
// calculate the projection, u1, of u along d.
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
- ud = sgdScalarProductVec3(u, d);
- dd = sgdScalarProductVec3(d, d);
- tmp = ud / dd;
+ double ud = sgdScalarProductVec3(u, d);
+ double dd = sgdScalarProductVec3(d, d);
+ double tmp = ud / dd;
sgdScaleVec3(u1, d, tmp);;
dst [ 3 ] = -src [ 3 ] ;
}
+// Given a point p, and a line through p0 with direction vector d,
+// find the closest point (p1) on the line
+void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0,
+ const sgVec3 d );
+
+// Given a point p, and a line through p0 with direction vector d,
+// find the closest point (p1) on the line
+void sgdClosestPointToLine( sgdVec3 p1, const sgdVec3 p, const sgdVec3 p0,
+ const sgdVec3 d );
+
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance (squared) from the point to the line
-double sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
- const sgVec3 d );
+double sgClosestPointToLineDistSquared( const sgVec3 p, const sgVec3 p0,
+ const sgVec3 d );
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance (squared) from the point to the line
-double sgdPointLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
- const sgdVec3 d );
+double sgdClosestPointToLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
+ const sgdVec3 d );
// This is same as
// sgMakeMatTrans4( sgMat4 sgTrans, sgVec3 trans )
INCLUDES += -I$(top_srcdir)
-noinst_PROGRAMS = waytest
+noinst_PROGRAMS = waytest routetest
waytest_SOURCES = waytest.cxx
waytest_LDADD = \
+ $(top_builddir)/simgear/route/libsgroute.a \
+ $(top_builddir)/simgear/math/libsgmath.a \
+ $(top_builddir)/simgear/debug/libsgdebug.a
+
+routetest_SOURCES = routetest.cxx
+
+routetest_LDADD = \
$(top_builddir)/simgear/route/libsgroute.a \
$(top_builddir)/simgear/math/libsgmath.a \
$(top_builddir)/simgear/debug/libsgdebug.a
\ No newline at end of file
// $Id$
+#include <plib/sg.h>
+
+#include <simgear/math/vector.hxx>
+
#include "route.hxx"
// destructor
SGRoute::~SGRoute() {
}
+
+
+// Calculate perpendicular distance from the current route segment
+// This routine assumes all points are laying on a flat plane and
+// ignores the altitude (or Z) dimension. For best results, use with
+// CARTESIAN way points.
+double SGRoute::distance_off_route( double x, double y ) const {
+ if ( current_wp > 0 ) {
+ int n0 = current_wp - 1;
+ int n1 = current_wp;
+ sgdVec3 p, p0, p1, d;
+ sgdSetVec3( p, x, y, 0.0 );
+ sgdSetVec3( p0,
+ route[n0].get_target_lon(), route[n0].get_target_lat(),
+ 0.0 );
+ sgdSetVec3( p1,
+ route[n1].get_target_lon(), route[n1].get_target_lat(),
+ 0.0 );
+ sgdSubVec3( d, p0, p1 );
+
+ return sqrt( sgdClosestPointToLineDistSquared( p, p0, d ) );
+
+ } else {
+ // We are tracking the first waypoint so there is no route
+ // segment. If you add the current location as the first
+ // waypoint and the actual waypoint as the second, then we
+ // will have a route segment and calculate distance from it.
+
+ return 0;
+ }
+}
route.erase( route.begin() );
}
}
+
+ // Calculate perpendicular distance from the current route segment
+ // This routine assumes all points are laying on a flat plane and
+ // ignores the altitude (or Z) dimension. For best results, use
+ // with CARTESIAN way points.
+ double distance_off_route( double x, double y ) const;
};
--- /dev/null
+#include <simgear/constants.h>
+
+#include "route.hxx"
+#include "waypoint.hxx"
+
+int main() {
+ SGRoute route;
+
+ route.add_waypoint( SGWayPoint(0, 0, 0, SGWayPoint::CARTESIAN, "Start") );
+ route.add_waypoint( SGWayPoint(1, 0, 0, SGWayPoint::CARTESIAN, "1") );
+ route.add_waypoint( SGWayPoint(2, 0, 0, SGWayPoint::CARTESIAN, "2") );
+ route.add_waypoint( SGWayPoint(2, 2, 0, SGWayPoint::CARTESIAN, "3") );
+ route.add_waypoint( SGWayPoint(4, 2, 0, SGWayPoint::CARTESIAN, "4") );
+
+ route.set_current( 1 );
+
+ cout << "( 0.5, 0 ) = " << route.distance_off_route( 0.5, 0 ) << endl;
+ cout << "( 0.5, 1 ) = " << route.distance_off_route( 0.5, 1 ) << endl;
+ cout << "( 0.5, -1 ) = " << route.distance_off_route( 0.5, 1 ) << endl;
+
+ route.set_current( 3 );
+
+ cout << "( 2, 4 ) = " << route.distance_off_route( 2, 4 ) << endl;
+ cout << "( 2.5, 4 ) = " << route.distance_off_route( 2.5, 4 ) << endl;
+
+ return 0;
+}