(C++) GetDistance
February 24, 2017 · View on GitHub
(C++) GetDistance
GetDistance is a geometry code snippet to calculate the distance between two coordinats from their horizontal and vertical distances, using Pythagoras.
GetDistance is maintained in the CppGeometry class, see CppGeometry for the heavily tested, debugged and used version.
#include <cmath> ///Obtain the Pythagorian distance from two delta's //From www.richelbilderbeek.nl/CppGetDistance.htm double GetDistance(const double delta_x, const double delta_y) { return std::sqrt( (delta_x * delta_x) + (delta_y * delta_y) ); } ///Obtain the Pythagorian distance from two coordinats //From www.richelbilderbeek.nl/CppGetDistance.htm double GetDistance(const double x1, const double y1, const double x2, const double y2) { return GetDistance(x1-x2,y1-y2); }
Below is a complete project for testing GetDistance, additionally using the Boost.Geometry library.
Testing code
Technical facts
Operating system(s) or programming environment(s)
Lubuntu 12.10 (quantal)
Qt Creator 2.5.2
- G++ 4.7.2
Libraries used:
STL: GNU ISO C++ Library, version
4.7.2
Qt project file: CppGetDistance.pro
TEMPLATE = app CONFIG += console CONFIG -= qt QMAKE_CXXFLAGS += -std=c++11 -Wextra -Werror SOURCES += main.cpp
main.cpp
#include <cmath> ///Obtain the Pythagorian distance from two delta's //From www.richelbilderbeek.nl/CppGetDistance.htm double GetDistance(const double delta_x, const double delta_y) { return std::sqrt( (delta_x * delta_x) + (delta_y * delta_y) ); } ///Obtain the Pythagorian distance from two coordinats //From www.richelbilderbeek.nl/CppGetDistance.htm double GetDistance(const double x1, const double y1, const double x2, const double y2) { return GetDistance(x1-x2,y1-y2); } #include <boost/geometry.hpp> ///Obtain the Pythagorian distance from two delta's //From www.richelbilderbeek.nl/CppGetDistance.htm double GetDistanceBoost(const double delta_x, const double delta_y) { const boost::geometry::model::d2::point_xy<double> p1(0.0,0.0); const boost::geometry::model::d2::point_xy<double> p2(delta_x,delta_y); return boost::geometry::distance(p1,p2); } ///Obtain the Pythagorian distance from two coordinats //From www.richelbilderbeek.nl/CppGetDistance.htm double GetDistanceBoost(const double x1, const double y1, const double x2, const double y2) { const boost::geometry::model::d2::point_xy<double> p1(x1,y1); const boost::geometry::model::d2::point_xy<double> p2(x2,y2); return boost::geometry::distance(p1,p2); } ///fuzzy_equal_to is a predicate to test two doubles for equality ///with a certain tolerance. A tolerance of 0.0 denotes that ///an exact match is requested. Note that the value of 0.0 cannot ///be compared fuzzily. struct fuzzy_equal_to : public std::binary_function<double,double,bool> { fuzzy_equal_to(const double tolerance = std::numeric_limits<double>::epsilon()) : m_tolerance(tolerance) { assert(tolerance >= 0.0); } bool operator()(const double lhs, const double rhs) const { const double d = std::abs(m_tolerance * lhs); return rhs > lhs - d && rhs < lhs + d; } const double m_tolerance; }; #include <algorithm> #include <cassert> #include <tuple> #include <vector> int main() { //Delta's assert(fuzzy_equal_to()(GetDistance(3.0, 4.0),5.0)); assert(fuzzy_equal_to()(GetDistance(5.0,12.0),13.0)); assert(fuzzy_equal_to()(GetDistance(8.0,15.0),17.0)); assert(fuzzy_equal_to()(GetDistance(7.0,24.0),25.0)); assert(fuzzy_equal_to()(GetDistance(9.0,40.0),41.0)); assert(fuzzy_equal_to()(GetDistanceBoost(3.0, 4.0),5.0)); assert(fuzzy_equal_to()(GetDistanceBoost(5.0,12.0),13.0)); assert(fuzzy_equal_to()(GetDistanceBoost(8.0,15.0),17.0)); assert(fuzzy_equal_to()(GetDistanceBoost(7.0,24.0),25.0)); assert(fuzzy_equal_to()(GetDistanceBoost(9.0,40.0),41.0)); //Compared to origin assert(fuzzy_equal_to()(GetDistance(3.0, 4.0,0.0,0.0), 5.0)); assert(fuzzy_equal_to()(GetDistance(5.0,12.0,0.0,0.0),13.0)); assert(fuzzy_equal_to()(GetDistance(8.0,15.0,0.0,0.0),17.0)); assert(fuzzy_equal_to()(GetDistance(7.0,24.0,0.0,0.0),25.0)); assert(fuzzy_equal_to()(GetDistance(9.0,40.0,0.0,0.0),41.0)); assert(fuzzy_equal_to()(GetDistance(0.0,0.0,3.0, 4.0), 5.0)); assert(fuzzy_equal_to()(GetDistance(0.0,0.0,5.0,12.0),13.0)); assert(fuzzy_equal_to()(GetDistance(0.0,0.0,8.0,15.0),17.0)); assert(fuzzy_equal_to()(GetDistance(0.0,0.0,7.0,24.0),25.0)); assert(fuzzy_equal_to()(GetDistance(0.0,0.0,9.0,40.0),41.0)); assert(fuzzy_equal_to()(GetDistanceBoost(3.0, 4.0,0.0,0.0), 5.0)); assert(fuzzy_equal_to()(GetDistanceBoost(5.0,12.0,0.0,0.0),13.0)); assert(fuzzy_equal_to()(GetDistanceBoost(8.0,15.0,0.0,0.0),17.0)); assert(fuzzy_equal_to()(GetDistanceBoost(7.0,24.0,0.0,0.0),25.0)); assert(fuzzy_equal_to()(GetDistanceBoost(9.0,40.0,0.0,0.0),41.0)); assert(fuzzy_equal_to()(GetDistanceBoost(0.0,0.0,3.0, 4.0), 5.0)); assert(fuzzy_equal_to()(GetDistanceBoost(0.0,0.0,5.0,12.0),13.0)); assert(fuzzy_equal_to()(GetDistanceBoost(0.0,0.0,8.0,15.0),17.0)); assert(fuzzy_equal_to()(GetDistanceBoost(0.0,0.0,7.0,24.0),25.0)); assert(fuzzy_equal_to()(GetDistanceBoost(0.0,0.0,9.0,40.0),41.0)); //Translated by (+1.0,+1.0) assert(fuzzy_equal_to()(GetDistance( 4.0, 5.0, 1.0, 1.0), 5.0)); assert(fuzzy_equal_to()(GetDistance( 6.0,13.0, 1.0, 1.0),13.0)); assert(fuzzy_equal_to()(GetDistance( 9.0,16.0, 1.0, 1.0),17.0)); assert(fuzzy_equal_to()(GetDistance( 8.0,25.0, 1.0, 1.0),25.0)); assert(fuzzy_equal_to()(GetDistance(10.0,41.0, 1.0, 1.0),41.0)); assert(fuzzy_equal_to()(GetDistance( 1.0, 1.0, 4.0, 5.0), 5.0)); assert(fuzzy_equal_to()(GetDistance( 1.0, 1.0, 6.0,13.0),13.0)); assert(fuzzy_equal_to()(GetDistance( 1.0, 1.0, 9.0,16.0),17.0)); assert(fuzzy_equal_to()(GetDistance( 1.0, 1.0, 8.0,25.0),25.0)); assert(fuzzy_equal_to()(GetDistance( 1.0, 1.0,10.0,41.0),41.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 4.0, 5.0, 1.0, 1.0), 5.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 6.0,13.0, 1.0, 1.0),13.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 9.0,16.0, 1.0, 1.0),17.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 8.0,25.0, 1.0, 1.0),25.0)); assert(fuzzy_equal_to()(GetDistanceBoost(10.0,41.0, 1.0, 1.0),41.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 1.0, 1.0, 4.0, 5.0), 5.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 1.0, 1.0, 6.0,13.0),13.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 1.0, 1.0, 9.0,16.0),17.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 1.0, 1.0, 8.0,25.0),25.0)); assert(fuzzy_equal_to()(GetDistanceBoost( 1.0, 1.0,10.0,41.0),41.0)); const std::vector<std::tuple<double,double,double> > v = { std::make_tuple(3.0, 4.0, 5.0), std::make_tuple(5.0,12.0,13.0), std::make_tuple(8.0,15.0,17.0), std::make_tuple(7.0,24.0,25.0), std::make_tuple(9.0,40.0,41.0) }; std::for_each(v.begin(),v.end(), [](const std::tuple<double,double,double>& t) { assert(fuzzy_equal_to()( GetDistance(std::get<0>(t),std::get<1>(t)), std::get<2>(t) ) ); assert(fuzzy_equal_to()( GetDistanceBoost(std::get<0>(t),std::get<1>(t)), std::get<2>(t) ) ); } ); std::vector<std::tuple<double,double,double,double,double> > w; std::transform(v.begin(),v.end(), std::back_inserter(w), [](const std::tuple<double,double,double>& t) { //Add a random translation const double t_x = static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX); const double t_y = static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX); return std::make_tuple( t_x, t_y, std::get<0>(t) + t_x, std::get<1>(t) + t_y, std::get<2>(t)); } ); std::for_each(w.begin(),w.end(), [](const std::tuple<double,double,double,double,double>& t) { assert(fuzzy_equal_to()( GetDistance(std::get<0>(t),std::get<1>(t),std::get<2>(t),std::get<3>(t)), std::get<4>(t) ) ); assert(fuzzy_equal_to()( GetDistanceBoost(std::get<0>(t),std::get<1>(t),std::get<2>(t),std::get<3>(t)), std::get<4>(t) ) ); } ); }